SlideShare a Scribd company logo
1 of 78
Download to read offline
Growing Object-Oriented System
Principles, Guidelines, and Methods
Kent Wang
Dec 6, 2012
13年6月6⽇日星期四
Agenda
• Introduction
• Understand The Problem
• Broad-Brush Design
• Implementation
• Recommended Readings
13年6月6⽇日星期四
Introduction
13年6月6⽇日星期四
Why This Talk
13年6月6⽇日星期四
13年6月6⽇日星期四
Software Developing
Is a Learning Process
13年6月6⽇日星期四
Feedback is Critical
Understand
the Problem
(Analysis)
Broad-Brush
Design
(Architecture)
Test Driven
Development
(Implementation)
Deployable
System
13年6月6⽇日星期四
Understand the Problem
13年6月6⽇日星期四
Understand The Problem
• User Story
• Use Case
• Conceptual Model
• Color Modeling
13年6月6⽇日星期四
User Story
Users could pay for their orders from
various platform via tenpay
13年6月6⽇日星期四
Use Case
User
Pay
13年6月6⽇日星期四
Use Case Is Valuable
But Not The End
13年6月6⽇日星期四
Digging A Conceptual Model
13年6月6⽇日星期四
Dig Conceptual Model
Payment
Partner
User
Payment
Type
Buyer
Seller
Partner
Trade
13年6月6⽇日星期四
Color Modeling
Moment-
Interval
Role
Description
Party /
Place /Thing
13年6月6⽇日星期四
User Story Changed
Users could pay for their orders from
various platform via tenpay or alipay
13年6月6⽇日星期四
Simple Solution
Payment
Partner
User
Payment
Type
Buyer
Seller
Partner
Trade
13年6月6⽇日星期四
The Missing Concept
Payment
Partner
User
Payment
Type
Buyer
Seller
Partner
Trade
Provider
Payment
Payment
Provider
13年6月6⽇日星期四
Models Are Not Right Or Wrong
They Are More Or Less Useful
13年6月6⽇日星期四
One Team, One Language
13年6月6⽇日星期四
Bounded Context
Payment
Partner
Payment
Type
Provider
Payment
Payment
Provider
13年6月6⽇日星期四
Context Map
Provider
Payment
Transaction
unipay tenpay
Transaction Map
13年6月6⽇日星期四
Get Help If Required
13年6月6⽇日星期四
Broad-Brush Design
13年6月6⽇日星期四
Broad-Brush Design
• Tackling Complexity
• Architectural Level
• Application Level
• Domain Model Level
13年6月6⽇日星期四
Tackling Complexity
13年6月6⽇日星期四
Separation of Concerns
13年6月6⽇日星期四
Layered Architecture
Application
Presentation
Data Source
13年6月6⽇日星期四
Layered Architecture
Application
Presentation
Data Source
Domain
13年6月6⽇日星期四
High Level of Abstraction
13年6月6⽇日星期四
High Level of Abstraction
13年6月6⽇日星期四
Architectural Level
13年6月6⽇日星期四
Infrastructure
• Distributed or Not
• Synchronous or Asynchronous
• Data Source
13年6月6⽇日星期四
Architectural Style
Transaction
Script
Table Module
Domain Model
Complexity
Tool-Chain
13年6月6⽇日星期四
Location of Domain Logic
DAOAO
Domain
vs.
13年6月6⽇日星期四
Concurrent Control
• Transaction is not Silver Bullet
• Optimistic or Pessimistic
• Offline or Not
13年6月6⽇日星期四
Application Level
13年6月6⽇日星期四
Walking Through Scenarios
User Submit
Payment
Save Payment
Get Payment
Parameter
Submit To
Provider
Presentation
Layer
Application
Layer
13年6月6⽇日星期四
Intension-Revealing Interface
CUnipayAO
GetPaymentParameter
CUnipayAO
ProcessTrade
vs.
13年6月6⽇日星期四
Do One Thing
CUnipayAO
GetPaymentParameter
Save or update
Payments
Assemble Payment
Parameters
13年6月6⽇日星期四
Command Query Separation
System CommandQuery
State A
State
B
13年6月6⽇日星期四
Command Query Separation
CUnipayAO
GetPaymentParameter
SetupPayment
Save or update
Payments
Assemble Payment
Parameters
13年6月6⽇日星期四
Module
Payment
Payment ProviderPartner
Notification HistorySecurity
Settlement
13年6月6⽇日星期四
Domain Model Level
13年6月6⽇日星期四
Simplify Associations
Payment
Partner
User
Payment
Type
Buyer
Seller
Partner
Trade
Provider
Payment
Payment
Provider
13年6月6⽇日星期四
Simplify Associations
Payment
Partner
Payment
Type
Partner
Trade
Provider
Payment
Payment
Provider
13年6月6⽇日星期四
Simplify Associations
Payment
Partner
Payment
Type
Provider
Payment
Payment
Provider
1..*
13年6月6⽇日星期四
Simplify Associations
Payment
Partner
Payment
Type
Provider
Payment
Payment
Provider
1
current
13年6月6⽇日星期四
Design Is Not Just A
Technical Issue
13年6月6⽇日星期四
Integrity Problem
ChargePlan
ChargePlan
LineItem
ChargePlan
LineItem
amount = 50 amount = 50
amount = 100
ChargePlan
LineItem
amount = 50
13年6月6⽇日星期四
Aggregate
ChargePlan
ChargePlan
LineItem
ChargePlan
LineItem
amount = 50 amount = 50
amount = 100
ChargePlan
LineItem
amount = 50
13年6月6⽇日星期四
Domain Model Pollution
ao_unipay_settle
Payment
Relay Service
ao_unipay
Transaction
13年6月6⽇日星期四
Anti-Corruption Layer
ao_unipay_settle nao_unipay_tenpay
Tenpay Service
Payment
Relay Service
ao_unipay
Transaction
13年6月6⽇日星期四
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
13年6月6⽇日星期四
Implementation
13年6月6⽇日星期四
Implementation
• Design Tools
• Make A New Type
• Consistent Abstraction Level
• Open Close Principle
• Extract Hidden Concept
13年6月6⽇日星期四
Costly Tools Don’t Produce
Better Designs
13年6月6⽇日星期四
UML Without CASE
13年6月6⽇日星期四
CRC Card
CTenpayProviderType
Make Tenpay Trade No
Make Tenpay Settle No
Get Request Builder
CTenpayTradeNo
CTenpayProvider
CTenpayRequest
Builder
Class
Responsibility
Collaborator
13年6月6⽇日星期四
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);
13年6月6⽇日星期四
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
13年6月6⽇日星期四
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());
13年6月6⽇日星期四
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;
}
13年6月6⽇日星期四
Code Closer To Problem
// inside SetupPayment function
if (IsPaymentNotExist(dwRet))
{
return CreatePayment();
}
else
{
return MakeSurePriceHasNotChanged();
}
13年6月6⽇日星期四
Keep Consistent
Abstraction Level
13年6月6⽇日星期四
Feature Envy
// inside GetPaymentParameter function
...
if (rProvider.GetType() == TENPAY)
{
BuildBasicParameter(rPayment);
if (rSpec.GetPaymentMethod() == STANDARD)
{
BuildParameterOfTenpayStandardPayment(rPayment);
}
else if (rSpec.GetPaymentMethod() == BANK)
{
BuildParameterOfTenpayBankPayment(rPayment);
}
}
...
13年6月6⽇日星期四
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
13年6月6⽇日星期四
The Clean Way
// inside GetPaymentParameter function
...
IPaymentRequestBuilder* pBuilder = rSpec.GetPaymentMethod().
NewPaymentRequestBuilder(rProvider);
pBuilder->Build(rPayment);
...
13年6月6⽇日星期四
Open for Extension
Close for Modification
13年6月6⽇日星期四
Extract Hidden Concept
// inside NotifyPayment function
...
if (rPayment.GetCurrentProviderPaymentId() ==
rProviderPayment.GetProviderPaymentId() &&
rPayment.IsWaitPay())
{
rPayment.Accept(rProviderPayment);
}
...
13年6月6⽇日星期四
Extract Hidden Concept
Payment ProviderPayment
IPaymentAcceptingPolicy
*
13年6月6⽇日星期四
Extract Hidden Concept
// inside NotifyPayment function
IPaymentAcceptingPolicy* paymentAcceptingPolicy;
...
if (paymentAcceptingPolicy->IsAllowedToAccept(
rPayment, rProviderPayment))
{
rPayment.Accept(rProviderPayment);
}
...
13年6月6⽇日星期四
Making Implicit Concept
Explicit
13年6月6⽇日星期四
Recommended Readings
13年6月6⽇日星期四
13年6月6⽇日星期四
13年6月6⽇日星期四
Q & A
13年6月6⽇日星期四
Thanks for your time
13年6月6⽇日星期四

