Download - So We Thought We Knew Money
![Page 1: So We Thought We Knew Money](https://reader033.vdocuments.net/reader033/viewer/2022051609/547e3427b4af9fc9158b5626/html5/thumbnails/1.jpg)
So We Thought We Knew Money
Ying Hu Sam [email protected] [email protected]
Custom House Global Foreign Exchange
![Page 2: So We Thought We Knew Money](https://reader033.vdocuments.net/reader033/viewer/2022051609/547e3427b4af9fc9158b5626/html5/thumbnails/2.jpg)
Outline
• Background• The problem in the system• Distilling the domain model and the discovery
of the value objects• Refactoring, differences before and after• Compromises and pitfalls
![Page 3: So We Thought We Knew Money](https://reader033.vdocuments.net/reader033/viewer/2022051609/547e3427b4af9fc9158b5626/html5/thumbnails/3.jpg)
The Domain
• Foreign exchange is all we do
![Page 4: So We Thought We Knew Money](https://reader033.vdocuments.net/reader033/viewer/2022051609/547e3427b4af9fc9158b5626/html5/thumbnails/4.jpg)
In our system…
• Variable names of primitive data types public class Contract { decimal tradingRate; bool isRateDirect; string tradeCurrency; decimal tradeAmount; string settlementCurrency; decimal settlementAmount; decimal Markup; … …
decimal GetRate(string unitCurrency, string referenceCurrency);
• Method names, parameters, return types
![Page 5: So We Thought We Knew Money](https://reader033.vdocuments.net/reader033/viewer/2022051609/547e3427b4af9fc9158b5626/html5/thumbnails/5.jpg)
Implicit Domain ConceptPublic Class Contract{ decimal CalculateSettlementAmount(
bool isRateDirect,decimal tradeAmount,decimal tradingRate)
{if (isRateDirect)
return tradeAmount * tradingRate;else
return tradeAmount / tradingRate; }
decimal settlementAmount = CalculateSettlementAmount(true, 200m, 1.12m);
//……}
Public Class Contract{ decimal ApplyMarkup( decimal rate, decimal markup, bool isPercentageMarkup, bool isBuyMarkup) { if (isBuyMarkup) { if (isPercentageMarkup)
return rate* (1-markup); else
return rate-markup; } else { if (isPercentageMarkup)
return rate* (1+markup); else
return rate+markup; } }
decimal newRate = ApplyMarkup(1.12, 0.02, true, false);
}
![Page 6: So We Thought We Knew Money](https://reader033.vdocuments.net/reader033/viewer/2022051609/547e3427b4af9fc9158b5626/html5/thumbnails/6.jpg)
Distilling the Domain
• Domain Driven Design– Excessive use of primitive data types– Lack of ubiquitous language
• Distilling Domain Model (phase one)– Discovery of domain fundamental value objects– Refactoring
![Page 7: So We Thought We Knew Money](https://reader033.vdocuments.net/reader033/viewer/2022051609/547e3427b4af9fc9158b5626/html5/thumbnails/7.jpg)
Value Objects - Rate • Encapsulate domain logicClass Contract{ decimal CalculateSettlementAmount(
bool isRateDirect,decimal tradeAmount,decimal tradingRate)
{if (isRateDirect)
return tradeAmount * tradingRate;else
return tradeAmount / tradingRate;
}
// …….
decimal settlementAmount =CalculateSettlementAmount(true, 200m, 1.12m);
Class Rate{ Currency unitCurrency; Currency settlementCurrency; decimal value; public Money Convert (Money money);}
Class Contract { Money settlementMoney = tradingRate.Convert(tradeMoney);}
![Page 8: So We Thought We Knew Money](https://reader033.vdocuments.net/reader033/viewer/2022051609/547e3427b4af9fc9158b5626/html5/thumbnails/8.jpg)
Class Contract
public decimal ApplyMarkup( decimal rate, decimal markup, bool isPercentageMarkup, bool isBuyMarkup){ if (isBuyMarkup) { if (isPercentageMarkup)
return rate* (1-markup); else
return rate-markup; } else { if (isPercentageMarkup)
return rate* (1+markup); else
return rate+markup; }}
decimal newRate = ApplyMarkup(1.12, 0.02, true, false);
Value Objects - Markup
Class Markup
public Rate AppliedTo(Rate rate);
Class Contract
Rate newRate = markup.AppliedTo(oldRate);
![Page 9: So We Thought We Knew Money](https://reader033.vdocuments.net/reader033/viewer/2022051609/547e3427b4af9fc9158b5626/html5/thumbnails/9.jpg)
Value Objects
• Simplifying interfacespublic decimal CalculateProfit(
string tradeCurrency, decimal tradeAmount,string settlementCurrency, decimal settlementAmount )
public Money CalculateProfit(money tradeMoney, money settlementMoney)
• Type safedecimal GetRate(
string unitCurrency,string referenceCurrency);
Rate GetRate(Currency unitCurrency,Currency referenceCurrency);
Currency gbp = CurrencyList.Get(“GBP”);
![Page 10: So We Thought We Knew Money](https://reader033.vdocuments.net/reader033/viewer/2022051609/547e3427b4af9fc9158b5626/html5/thumbnails/10.jpg)
Refactoring
• Shared code base (CVS)• Unit test suites• Continuous integration• 2 developers working on refactoring, others
working on upcoming release• 2 weeks to redesign and refactor• Tool: Jetbrain’s Resharper
![Page 11: So We Thought We Knew Money](https://reader033.vdocuments.net/reader033/viewer/2022051609/547e3427b4af9fc9158b5626/html5/thumbnails/11.jpg)
Compromises…• Refactor important interfaces
public class Order{ private decimal settlementAmount; private string settlementCurrency;
public string SettlementCurrency { get { return settlementCurrency; } }
public decimal SettlementAmount { get { return settlementAmount;} }}
public class Order{ private decimal settlementAmount; private string settlementCurrency;
public Money SettlementMoney { get{ return new Money(settlementCurrency,settlementAmount); } }}
![Page 12: So We Thought We Knew Money](https://reader033.vdocuments.net/reader033/viewer/2022051609/547e3427b4af9fc9158b5626/html5/thumbnails/12.jpg)
…And Pitfallspublic class Rate{
public static implicit operator decimal(Rate rate){
return rate.Value;}
public Money AddMoney(Money target, Money moneyToAdd) {
return target + Convert(moneyToAdd); }
}
X
![Page 13: So We Thought We Knew Money](https://reader033.vdocuments.net/reader033/viewer/2022051609/547e3427b4af9fc9158b5626/html5/thumbnails/13.jpg)
Today and Beyond
• More domain fundamental objects are discovered.
• More interfaces and classes have been refactored
• Richer, evolving domain model• Confidence and skills to refactor
![Page 14: So We Thought We Knew Money](https://reader033.vdocuments.net/reader033/viewer/2022051609/547e3427b4af9fc9158b5626/html5/thumbnails/14.jpg)
Summary
• Domain Driven Design: make hidden domain concept explicit– http://www.domaindrivendesign.com
• A concrete example of refactoring: replacing primitive types with value objects.
• Share our experiences as well as pitfalls.
![Page 15: So We Thought We Knew Money](https://reader033.vdocuments.net/reader033/viewer/2022051609/547e3427b4af9fc9158b5626/html5/thumbnails/15.jpg)
Thank you for your attention
• IAnticorruption – A Domain Driven Approach To More Robust Integration
by Sam Peng and Ying Hu