Skip to content

Commit 60cc004

Browse files
authored
Provide test case for the GRASP Information Expert principle (#68)
1 parent 223b6ef commit 60cc004

File tree

4 files changed

+85
-3
lines changed

4 files changed

+85
-3
lines changed

CleanCode/src/main/java/pl/mperor/lab/java/clean/code/ddd/value/object/Money.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
import java.math.BigDecimal;
44
import java.math.RoundingMode;
55

6-
record Money(BigDecimal amount) {
6+
public record Money(BigDecimal amount) {
77

8-
Money(BigDecimal amount) {
8+
public static Money ZERO = new Money(BigDecimal.ZERO);
9+
10+
public Money(BigDecimal amount) {
911
if (amount == null) {
1012
throw new IllegalArgumentException("Amount must not be null");
1113
}
@@ -27,6 +29,10 @@ public Money subtract(Money other) {
2729
return new Money(this.amount.subtract(other.amount));
2830
}
2931

32+
public Money multiply(BigDecimal multiplier) {
33+
return new Money(this.amount.multiply(multiplier));
34+
}
35+
3036
public static Money of(BigDecimal amount) {
3137
return new Money(amount);
3238
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package pl.mperor.lab.java.clean.code.grasp;
2+
3+
/**
4+
* General Responsibility Assignment Software Pattern (1997)
5+
* - OOP design principles.
6+
*/
7+
public interface GRASP {
8+
}

CleanCode/src/test/java/pl/mperor/lab/java/clean/code/ddd/value/object/ValueObjectTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class ValueObjectTest {
2121

2222
@Test
2323
void shouldAllowToUseMoneyAsValueObject() {
24-
var money = Money.of(BigDecimal.ZERO);
24+
var money = Money.ZERO;
2525
Assertions.assertEquals(BigDecimal.ZERO.setScale(2, RoundingMode.HALF_EVEN), money.amount());
2626

2727
Assertions.assertThrows(IllegalArgumentException.class, () -> new Money(null));
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package pl.mperor.lab.java.clean.code.grasp;
2+
3+
import org.junit.jupiter.api.Assertions;
4+
import org.junit.jupiter.api.Test;
5+
import pl.mperor.lab.java.clean.code.ddd.value.object.Money;
6+
7+
import java.math.BigDecimal;
8+
import java.util.Arrays;
9+
import java.util.List;
10+
11+
/**
12+
* 🤓 Information Expert
13+
*
14+
* <p>The principle states that a class should be responsible for behavior
15+
* that is directly related to its data.
16+
*
17+
* This test verifies that:
18+
* <ul>
19+
* <li>{@link Order} calculates its total price.</li>
20+
* <li>{@link Cart} aggregates the total cost of multiple orders.</li>
21+
* </ul>
22+
* Each class encapsulates its own logic, following the principle of expert knowledge.
23+
*/
24+
class InformationExpertTest {
25+
26+
record Cart(List<Order> order) {
27+
Cart(Order... orders) {
28+
this(Arrays.asList(orders));
29+
}
30+
31+
Cart(List<Order> order) {
32+
this.order = List.copyOf(order);
33+
}
34+
35+
Money totalCost() {
36+
return order.stream()
37+
.map(Order::totalPrice)
38+
.reduce(Money.ZERO, Money::add);
39+
}
40+
}
41+
42+
record Order(OrderItem item, int quantity) {
43+
Order {
44+
if (quantity < 1) {
45+
throw new IllegalArgumentException("Quantity must be greater then 0!");
46+
}
47+
}
48+
49+
Money totalPrice() {
50+
return item.price.multiply(BigDecimal.valueOf(quantity));
51+
}
52+
}
53+
54+
record OrderItem(String name, Money price) {}
55+
56+
@Test
57+
void cartShouldFollowInformationExpertPrinciple () {
58+
var pencil = new OrderItem("Pencil", Money.of(BigDecimal.ONE));
59+
var rubber = new OrderItem("Rubber", Money.of(new BigDecimal("1.5")));
60+
var cart = new Cart(
61+
new Order(pencil, 2),
62+
new Order(rubber, 1)
63+
);
64+
65+
Assertions.assertEquals(new Money(new BigDecimal("3.50")), cart.totalCost());
66+
Assertions.assertThrows(IllegalArgumentException.class, () -> new Order(pencil, 0));
67+
}
68+
}

0 commit comments

Comments
 (0)