From 47996d7a6b45556ad0eb079b331be809d9fa8e7f Mon Sep 17 00:00:00 2001 From: mperor Date: Tue, 28 Jan 2025 11:25:07 +0100 Subject: [PATCH] Add observer design pattern with test case --- DesignPatterns/README.md | 6 +++-- .../pattern/behavioral/observer/Follower.java | 9 +++++++ .../behavioral/observer/MessageListener.java | 7 +++++ .../behavioral/observer/MessagePublisher.java | 10 +++++++ .../observer/SocialMediaAccount.java | 24 +++++++++++++++++ .../observer/MessageObserverTest.java | 26 +++++++++++++++++++ 6 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/observer/Follower.java create mode 100644 DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/observer/MessageListener.java create mode 100644 DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/observer/MessagePublisher.java create mode 100644 DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/observer/SocialMediaAccount.java create mode 100644 DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/behavioral/observer/MessageObserverTest.java diff --git a/DesignPatterns/README.md b/DesignPatterns/README.md index c19efc4..fdd95cb 100644 --- a/DesignPatterns/README.md +++ b/DesignPatterns/README.md @@ -2,15 +2,17 @@ ## Description 📄 -This project explores various design patterns and their implementations in modern Java. It aims to provide developers with practical examples and best practices for using design patterns to create robust and maintainable code. +This project explores various design patterns and their implementations in modern Java. It aims to provide developers +with practical examples and best practices for using design patterns to create robust and maintainable code. ## Design Pattern Catalog 📚 ### Behavioral Design Patterns 💪 - [Command](src/main/java/pl/mperor/lab/java/design/pattern/behavioral/command) 📝 -- [Strategy](src/main/java/pl/mperor/lab/java/design/pattern/behavioral/strategy) 🎯 - [Execute Around Method (EAM)](src/main/java/pl/mperor/lab/java/design/pattern/behavioral/eam) ⭕ +- [Strategy](src/main/java/pl/mperor/lab/java/design/pattern/behavioral/strategy) 🎯 +- [Observer](src/main/java/pl/mperor/lab/java/design/pattern/behavioral/observer) 👀 ### Creational Design Patterns 🏭 diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/observer/Follower.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/observer/Follower.java new file mode 100644 index 0000000..d9e0f37 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/observer/Follower.java @@ -0,0 +1,9 @@ +package pl.mperor.lab.java.design.pattern.behavioral.observer; + +public record Follower(String name) implements MessageListener { + + @Override + public void accept(String message) { + System.out.printf("%s received message: %s%n", name, message); + } +} \ No newline at end of file diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/observer/MessageListener.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/observer/MessageListener.java new file mode 100644 index 0000000..ea55401 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/observer/MessageListener.java @@ -0,0 +1,7 @@ +package pl.mperor.lab.java.design.pattern.behavioral.observer; + +@FunctionalInterface +public interface MessageListener { + + void accept(String message); +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/observer/MessagePublisher.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/observer/MessagePublisher.java new file mode 100644 index 0000000..47eceec --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/observer/MessagePublisher.java @@ -0,0 +1,10 @@ +package pl.mperor.lab.java.design.pattern.behavioral.observer; + +public interface MessagePublisher { + + void follow(MessageListener participant); + + void unfollow(MessageListener participant); + + void publish(String message); +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/observer/SocialMediaAccount.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/observer/SocialMediaAccount.java new file mode 100644 index 0000000..84a5ea4 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/observer/SocialMediaAccount.java @@ -0,0 +1,24 @@ +package pl.mperor.lab.java.design.pattern.behavioral.observer; + +import java.util.ArrayList; +import java.util.List; + +public class SocialMediaAccount implements MessagePublisher { + + private List followers = new ArrayList<>(); + + @Override + public void follow(MessageListener follower) { + followers.add(follower); + } + + @Override + public void unfollow(MessageListener follower) { + followers.remove(follower); + } + + @Override + public void publish(String message) { + followers.forEach(follower -> follower.accept(message)); + } +} diff --git a/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/behavioral/observer/MessageObserverTest.java b/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/behavioral/observer/MessageObserverTest.java new file mode 100644 index 0000000..49eb279 --- /dev/null +++ b/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/behavioral/observer/MessageObserverTest.java @@ -0,0 +1,26 @@ +package pl.mperor.lab.java.design.pattern.behavioral.observer; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import pl.mperor.lab.common.TestUtils; + +public class MessageObserverTest { + + @Test + public void messagePublisherShouldAllowToFollowHisMessages() { + var out = TestUtils.setTempSystemOut(); + + var socialMediaAccount = new SocialMediaAccount(); + socialMediaAccount.follow(new Follower("👨 Adam")); + socialMediaAccount.follow(new Follower("👩 Eva")); + socialMediaAccount.follow(message -> System.out.printf("🤖 I'm scanning your message: %s%n", message)); + socialMediaAccount.publish("Hello 🙋 everybody!"); + + var printedLines = out.lines(); + Assertions.assertEquals("👨 Adam received message: Hello 🙋 everybody!", printedLines.getFirst()); + Assertions.assertEquals("👩 Eva received message: Hello 🙋 everybody!", printedLines.getSecond()); + Assertions.assertEquals("🤖 I'm scanning your message: Hello 🙋 everybody!", printedLines.getThird()); + + TestUtils.resetSystemOut(); + } +} \ No newline at end of file