More Related Content

Similar to Growing object oriented system

Practice: Refactor with Tests
Practice: Refactor with TestsPractice: Refactor with Tests
Practice: Refactor with TestsManic Chuang
 
Our experience to start a startup
Our experience to start a startupOur experience to start a startup
Our experience to start a startupYenwen Feng
 
Design Method_20190529
Design Method_20190529Design Method_20190529
Design Method_20190529Winny Wang
 
QM-060-問題分析與解決能力提升
QM-060-問題分析與解決能力提升QM-060-問題分析與解決能力提升
QM-060-問題分析與解決能力提升handbook
 
台中市創業平台建置計畫
台中市創業平台建置計畫台中市創業平台建置計畫
台中市創業平台建置計畫Chris 克里斯
 
企業個案報告寫作(2012版)
企業個案報告寫作(2012版)企業個案報告寫作(2012版)
企業個案報告寫作(2012版)基欽 劉
 
Scrum gathering 2012 shanghai 产品管理及用户体验 分会场:敏捷的hard模式 产品经理视角(窦涵之)
Scrum gathering 2012 shanghai 产品管理及用户体验 分会场:敏捷的hard模式 产品经理视角(窦涵之)Scrum gathering 2012 shanghai 产品管理及用户体验 分会场:敏捷的hard模式 产品经理视角(窦涵之)
Scrum gathering 2012 shanghai 产品管理及用户体验 分会场:敏捷的hard模式 产品经理视角(窦涵之)LetAgileFly
 
