Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Growing Object-Oriented System
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Kent Wang
December 10, 2012
Programming
400
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Growing Object-Oriented System
Kent Wang
December 10, 2012
Other Decks in Programming
See All in Programming
FactoryBotをやめればRSpecは速くなるのか?
yuta_onishi_97
0
330
機械に任せるテスト、人が見るテスト ⽣成AIで引き直した、運⽤保守フェーズの線引き
dske104
0
190
パズルゲームの作り方 / how to make puzzle games
kaityo256
PRO
2
290
TechTown - Creating Composable Callables in Contemporary C++
rollbear
0
130
設計次第でAIコードの読む量は減らせる / designing-for-code-reading
minodriven
35
17k
GemmaをJevのように使ってみる / Use Gemma like Jev
kishida
5
790
作って学ぶSpring BootのAuto Configuration / JJUG Night Seminar 2026-10-19
rshindo
0
150
複雑なUIコンポーネントとの ⻑い付き合い⽅:波及するバグからテスト戦略を経て、安全な再設計へ
mixplace
0
410
[Dev Group Paris Octobre 26] Agentforce, SIforce, Claudeforce, Slackbot… on s'y retrouve ?
nabondance
0
110
【加筆修正版】Laravel のアプリケーションをどこにデプロイするか #phpcon_ehime
akase244
0
150
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Kaigi on Rails 2026, Tokyo, Japan
marcoroth
2
220
Unity6 URPによる海底をテーマにしたVJシステムの解説 | Unity Shader 完全に理解した 勉強会
gam0022
0
370
Featured
See All Featured
Designing for humans not robots
tammielis
254
26k
Bootstrapping a Software Product
garrettdimon
PRO
306
120k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
2
410
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
570
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
780
Being A Developer After 40
akosma
92
590k
We Have a Design System, Now What?
morganepeng
55
8.4k
Fireside Chat
paigeccino
43
4.1k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
730
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
330
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
31k
Google's AI Overviews - The New Search
badams
0
1.6k
Transcript
Growing Object-Oriented System Principles, Guidelines, and Methods Kent Wang Dec
6, 2012
Agenda • Introduction • Understand The Problem • Broad-Brush Design
• Implementation • Recommended Readings
Introduction
Why This Talk
None
Software Developing Is a Learning Process
Feedback is Critical Understand the Problem (Analysis) Broad-Brush Design (Architecture)
Test Driven Development (Implementation) Deployable System
Understand the Problem
Understand The Problem • User Story • Use Case •
Conceptual Model • Color Modeling
User Story Users could pay for their orders from various
platform via tenpay
Use Case User Pay
Use Case Is Valuable But Not The End
Digging A Conceptual Model
Dig Conceptual Model
Dig Conceptual Model Payment
Dig Conceptual Model Payment Partner Trade
Dig Conceptual Model Payment Partner Partner Trade
Dig Conceptual Model Payment Partner User Partner Trade
Dig Conceptual Model Payment Partner User Buyer Seller Partner Trade
Dig Conceptual Model Payment Partner User Payment Type Buyer Seller
Partner Trade
Color Modeling
Color Modeling Moment- Interval
Color Modeling Moment- Interval Party / Place /Thing
Color Modeling Moment- Interval Role Party / Place /Thing
Color Modeling Moment- Interval Role Description Party / Place /Thing
User Story Changed Users could pay for their orders from
various platform via tenpay or alipay
Simple Solution Payment Partner User Payment Type Buyer Seller Partner
Trade
Simple Solution Payment Partner User Payment Type Buyer Seller Partner
Trade
The Missing Concept Payment Partner User Payment Type Buyer Seller
Partner Trade
The Missing Concept Payment Partner User Payment Type Buyer Seller
Partner Trade Provider Payment
The Missing Concept Payment Partner User Payment Type Buyer Seller
Partner Trade Provider Payment Payment Provider
Models Are Not Right Or Wrong They Are More Or
Less Useful
One Team, One Language
Bounded Context Payment Partner Payment Type Provider Payment Payment Provider
Context Map Provider Payment Transaction unipay tenpay
Context Map Provider Payment Transaction unipay tenpay Transaction Map
Get Help If Required
Broad-Brush Design
Broad-Brush Design • Tackling Complexity • Architectural Level • Application
Level • Domain Model Level
Tackling Complexity
Separation of Concerns
Layered Architecture Application Presentation Data Source
Layered Architecture Application Presentation Data Source Domain
High Level of Abstraction
High Level of Abstraction
Architectural Level
Infrastructure • Distributed or Not • Synchronous or Asynchronous •
Data Source
Architectural Style Transaction Script Table Module Domain Model Complexity Tool-Chain
Location of Domain Logic DAO AO vs.
Location of Domain Logic DAO AO Domain vs.
Location of Domain Logic DAO AO Domain vs.
Location of Domain Logic DAO AO Domain vs.
Concurrent Control • Transaction is not Silver Bullet • Optimistic
or Pessimistic • Offline or Not
Application Level
Walking Through Scenarios
Walking Through Scenarios User Submit Payment Save Payment Get Payment
Parameter Submit To Provider
Walking Through Scenarios User Submit Payment Save Payment Get Payment
Parameter Submit To Provider Presentation Layer Application Layer
Intension-Revealing Interface CUnipayAO GetPaymentParameter CUnipayAO ProcessTrade vs.
Do One Thing CUnipayAO GetPaymentParameter
Do One Thing CUnipayAO GetPaymentParameter Save or update Payments Assemble
Payment Parameters
Command Query Separation System Command Query State A
Command Query Separation System Command Query State B
Command Query Separation System Command Query State B
Command Query Separation CUnipayAO GetPaymentParameter SetupPayment Save or update Payments
Assemble Payment Parameters
Module Payment Payment Provider Partner Notification History Security Settlement
Domain Model Level
Simplify Associations Payment Partner User Payment Type Buyer Seller Partner
Trade Provider Payment Payment Provider
Simplify Associations Payment Partner Payment Type Partner Trade Provider Payment
Payment Provider
Simplify Associations Payment Partner Payment Type Provider Payment Payment Provider
1..*
Simplify Associations Payment Partner Payment Type Provider Payment Payment Provider
1 current
Design Is Not Just A Technical Issue
Integrity Problem ChargePlan ChargePlan LineItem ChargePlan LineItem amount = 50
amount = 50 amount = 100
Integrity Problem ChargePlan ChargePlan LineItem ChargePlan LineItem amount = 50
amount = 50 amount = 100 ChargePlan LineItem amount = 50
Aggregate ChargePlan ChargePlan LineItem ChargePlan LineItem amount = 50 amount
= 50 amount = 100
Aggregate ChargePlan ChargePlan LineItem ChargePlan LineItem amount = 50 amount
= 50 amount = 100 ChargePlan LineItem amount = 50
Domain Model Pollution ao_unipay_settle Payment Relay Service ao_unipay Transaction
Anti-Corruption Layer ao_unipay_settle nao_unipay_tenpay Tenpay Service Payment Relay Service ao_unipay
Transaction
Design To Test Tenpay Service Facade
Design To Test Tenpay Service Facade Mock Tenpay Relay Client
Tenpay Service Facade Test
Design To Test Tenpay Service Facade Mock Tenpay Relay Client
Tenpay Service Facade Test 1. RegisterChargePlan(plan) 3. Execute(request, response) 4. Checking Request 5. Return Response 6. Return Response 7. Parse Response 2. Assemble Request 8. Return Result 9. Checking Result
Implementation
Implementation • Design Tools • Make A New Type •
Consistent Abstraction Level • Open Close Principle • Extract Hidden Concept
Costly Tools Don’t Produce Better Designs
UML Without CASE
CRC Card CTenpayProviderType Make Tenpay Trade No Make Tenpay Settle
No Get Request Builder CTenpayTradeNo CTenpayProvider CTenpayRequest Builder
CRC Card CTenpayProviderType Make Tenpay Trade No Make Tenpay Settle
No Get Request Builder CTenpayTradeNo CTenpayProvider CTenpayRequest Builder Class Responsibility Collaborator
Duplicated Code // inside NotifyPayment function // inside GetPayment fuction
if (sProviderTradeNo.length() != 28) { return ERR_APP_PARAM_INVALID; } uint64_t ddwProviderPartnerNo = lexical_cast<uint64_t>(sProviderTradeNo.substr(0, 10)) uint64_t ddwSerialNo = lexical_cast<uint64_t>(sProviderTradeNo.substr(18)); dwRet = GetPaymentByProviderTradeNo( ddwProviderPartnerNo, ddwSerialNo);
Make A New Type CTenpayTradeNo Make Tenpay Trade No Parse
Tenpay Trade No Verify Tenpay Trade No CTenpayProvider Get Date From Trade No Get Serial No From Trade No
Use The New Type // inside NotifyPayment function // inside
GetPayment fuction CTenpayTradeNo oTradeNo; if (!CProviderTradeNo::TryParse(sProviderTradeNo, oTradeNo) { return ERR_APP_PARAM_INVALID; } dwRet = GetPaymentByProviderTradeNo( oTradeNo.GetProviderPartnerNo(), oTradeNo.GetProviderTradeSerialNo());
Too Much Detail // inside SetupPayment function if (dwRet ==
ERR_PAYMENT_NOT_FOUND) { CPayment oPayment; oPayment.SetPaymentId(NextPaymentId()); oPayment.SetAmount(rTrade.GetAmount()); oPayment.SetBuyerUid(rTrade.GetBuyerUid()); oPayment.SetSellerUid(rTrade.GetSellerUid()); // ... 50 lines more oPayment.SetLastUpdateTime(CTime::Now()); dwRet = m_pDao->SavePayment(oPayment); if (dwRet != 0) { // ... 10 lines of error handling } return dwRet; }
Too Much Detail // inside SetupPayment function if (dwRet ==
ERR_PAYMENT_NOT_FOUND) { CPayment oPayment; oPayment.SetPaymentId(NextPaymentId()); oPayment.SetAmount(rTrade.GetAmount()); oPayment.SetBuyerUid(rTrade.GetBuyerUid()); oPayment.SetSellerUid(rTrade.GetSellerUid()); // ... 50 lines more oPayment.SetLastUpdateTime(CTime::Now()); dwRet = m_pDao->SavePayment(oPayment); if (dwRet != 0) { // ... 10 lines of error handling } return dwRet; }
Code Closer To Problem // inside SetupPayment function if (IsPaymentNotExist(dwRet))
{ return CreatePayment(); } else { return MakeSurePriceHasNotChanged(); }
Code Closer To Problem // inside SetupPayment function if (IsPaymentNotExist(dwRet))
{ return CreatePayment(); } else { return MakeSurePriceHasNotChanged(); }
Keep Consistent Abstraction Level
Feature Envy // inside GetPaymentParameter function ... if (rProvider.GetType() ==
TENPAY) { BuildBasicParameter(rPayment); if (rSpec.GetPaymentMethod() == STANDARD) { BuildParameterOfTenpayStandardPayment(rPayment); } else if (rSpec.GetPaymentMethod() == BANK) { BuildParameterOfTenpayBankPayment(rPayment); } } ...
Feature Envy // inside GetPaymentParameter function ... if (rProvider.GetType() ==
TENPAY) { BuildBasicParameter(rPayment); if (rSpec.GetPaymentMethod() == STANDARD) { BuildParameterOfTenpayStandardPayment(rPayment); } else if (rSpec.GetPaymentMethod() == BANK) { BuildParameterOfTenpayBankPayment(rPayment); } } ...
Power Of Values IPaymentRequestBuilder Build Payment Request GetPaymentUrl CopyPaymentParameters CProviderType
CProvider CTenpayStandardPayment RequestBuilder Build Payment Request GetPaymentUrl CopyPaymentParameters CTenpayProviderType CTenpayBankPayment RequestBuilder Build Payment Request GetPaymentUrl CopyPaymentParameters CTenpayProviderType
The Clean Way // inside GetPaymentParameter function ... IPaymentRequestBuilder* pBuilder
= rSpec.GetPaymentMethod(). NewPaymentRequestBuilder(rProvider); pBuilder->Build(rPayment); ...
Open for Extension Close for Modification
Extract Hidden Concept // inside NotifyPayment function ... if (rPayment.GetCurrentProviderPaymentId()
== rProviderPayment.GetProviderPaymentId() && rPayment.IsWaitPay()) { rPayment.Accept(rProviderPayment); } ...
Extract Hidden Concept // inside NotifyPayment function ... if (rPayment.GetCurrentProviderPaymentId()
== rProviderPayment.GetProviderPaymentId() && rPayment.IsWaitPay()) { rPayment.Accept(rProviderPayment); } ...
Extract Hidden Concept Payment ProviderPayment IPaymentAcceptingPolicy *
Extract Hidden Concept // inside NotifyPayment function IPaymentAcceptingPolicy* paymentAcceptingPolicy; ...
if (paymentAcceptingPolicy->IsAllowedToAccept( rPayment, rProviderPayment)) { rPayment.Accept(rProviderPayment); } ...
Extract Hidden Concept // inside NotifyPayment function IPaymentAcceptingPolicy* paymentAcceptingPolicy; ...
if (paymentAcceptingPolicy->IsAllowedToAccept( rPayment, rProviderPayment)) { rPayment.Accept(rProviderPayment); } ...
Making Implicit Concept Explicit
Recommended Readings
None
None
Q & A
Thanks for your time