Growing object oriented system
-
Upload
xprayc -
Category
Technology
-
view
187 -
download
0
Transcript of Growing object oriented system
![Page 1: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/1.jpg)
Growing Object-Oriented SystemPrinciples, Guidelines, and Methods
Kent WangDec 6, 2012
13年6月6⽇日星期四
![Page 2: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/2.jpg)
Agenda
• Introduction
• Understand The Problem
• Broad-Brush Design
• Implementation
• Recommended Readings
13年6月6⽇日星期四
![Page 3: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/3.jpg)
Introduction
13年6月6⽇日星期四
![Page 4: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/4.jpg)
Why This Talk
13年6月6⽇日星期四
![Page 5: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/5.jpg)
13年6月6⽇日星期四
![Page 6: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/6.jpg)
Software Developing Is a Learning Process
13年6月6⽇日星期四
![Page 7: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/7.jpg)
Feedback is Critical
Understandthe Problem(Analysis)
Broad-BrushDesign
(Architecture)
Test DrivenDevelopment
(Implementation)
DeployableSystem
13年6月6⽇日星期四
![Page 8: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/8.jpg)
Understand the Problem
13年6月6⽇日星期四
![Page 9: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/9.jpg)
Understand The Problem
• User Story
• Use Case
• Conceptual Model
• Color Modeling
13年6月6⽇日星期四
![Page 10: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/10.jpg)
User Story
Users could pay for their orders from various platform via tenpay
13年6月6⽇日星期四
![Page 11: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/11.jpg)
Use Case
UserPay
13年6月6⽇日星期四
![Page 12: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/12.jpg)
Use Case Is Valuable But Not The End
13年6月6⽇日星期四
![Page 13: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/13.jpg)
Digging A Conceptual Model
13年6月6⽇日星期四
![Page 14: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/14.jpg)
Dig Conceptual Model
Payment
Partner
User
PaymentType
Buyer
Seller
PartnerTrade
13年6月6⽇日星期四
![Page 15: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/15.jpg)
Color Modeling
Moment-Interval
Role
Description
Party / Place /Thing
13年6月6⽇日星期四
![Page 16: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/16.jpg)
User Story Changed
Users could pay for their orders from various platform via tenpay or alipay
13年6月6⽇日星期四
![Page 17: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/17.jpg)
Simple Solution
Payment
Partner
User
PaymentType
Buyer
Seller
PartnerTrade
13年6月6⽇日星期四
![Page 18: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/18.jpg)
The Missing Concept
Payment
Partner
UserPayment
Type
Buyer
Seller
PartnerTrade
ProviderPayment
PaymentProvider
13年6月6⽇日星期四
![Page 19: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/19.jpg)
Models Are Not Right Or Wrong They Are More Or Less Useful
13年6月6⽇日星期四
![Page 20: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/20.jpg)
One Team, One Language
13年6月6⽇日星期四
![Page 21: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/21.jpg)
Bounded Context
Payment
Partner
PaymentType
ProviderPayment
PaymentProvider
13年6月6⽇日星期四
![Page 22: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/22.jpg)
Context Map
ProviderPayment Transaction
unipay tenpayTransaction Map
13年6月6⽇日星期四
![Page 23: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/23.jpg)
Get Help If Required
13年6月6⽇日星期四
![Page 24: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/24.jpg)
Broad-Brush Design
13年6月6⽇日星期四
![Page 25: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/25.jpg)
Broad-Brush Design
• Tackling Complexity
• Architectural Level
• Application Level
• Domain Model Level
13年6月6⽇日星期四
![Page 26: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/26.jpg)
Tackling Complexity
13年6月6⽇日星期四
![Page 27: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/27.jpg)
Separation of Concerns
13年6月6⽇日星期四
![Page 28: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/28.jpg)
Layered Architecture
Application
Presentation
Data Source
13年6月6⽇日星期四
![Page 29: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/29.jpg)
Layered Architecture
Application
Presentation
Data Source
Domain
13年6月6⽇日星期四
![Page 30: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/30.jpg)
High Level of Abstraction
13年6月6⽇日星期四
![Page 31: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/31.jpg)
High Level of Abstraction
13年6月6⽇日星期四
![Page 32: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/32.jpg)
Architectural Level
13年6月6⽇日星期四
![Page 33: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/33.jpg)
Infrastructure
• Distributed or Not
• Synchronous or Asynchronous
• Data Source
13年6月6⽇日星期四
![Page 34: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/34.jpg)
Architectural Style
TransactionScript
Table Module
Domain Model
Complexity
Tool-Chain
13年6月6⽇日星期四
![Page 35: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/35.jpg)
Location of Domain Logic
DAOAO
Domain
vs.
13年6月6⽇日星期四
![Page 36: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/36.jpg)
Concurrent Control
• Transaction is not Silver Bullet
• Optimistic or Pessimistic
• Offline or Not
13年6月6⽇日星期四
![Page 37: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/37.jpg)
Application Level
13年6月6⽇日星期四
![Page 38: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/38.jpg)
Walking Through Scenarios
User Submit Payment
Save PaymentGet Payment Parameter
Submit To Provider
PresentationLayer
ApplicationLayer
13年6月6⽇日星期四
![Page 39: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/39.jpg)
Intension-Revealing Interface
CUnipayAO
GetPaymentParameter
CUnipayAO
ProcessTrade vs.
13年6月6⽇日星期四
![Page 40: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/40.jpg)
Do One Thing
CUnipayAO
GetPaymentParameter
Save or update Payments
Assemble Payment Parameters
13年6月6⽇日星期四
![Page 41: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/41.jpg)
Command Query Separation
System CommandQuery
State A
State B
13年6月6⽇日星期四
![Page 42: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/42.jpg)
Command Query Separation
CUnipayAO
GetPaymentParameter
SetupPaymentSave or update
Payments
Assemble Payment Parameters
13年6月6⽇日星期四
![Page 43: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/43.jpg)
Module
Payment
Payment ProviderPartner
Notification HistorySecurity
Settlement
13年6月6⽇日星期四
![Page 44: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/44.jpg)
Domain Model Level
13年6月6⽇日星期四
![Page 45: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/45.jpg)
Simplify Associations
Payment
Partner
UserPayment
Type
Buyer
Seller
PartnerTrade
ProviderPayment
PaymentProvider
13年6月6⽇日星期四
![Page 46: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/46.jpg)
Simplify Associations
Payment
Partner
PaymentType
PartnerTrade
ProviderPayment
PaymentProvider
13年6月6⽇日星期四
![Page 47: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/47.jpg)
Simplify Associations
Payment
Partner
PaymentType
ProviderPayment
PaymentProvider
1..*
13年6月6⽇日星期四
![Page 48: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/48.jpg)
Simplify Associations
Payment
Partner
PaymentType
ProviderPayment
PaymentProvider
1current
13年6月6⽇日星期四
![Page 49: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/49.jpg)
Design Is Not Just A Technical Issue
13年6月6⽇日星期四
![Page 50: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/50.jpg)
Integrity Problem
ChargePlan
ChargePlanLineItem
ChargePlanLineItem
amount = 50 amount = 50
amount = 100
ChargePlanLineItem
amount = 50
13年6月6⽇日星期四
![Page 51: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/51.jpg)
Aggregate
ChargePlan
ChargePlanLineItem
ChargePlanLineItem
amount = 50 amount = 50
amount = 100
ChargePlanLineItem
amount = 50
13年6月6⽇日星期四
![Page 52: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/52.jpg)
Domain Model Pollution
ao_unipay_settle
PaymentRelay Service
ao_unipay
Transaction
13年6月6⽇日星期四
![Page 53: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/53.jpg)
Anti-Corruption Layer
ao_unipay_settle nao_unipay_tenpay
Tenpay Service Payment
Relay Service
ao_unipay
Transaction
13年6月6⽇日星期四
![Page 54: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/54.jpg)
Design To Test
Tenpay ServiceFacade
Mock Tenpay Relay Client
Tenpay ServiceFacade Test
1. RegisterChargePlan(plan)
3. Execute(request, response)
4. Checking Request5. ReturnResponse
6. Return Response
7. ParseResponse
2. Assemble Request
8. Return Result
9. Checking Result
13年6月6⽇日星期四
![Page 55: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/55.jpg)
Implementation
13年6月6⽇日星期四
![Page 56: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/56.jpg)
Implementation
• Design Tools
• Make A New Type
• Consistent Abstraction Level
• Open Close Principle
• Extract Hidden Concept
13年6月6⽇日星期四
![Page 57: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/57.jpg)
Costly Tools Don’t Produce Better Designs
13年6月6⽇日星期四
![Page 58: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/58.jpg)
UML Without CASE
13年6月6⽇日星期四
![Page 59: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/59.jpg)
CRC CardCTenpayProviderType
Make Tenpay Trade No
Make Tenpay Settle No
Get Request Builder
CTenpayTradeNo
CTenpayProvider
CTenpayRequestBuilder
Class
Respon
sibility
Collaborator
13年6月6⽇日星期四
![Page 60: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/60.jpg)
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⽇日星期四
![Page 61: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/61.jpg)
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 FromTrade No
13年6月6⽇日星期四
![Page 62: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/62.jpg)
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⽇日星期四
![Page 63: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/63.jpg)
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⽇日星期四
![Page 64: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/64.jpg)
Code Closer To Problem
// inside SetupPayment function
if (IsPaymentNotExist(dwRet)){ return CreatePayment();}else{ return MakeSurePriceHasNotChanged();}
13年6月6⽇日星期四
![Page 65: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/65.jpg)
Keep Consistent Abstraction Level
13年6月6⽇日星期四
![Page 66: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/66.jpg)
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⽇日星期四
![Page 67: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/67.jpg)
Power Of ValuesIPaymentRequestBuilder
Build Payment Request
GetPaymentUrlCopyPaymentParameters
CProviderType
CProvider
CTenpayStandardPaymentRequestBuilder
Build Payment Request
GetPaymentUrl
CopyPaymentParameters
CTenpayProviderType
CTenpayBankPaymentRequestBuilder
Build Payment Request
GetPaymentUrl
CopyPaymentParameters
CTenpayProviderType
13年6月6⽇日星期四
![Page 68: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/68.jpg)
The Clean Way
// inside GetPaymentParameter function
...
IPaymentRequestBuilder* pBuilder = rSpec.GetPaymentMethod().NewPaymentRequestBuilder(rProvider);
pBuilder->Build(rPayment);
...
13年6月6⽇日星期四
![Page 69: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/69.jpg)
Open for ExtensionClose for Modification
13年6月6⽇日星期四
![Page 70: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/70.jpg)
Extract Hidden Concept
// inside NotifyPayment function
...
if (rPayment.GetCurrentProviderPaymentId() == rProviderPayment.GetProviderPaymentId() &&
rPayment.IsWaitPay()){
rPayment.Accept(rProviderPayment);}
...
13年6月6⽇日星期四
![Page 71: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/71.jpg)
Extract Hidden Concept
Payment ProviderPayment
IPaymentAcceptingPolicy
*
13年6月6⽇日星期四
![Page 72: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/72.jpg)
Extract Hidden Concept
// inside NotifyPayment function
IPaymentAcceptingPolicy* paymentAcceptingPolicy;
...
if (paymentAcceptingPolicy->IsAllowedToAccept( rPayment, rProviderPayment))
{rPayment.Accept(rProviderPayment);
}
...
13年6月6⽇日星期四
![Page 73: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/73.jpg)
Making Implicit Concept Explicit
13年6月6⽇日星期四
![Page 74: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/74.jpg)
Recommended Readings
13年6月6⽇日星期四
![Page 75: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/75.jpg)
13年6月6⽇日星期四
![Page 76: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/76.jpg)
13年6月6⽇日星期四
![Page 77: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/77.jpg)
Q & A
13年6月6⽇日星期四
![Page 78: Growing object oriented system](https://reader033.fdocument.pub/reader033/viewer/2022052823/5550d649b4c905f2318b50ca/html5/thumbnails/78.jpg)
Thanks for your time
13年6月6⽇日星期四