|
| 1 | +--- |
| 2 | +title: "Money Pattern in Java: Encapsulating Monetary Values with Currency Consistency" |
| 3 | +shortTitle: Money |
| 4 | +description: "Learn how the Money design pattern in Java ensures currency safety, precision handling, and maintainable financial operations. Explore examples, applicability, and benefits of the pattern." |
| 5 | +category: Behavioral |
| 6 | +language: en |
| 7 | +tag: |
| 8 | + - Encapsulation |
| 9 | + - Precision handling |
| 10 | + - Currency safety |
| 11 | + - Value Object |
| 12 | + - Financial operations |
| 13 | + - Currency |
| 14 | + - Financial |
| 15 | + - Immutable |
| 16 | + - Value Object |
| 17 | +--- |
| 18 | + |
| 19 | +## Also known as |
| 20 | + |
| 21 | +* Monetary Value Object |
| 22 | + |
| 23 | +## Intent of Money Design Pattern |
| 24 | + |
| 25 | +The Money design pattern provides a robust way to encapsulate monetary values and their associated currencies. It ensures precise calculations, currency consistency, and maintainability of financial logic in Java applications. |
| 26 | + |
| 27 | +## Detailed Explanation of Money Pattern with Real-World Examples |
| 28 | + |
| 29 | +### Real-world example |
| 30 | + |
| 31 | +> Imagine an e-commerce platform where customers shop in their local currencies. The platform needs to calculate order totals, taxes, and discounts accurately while handling multiple currencies seamlessly. |
| 32 | +
|
| 33 | +In this example: |
| 34 | +- Each monetary value (like a product price or tax amount) is encapsulated in a `Money` object. |
| 35 | +- The `Money` class ensures that only values in the same currency are combined and supports safe currency conversion for global operations. |
| 36 | + |
| 37 | +### In plain words |
| 38 | + |
| 39 | +> The Money pattern encapsulates both an amount and its currency, ensuring financial operations are precise, consistent, and maintainable. |
| 40 | +
|
| 41 | +### Wikipedia says |
| 42 | + |
| 43 | +> "The Money design pattern encapsulates a monetary value and its currency, allowing for safe arithmetic operations and conversions while preserving accuracy and consistency in financial calculations." |
| 44 | +
|
| 45 | +## Programmatic Example of Money Pattern in Java |
| 46 | + |
| 47 | +### Money Class |
| 48 | + |
| 49 | +```java |
| 50 | + |
| 51 | +/** |
| 52 | + * Represents a monetary value with an associated currency. |
| 53 | + * Provides operations for basic arithmetic (addition, subtraction, multiplication), |
| 54 | + * as well as currency conversion while ensuring proper rounding. |
| 55 | + */ |
| 56 | +@Getter |
| 57 | +public class Money { |
| 58 | + private @Getter double amount; |
| 59 | + private @Getter String currency; |
| 60 | + |
| 61 | + public Money(double amnt, String curr) { |
| 62 | + this.amount = amnt; |
| 63 | + this.currency = curr; |
| 64 | + } |
| 65 | + |
| 66 | + private double roundToTwoDecimals(double value) { |
| 67 | + return Math.round(value * 100.0) / 100.0; |
| 68 | + } |
| 69 | + |
| 70 | + public void addMoney(Money moneyToBeAdded) throws CannotAddTwoCurrienciesException { |
| 71 | + if (!moneyToBeAdded.getCurrency().equals(this.currency)) { |
| 72 | + throw new CannotAddTwoCurrienciesException("You are trying to add two different currencies"); |
| 73 | + } |
| 74 | + this.amount = roundToTwoDecimals(this.amount + moneyToBeAdded.getAmount()); |
| 75 | + } |
| 76 | + |
| 77 | + public void subtractMoney(Money moneyToBeSubtracted) throws CannotSubtractException { |
| 78 | + if (!moneyToBeSubtracted.getCurrency().equals(this.currency)) { |
| 79 | + throw new CannotSubtractException("You are trying to subtract two different currencies"); |
| 80 | + } else if (moneyToBeSubtracted.getAmount() > this.amount) { |
| 81 | + throw new CannotSubtractException("The amount you are trying to subtract is larger than the amount you have"); |
| 82 | + } |
| 83 | + this.amount = roundToTwoDecimals(this.amount - moneyToBeSubtracted.getAmount()); |
| 84 | + } |
| 85 | + |
| 86 | + public void multiply(int factor) { |
| 87 | + if (factor < 0) { |
| 88 | + throw new IllegalArgumentException("Factor must be non-negative"); |
| 89 | + } |
| 90 | + this.amount = roundToTwoDecimals(this.amount * factor); |
| 91 | + } |
| 92 | + |
| 93 | + public void exchangeCurrency(String currencyToChangeTo, double exchangeRate) { |
| 94 | + if (exchangeRate < 0) { |
| 95 | + throw new IllegalArgumentException("Exchange rate must be non-negative"); |
| 96 | + } |
| 97 | + this.amount = roundToTwoDecimals(this.amount * exchangeRate); |
| 98 | + this.currency = currencyToChangeTo; |
| 99 | + } |
| 100 | +} |
| 101 | + |
| 102 | +## When to Use the Money Pattern |
| 103 | + |
| 104 | +The Money pattern should be used in scenarios where: |
| 105 | + |
| 106 | +1. **Currency-safe arithmetic operations** |
| 107 | + To ensure that arithmetic operations like addition, subtraction, and multiplication are performed only between amounts in the same currency, preventing inconsistencies or errors in calculations. |
| 108 | + |
| 109 | +2. **Accurate rounding for financial calculations** |
| 110 | + Precise rounding to two decimal places is critical to maintain accuracy and consistency in financial systems. |
| 111 | + |
| 112 | +3. **Consistent currency conversion** |
| 113 | + When handling international transactions or displaying monetary values in different currencies, the Money pattern facilitates easy and reliable conversion using exchange rates. |
| 114 | + |
| 115 | +4. **Encapsulation of monetary logic** |
| 116 | + By encapsulating all monetary operations within a dedicated class, the Money pattern improves maintainability and reduces the likelihood of errors. |
| 117 | + |
| 118 | +5. **Preventing errors in financial operations** |
| 119 | + Strict validation ensures that operations like subtraction or multiplication are only performed when conditions are met, safeguarding against misuse or logical errors. |
| 120 | + |
| 121 | +6. **Handling diverse scenarios in financial systems** |
| 122 | + Useful in complex systems like e-commerce, banking, and payroll applications where precise and consistent monetary value handling is crucial. |
| 123 | + |
| 124 | +--- |
| 125 | +## Benefits and Trade-offs of Money Pattern |
| 126 | + |
| 127 | +### Benefits |
| 128 | +1. **Precision and Accuracy** |
| 129 | + The Money pattern ensures precise handling of monetary values, reducing the risk of rounding errors. |
| 130 | + |
| 131 | +2. **Encapsulation of Business Logic** |
| 132 | + By encapsulating monetary operations, the pattern enhances maintainability and reduces redundancy in financial systems. |
| 133 | + |
| 134 | +3. **Currency Safety** |
| 135 | + It ensures operations are performed only between amounts of the same currency, avoiding logical errors. |
| 136 | + |
| 137 | +4. **Improved Readability** |
| 138 | + By abstracting monetary logic into a dedicated class, the code becomes easier to read and maintain. |
| 139 | + |
| 140 | +5. **Ease of Extension** |
| 141 | + Adding new operations, handling different currencies, or incorporating additional business rules is straightforward. |
| 142 | + |
| 143 | +### Trade-offs |
| 144 | +1. **Increased Complexity** |
| 145 | + Introducing a dedicated `Money` class can add some overhead, especially for small or simple projects. |
| 146 | + |
| 147 | +2. **Potential for Misuse** |
| 148 | + Without proper validation and handling, incorrect usage of the Money pattern may introduce subtle bugs. |
| 149 | + |
| 150 | +3. **Performance Overhead** |
| 151 | + Precision and encapsulation might slightly affect performance in systems with extremely high transaction volumes. |
| 152 | + |
| 153 | +--- |
| 154 | + |
| 155 | +## Related Design Patterns |
| 156 | + |
| 157 | +1. **Value Object** |
| 158 | + Money is a classic example of the Value Object pattern, where objects are immutable and define equality based on their value. |
| 159 | + Link:https://martinfowler.com/bliki/ValueObject.html |
| 160 | +2. **Factory Method** |
| 161 | + Factories can be employed to handle creation logic, such as applying default exchange rates or rounding rules. |
| 162 | + Link:https://www.geeksforgeeks.org/factory-method-for-designing-pattern/ |
| 163 | +--- |
| 164 | + |
| 165 | +## References and Credits |
| 166 | + |
| 167 | +- [Patterns of Enterprise Application Architecture](https://martinfowler.com/eaaCatalog/money.html) by Martin Fowler |
| 168 | +- [Design Patterns: Elements of Reusable Object-Oriented Software](https://amzn.to/3w0pvKI) |
0 commit comments