Skip to content

Commit 4afffa0

Browse files
authored
Merge branch 'master' into feature/template-view
2 parents 8b80235 + ebcc070 commit 4afffa0

File tree

22 files changed

+1315
-64
lines changed

22 files changed

+1315
-64
lines changed

.all-contributorsrc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3312,6 +3312,24 @@
33123312
"contributions": [
33133313
"translation"
33143314
]
3315+
},
3316+
{
3317+
"login": "HabibaMekay",
3318+
"name": "HabibaMekay",
3319+
"avatar_url": "https://avatars.githubusercontent.com/u/133516736?v=4",
3320+
"profile": "https://github.com/HabibaMekay",
3321+
"contributions": [
3322+
"code"
3323+
]
3324+
},
3325+
{
3326+
"login": "Ahmed-Taha-981",
3327+
"name": "Ahmed-Taha-981",
3328+
"avatar_url": "https://avatars.githubusercontent.com/u/122402269?v=4",
3329+
"profile": "https://github.com/Ahmed-Taha-981",
3330+
"contributions": [
3331+
"code"
3332+
]
33153333
}
33163334
],
33173335
"contributorsPerLine": 6,

.github/stale.yml

Lines changed: 0 additions & 61 deletions
This file was deleted.

.github/workflows/stale.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: 'Comment on stale issues and PRs'
2+
on:
3+
schedule:
4+
- cron: '30 1 * * *'
5+
6+
jobs:
7+
stale:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/stale@v9
11+
with:
12+
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity.'
13+
stale-pr-message: 'This PR is stale because it has been open 60 days with no activity.'
14+
close-issue-message: 'This issue was closed because it has been stalled for too long with no activity.'
15+
close-pr-message: 'This PR was closed because it has been stalled for too long with no activity.'
16+
days-before-issue-stale: 60
17+
days-before-pr-stale: 60
18+
days-before-issue-close: -1
19+
days-before-pr-close: -1

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=coverage)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns)
77
[![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
88
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
9-
[![All Contributors](https://img.shields.io/badge/all_contributors-362-orange.svg?style=flat-square)](#contributors-)
9+
[![All Contributors](https://img.shields.io/badge/all_contributors-365-orange.svg?style=flat-square)](#contributors-)
1010
<!-- ALL-CONTRIBUTORS-BADGE:END -->
1111

1212
<br/>
@@ -544,6 +544,8 @@ This project is licensed under the terms of the MIT license.
544544
<td align="center" valign="top" width="16.66%"><a href="https://github.com/SalmaAzeem"><img src="https://avatars.githubusercontent.com/u/121863224?v=4?s=100" width="100px;" alt="Salma"/><br /><sub><b>Salma</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=SalmaAzeem" title="Code">💻</a></td>
545545
<td align="center" valign="top" width="16.66%"><a href="https://codemaverick-143.github.io/My-Portfolio/"><img src="https://avatars.githubusercontent.com/u/182847716?v=4?s=100" width="100px;" alt="Arpit Sarang"/><br /><sub><b>Arpit Sarang</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=CodeMaverick-143" title="Code">💻</a></td>
546546
<td align="center" valign="top" width="16.66%"><a href="https://github.com/mayatarek"><img src="https://avatars.githubusercontent.com/u/111644421?v=4?s=100" width="100px;" alt="Maya"/><br /><sub><b>Maya</b></sub></a><br /><a href="#translation-mayatarek" title="Translation">🌍</a></td>
547+
<td align="center" valign="top" width="16.66%"><a href="https://github.com/HabibaMekay"><img src="https://avatars.githubusercontent.com/u/133516736?v=4?s=100" width="100px;" alt="HabibaMekay"/><br /><sub><b>HabibaMekay</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=HabibaMekay" title="Code">💻</a></td>
548+
<td align="center" valign="top" width="16.66%"><a href="https://github.com/Ahmed-Taha-981"><img src="https://avatars.githubusercontent.com/u/122402269?v=4?s=100" width="100px;" alt="Ahmed-Taha-981"/><br /><sub><b>Ahmed-Taha-981</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=Ahmed-Taha-981" title="Code">💻</a></td>
547549
</tr>
548550
</tbody>
549551
</table>

hexagonal-architecture/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
<dependency>
4747
<groupId>de.flapdoodle.embed</groupId>
4848
<artifactId>de.flapdoodle.embed.mongo</artifactId>
49-
<version>4.18.0</version>
49+
<version>4.18.1</version>
5050
<scope>test</scope>
5151
</dependency>
5252
<dependency>

money/README.md

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
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)

money/pom.xml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
4+
This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
5+
6+
The MIT License
7+
Copyright © 2014-2022 Ilkka Seppälä
8+
9+
Permission is hereby granted, free of charge, to any person obtaining a copy
10+
of this software and associated documentation files (the "Software"), to deal
11+
in the Software without restriction, including without limitation the rights
12+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
copies of the Software, and to permit persons to whom the Software is
14+
furnished to do so, subject to the following conditions:
15+
16+
The above copyright notice and this permission notice shall be included in
17+
all copies or substantial portions of the Software.
18+
19+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
THE SOFTWARE.
26+
27+
-->
28+
<project xmlns="http://maven.apache.org/POM/4.0.0"
29+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
30+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
31+
<modelVersion>4.0.0</modelVersion>
32+
<parent>
33+
<groupId>com.iluwatar</groupId>
34+
<artifactId>java-design-patterns</artifactId>
35+
<version>1.26.0-SNAPSHOT</version>
36+
</parent>
37+
38+
<artifactId>money</artifactId>
39+
40+
41+
<dependencies>
42+
<dependency>
43+
<groupId>org.junit.jupiter</groupId>
44+
<artifactId>junit-jupiter-api</artifactId>
45+
<scope>test</scope>
46+
</dependency>
47+
</dependencies>
48+
49+
</project>

0 commit comments

Comments
 (0)