Files
java-design-patterns/money/README.md
T
Ahmed-Taha-981 cdb78d7fb6 feat: Money pattern (#3109)
* Money pattern

the implementation of the money patter and the tests along with the read me file

* Update money/README.md

Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>

* added App file anf modified README file and pom.xml file

* modified README and pom.xml

* added comments

* Added a test for App.java

---------

Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
2025-01-06 19:19:22 +02:00

169 lines
6.8 KiB
Markdown

---
title: "Money Pattern in Java: Encapsulating Monetary Values with Currency Consistency"
shortTitle: Money
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."
category: Behavioral
language: en
tag:
- Encapsulation
- Precision handling
- Currency safety
- Value Object
- Financial operations
- Currency
- Financial
- Immutable
- Value Object
---
## Also known as
* Monetary Value Object
## Intent of Money Design Pattern
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.
## Detailed Explanation of Money Pattern with Real-World Examples
### Real-world example
> 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.
In this example:
- Each monetary value (like a product price or tax amount) is encapsulated in a `Money` object.
- The `Money` class ensures that only values in the same currency are combined and supports safe currency conversion for global operations.
### In plain words
> The Money pattern encapsulates both an amount and its currency, ensuring financial operations are precise, consistent, and maintainable.
### Wikipedia says
> "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."
## Programmatic Example of Money Pattern in Java
### Money Class
```java
/**
* Represents a monetary value with an associated currency.
* Provides operations for basic arithmetic (addition, subtraction, multiplication),
* as well as currency conversion while ensuring proper rounding.
*/
@Getter
public class Money {
private @Getter double amount;
private @Getter String currency;
public Money(double amnt, String curr) {
this.amount = amnt;
this.currency = curr;
}
private double roundToTwoDecimals(double value) {
return Math.round(value * 100.0) / 100.0;
}
public void addMoney(Money moneyToBeAdded) throws CannotAddTwoCurrienciesException {
if (!moneyToBeAdded.getCurrency().equals(this.currency)) {
throw new CannotAddTwoCurrienciesException("You are trying to add two different currencies");
}
this.amount = roundToTwoDecimals(this.amount + moneyToBeAdded.getAmount());
}
public void subtractMoney(Money moneyToBeSubtracted) throws CannotSubtractException {
if (!moneyToBeSubtracted.getCurrency().equals(this.currency)) {
throw new CannotSubtractException("You are trying to subtract two different currencies");
} else if (moneyToBeSubtracted.getAmount() > this.amount) {
throw new CannotSubtractException("The amount you are trying to subtract is larger than the amount you have");
}
this.amount = roundToTwoDecimals(this.amount - moneyToBeSubtracted.getAmount());
}
public void multiply(int factor) {
if (factor < 0) {
throw new IllegalArgumentException("Factor must be non-negative");
}
this.amount = roundToTwoDecimals(this.amount * factor);
}
public void exchangeCurrency(String currencyToChangeTo, double exchangeRate) {
if (exchangeRate < 0) {
throw new IllegalArgumentException("Exchange rate must be non-negative");
}
this.amount = roundToTwoDecimals(this.amount * exchangeRate);
this.currency = currencyToChangeTo;
}
}
## When to Use the Money Pattern
The Money pattern should be used in scenarios where:
1. **Currency-safe arithmetic operations**
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.
2. **Accurate rounding for financial calculations**
Precise rounding to two decimal places is critical to maintain accuracy and consistency in financial systems.
3. **Consistent currency conversion**
When handling international transactions or displaying monetary values in different currencies, the Money pattern facilitates easy and reliable conversion using exchange rates.
4. **Encapsulation of monetary logic**
By encapsulating all monetary operations within a dedicated class, the Money pattern improves maintainability and reduces the likelihood of errors.
5. **Preventing errors in financial operations**
Strict validation ensures that operations like subtraction or multiplication are only performed when conditions are met, safeguarding against misuse or logical errors.
6. **Handling diverse scenarios in financial systems**
Useful in complex systems like e-commerce, banking, and payroll applications where precise and consistent monetary value handling is crucial.
---
## Benefits and Trade-offs of Money Pattern
### Benefits
1. **Precision and Accuracy**
The Money pattern ensures precise handling of monetary values, reducing the risk of rounding errors.
2. **Encapsulation of Business Logic**
By encapsulating monetary operations, the pattern enhances maintainability and reduces redundancy in financial systems.
3. **Currency Safety**
It ensures operations are performed only between amounts of the same currency, avoiding logical errors.
4. **Improved Readability**
By abstracting monetary logic into a dedicated class, the code becomes easier to read and maintain.
5. **Ease of Extension**
Adding new operations, handling different currencies, or incorporating additional business rules is straightforward.
### Trade-offs
1. **Increased Complexity**
Introducing a dedicated `Money` class can add some overhead, especially for small or simple projects.
2. **Potential for Misuse**
Without proper validation and handling, incorrect usage of the Money pattern may introduce subtle bugs.
3. **Performance Overhead**
Precision and encapsulation might slightly affect performance in systems with extremely high transaction volumes.
---
## Related Design Patterns
1. **Value Object**
Money is a classic example of the Value Object pattern, where objects are immutable and define equality based on their value.
Link:https://martinfowler.com/bliki/ValueObject.html
2. **Factory Method**
Factories can be employed to handle creation logic, such as applying default exchange rates or rounding rules.
Link:https://www.geeksforgeeks.org/factory-method-for-designing-pattern/
---
## References and Credits
- [Patterns of Enterprise Application Architecture](https://martinfowler.com/eaaCatalog/money.html) by Martin Fowler
- [Design Patterns: Elements of Reusable Object-Oriented Software](https://amzn.to/3w0pvKI)