2012/05/23 AU Talk - 讓事情發生
2012/05/23 AU Talk - 讓事情發生2012/05/23 AU Talk - 讓事情發生
2012/05/23 AU Talk - 讓事情發生appuniverz
 
service design 20221118
service design 20221118service design 20221118
service design 20221118Winny Wang
 
QM-064-常用QC手法
QM-064-常用QC手法QM-064-常用QC手法
QM-064-常用QC手法handbook
 
AgileNeihuSprint31
AgileNeihuSprint31AgileNeihuSprint31
AgileNeihuSprint31ccdouplus
 
Azurebootcamp 2018
Azurebootcamp 2018Azurebootcamp 2018
Azurebootcamp 2018Ian Chen
 
Project GATE 的敏捷實踐之路
Project GATE 的敏捷實踐之路Project GATE 的敏捷實踐之路
Project GATE 的敏捷實踐之路AgileCommunity
 
2013 TQC+ Java 認證研習簡報
2013 TQC+ Java 認證研習簡報2013 TQC+ Java 認證研習簡報
2013 TQC+ Java 認證研習簡報Kyle Lin
 
為了精準估算,你必須付出什麼代價?
為了精準估算,你必須付出什麼代價?為了精準估算,你必須付出什麼代價?
為了精準估算,你必須付出什麼代價?William Yeh
 
service design 20221104
service design 20221104service design 20221104
service design 20221104Winny Wang
 
美团点评技术沙龙011 - 客户端用户体验数据量化
美团点评技术沙龙011 - 客户端用户体验数据量化美团点评技术沙龙011 - 客户端用户体验数据量化
美团点评技术沙龙011 - 客户端用户体验数据量化美团点评技术团队
 

Similar to Growing object oriented system (20)

Practice: Refactor with Tests
Practice: Refactor with TestsPractice: Refactor with Tests
Practice: Refactor with Tests
 
Be the Owner
Be the OwnerBe the Owner
Be the Owner
 
Our experience to start a startup
Our experience to start a startupOur experience to start a startup
Our experience to start a startup
 
Design Method_20190529
Design Method_20190529Design Method_20190529
Design Method_20190529
 
SCRUM
SCRUMSCRUM
SCRUM
 
QM-060-問題分析與解決能力提升
QM-060-問題分析與解決能力提升QM-060-問題分析與解決能力提升
QM-060-問題分析與解決能力提升
 
台中市創業平台建置計畫
台中市創業平台建置計畫台中市創業平台建置計畫
台中市創業平台建置計畫
 
企業個案報告寫作(2012版)
企業個案報告寫作(2012版)企業個案報告寫作(2012版)
企業個案報告寫作(2012版)
 
Scrum gathering 2012 shanghai 产品管理及用户体验 分会场:敏捷的hard模式 产品经理视角(窦涵之)
Scrum gathering 2012 shanghai 产品管理及用户体验 分会场:敏捷的hard模式 产品经理视角(窦涵之)Scrum gathering 2012 shanghai 产品管理及用户体验 分会场:敏捷的hard模式 产品经理视角(窦涵之)
Scrum gathering 2012 shanghai 产品管理及用户体验 分会场:敏捷的hard模式 产品经理视角(窦涵之)
 
2012/05/23 AU Talk - 讓事情發生
2012/05/23 AU Talk - 讓事情發生2012/05/23 AU Talk - 讓事情發生
2012/05/23 AU Talk - 讓事情發生
 
service design 20221118
service design 20221118service design 20221118
service design 20221118
 
QM-064-常用QC手法
QM-064-常用QC手法QM-064-常用QC手法
QM-064-常用QC手法
 
AgileNeihuSprint31
AgileNeihuSprint31AgileNeihuSprint31
AgileNeihuSprint31
 
Azurebootcamp 2018
Azurebootcamp 2018Azurebootcamp 2018
Azurebootcamp 2018
 
Project GATE 的敏捷實踐之路
Project GATE 的敏捷實踐之路Project GATE 的敏捷實踐之路
Project GATE 的敏捷實踐之路
 
2013 TQC+ Java 認證研習簡報
2013 TQC+ Java 認證研習簡報2013 TQC+ Java 認證研習簡報
2013 TQC+ Java 認證研習簡報
 
為了精準估算,你必須付出什麼代價?
為了精準估算,你必須付出什麼代價?為了精準估算,你必須付出什麼代價?
為了精準估算,你必須付出什麼代價?
 
service design 20221104
service design 20221104service design 20221104
service design 20221104
 
美团点评技术沙龙011 - 客户端用户体验数据量化
美团点评技术沙龙011 - 客户端用户体验数据量化美团点评技术沙龙011 - 客户端用户体验数据量化
美团点评技术沙龙011 - 客户端用户体验数据量化
 
20150206 aic machine learning
20150206 aic machine learning20150206 aic machine learning
20150206 aic machine learning
 

Growing object oriented system