From 528350ce2baa1aaf2f2d53d8ff927ee0018608f0 Mon Sep 17 00:00:00 2001 From: mperor Date: Wed, 5 Feb 2025 11:12:08 +0100 Subject: [PATCH] Add chain of responsibility design pattern --- DesignPatterns/README.md | 1 + .../chain/of/responsibility/Banknote.java | 13 +++++++ .../of/responsibility/BanknotePocket.java | 17 +++++++++ .../Dollar100WithdrawalChain.java | 8 +++++ .../Dollar10WithdrawalChain.java | 8 +++++ .../Dollar200WithdrawalChain.java | 9 +++++ .../Dollar20WithdrawalChain.java | 8 +++++ .../Dollar50WithdrawalChain.java | 8 +++++ .../of/responsibility/WithdrawalChain.java | 36 +++++++++++++++++++ .../responsibility/WithdrawalChainTest.java | 24 +++++++++++++ 10 files changed, 132 insertions(+) create mode 100644 DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/Banknote.java create mode 100644 DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/BanknotePocket.java create mode 100644 DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/Dollar100WithdrawalChain.java create mode 100644 DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/Dollar10WithdrawalChain.java create mode 100644 DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/Dollar200WithdrawalChain.java create mode 100644 DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/Dollar20WithdrawalChain.java create mode 100644 DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/Dollar50WithdrawalChain.java create mode 100644 DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/WithdrawalChain.java create mode 100644 DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/WithdrawalChainTest.java diff --git a/DesignPatterns/README.md b/DesignPatterns/README.md index e57e99f..978ee05 100644 --- a/DesignPatterns/README.md +++ b/DesignPatterns/README.md @@ -9,6 +9,7 @@ with practical examples and best practices for using design patterns to create r ### Behavioral Design Patterns 💪 +- [Chain of Responsibility](src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility) 🔗 - [Command](src/main/java/pl/mperor/lab/java/design/pattern/behavioral/command) 📝 - [Execute Around Method (EAM)](src/main/java/pl/mperor/lab/java/design/pattern/behavioral/eam) ⭕ - [Observer](src/main/java/pl/mperor/lab/java/design/pattern/behavioral/observer) 👀 diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/Banknote.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/Banknote.java new file mode 100644 index 0000000..5957dc5 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/Banknote.java @@ -0,0 +1,13 @@ +package pl.mperor.lab.java.design.pattern.behavioral.chain.of.responsibility; + +enum Banknote { + $10, + $20, + $50, + $100, + $200; + + int getValue() { + return Integer.parseInt(this.name().substring(1)); + } +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/BanknotePocket.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/BanknotePocket.java new file mode 100644 index 0000000..8f67d33 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/BanknotePocket.java @@ -0,0 +1,17 @@ +package pl.mperor.lab.java.design.pattern.behavioral.chain.of.responsibility; + +import java.util.EnumMap; +import java.util.Map; + +class BanknotePocket { + + private final Map noteToAmount = new EnumMap<>(Banknote.class); + + void add(Banknote note, Integer amount) { + noteToAmount.put(note, amount); + } + + Integer get(Banknote note) { + return noteToAmount.getOrDefault(note, 0); + } +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/Dollar100WithdrawalChain.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/Dollar100WithdrawalChain.java new file mode 100644 index 0000000..9e01b1f --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/Dollar100WithdrawalChain.java @@ -0,0 +1,8 @@ +package pl.mperor.lab.java.design.pattern.behavioral.chain.of.responsibility; + +class Dollar100WithdrawalChain extends WithdrawalChain { + + Dollar100WithdrawalChain(int amount) { + super(Banknote.$100, amount); + } +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/Dollar10WithdrawalChain.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/Dollar10WithdrawalChain.java new file mode 100644 index 0000000..299fee2 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/Dollar10WithdrawalChain.java @@ -0,0 +1,8 @@ +package pl.mperor.lab.java.design.pattern.behavioral.chain.of.responsibility; + +class Dollar10WithdrawalChain extends WithdrawalChain { + + Dollar10WithdrawalChain(int amount) { + super(Banknote.$10, amount); + } +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/Dollar200WithdrawalChain.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/Dollar200WithdrawalChain.java new file mode 100644 index 0000000..a585eca --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/Dollar200WithdrawalChain.java @@ -0,0 +1,9 @@ +package pl.mperor.lab.java.design.pattern.behavioral.chain.of.responsibility; + +class Dollar200WithdrawalChain extends WithdrawalChain { + + Dollar200WithdrawalChain(int amount) { + super(Banknote.$200, amount); + } + +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/Dollar20WithdrawalChain.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/Dollar20WithdrawalChain.java new file mode 100644 index 0000000..e2e2f83 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/Dollar20WithdrawalChain.java @@ -0,0 +1,8 @@ +package pl.mperor.lab.java.design.pattern.behavioral.chain.of.responsibility; + +class Dollar20WithdrawalChain extends WithdrawalChain { + + Dollar20WithdrawalChain(int amount) { + super(Banknote.$20, amount); + } +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/Dollar50WithdrawalChain.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/Dollar50WithdrawalChain.java new file mode 100644 index 0000000..8bd1bc9 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/Dollar50WithdrawalChain.java @@ -0,0 +1,8 @@ +package pl.mperor.lab.java.design.pattern.behavioral.chain.of.responsibility; + +class Dollar50WithdrawalChain extends WithdrawalChain { + + Dollar50WithdrawalChain(int amount) { + super(Banknote.$50, amount); + } +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/WithdrawalChain.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/WithdrawalChain.java new file mode 100644 index 0000000..10393d4 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/WithdrawalChain.java @@ -0,0 +1,36 @@ +package pl.mperor.lab.java.design.pattern.behavioral.chain.of.responsibility; + +abstract class WithdrawalChain { + + protected final Banknote banknote; + protected int banknoteAmount; + protected WithdrawalChain nextChain; + + WithdrawalChain(Banknote banknote, int amount) { + this.banknote = banknote; + this.banknoteAmount = amount; + } + + BanknotePocket withdraw(int currency) { + int banknoteValue = banknote.getValue(); + int restValue = currency; + int banknoteCounter = 0; + + while (restValue - banknoteValue >= 0 && banknoteAmount > 0) { + restValue -= banknoteValue; + banknoteCounter++; + } + + BanknotePocket pocket = nextChain == null + ? new BanknotePocket() + : nextChain.withdraw(restValue); + + pocket.add(banknote, banknoteCounter); + return pocket; + } + + WithdrawalChain next(WithdrawalChain next) { + nextChain = next; + return next; + } +} \ No newline at end of file diff --git a/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/WithdrawalChainTest.java b/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/WithdrawalChainTest.java new file mode 100644 index 0000000..0159992 --- /dev/null +++ b/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/behavioral/chain/of/responsibility/WithdrawalChainTest.java @@ -0,0 +1,24 @@ +package pl.mperor.lab.java.design.pattern.behavioral.chain.of.responsibility; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class WithdrawalChainTest { + + @Test + public void testWithdrawBanknotes() { + WithdrawalChain parentChain = new Dollar200WithdrawalChain(2); + parentChain.next(new Dollar100WithdrawalChain(2)) + .next(new Dollar50WithdrawalChain(2)) + .next(new Dollar20WithdrawalChain(2)) + .next(new Dollar10WithdrawalChain(2)); + + BanknotePocket pocket = parentChain.withdraw(360); + + Assertions.assertEquals(1, pocket.get(Banknote.$200)); + Assertions.assertEquals(1, pocket.get(Banknote.$100)); + Assertions.assertEquals(1, pocket.get(Banknote.$50)); + Assertions.assertEquals(0, pocket.get(Banknote.$20)); + Assertions.assertEquals(1, pocket.get(Banknote.$10)); + } +} \ No newline at end of file