diff --git a/README.md b/README.md index 9e0034c..cfe72c5 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,33 @@ -# DesignPatternsJava9 -This repo consists Gang of Four Design patterns code on Java 9. Each branch in the repository has code of 1 design pattern. Switch repository to try out different design patterns. +# What is Observer Design Pattern +The observer pattern is a Behavioral design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes or updates. + +## Diagram +![Diagram](https://github.com/premaseem/DesignPatternsJava9/blob/observer-pattern/diagrams/Observer-Pattern-class-diagram.png "Diagram") + +![Diagram](https://github.com/premaseem/DesignPatternsJava9/blob/observer-pattern/diagrams/Observer-Design-Pattern-generic.jpeg "Diagram") + +![Diagram](https://github.com/premaseem/DesignPatternsJava9/blob/observer-pattern/diagrams/ObserverSequenceDiagram.png "Diagram") + +# When to use Observer Design Pattern +* Heavy used in "event driven" application +* It is suitable for any scenario that requires push-based notification. + +### Learn Design Patterns with Java by Aseem Jain +This repository contains working project code used in video Course by Packt Publication with title "Learn Design Patterns with Java " authored by "Aseem Jain". + +### Course link: +https://www.packtpub.com/application-development/learn-design-patterns-java-9-video + +### ![ http://in.linkedin.com/in/premaseem](https://github.com/premaseem/DesignPatternsJava9/blob/master/linkedin.png "http://in.linkedin.com/in/premaseem") Profile: http://in.linkedin.com/in/premaseem + +### Authors blog on design patterns: +https://premaseem.wordpress.com/category/computers/design-patterns/ + +### Software Design pattern community face book page: +https://www.facebook.com/DesignPatternGuru/ + +### Note: +* This code base will work on Java 9 and above versions. +* `diagrams` folders carry UML diagrams. +* `pattern` folder has code of primary example. +* `patternBonus` folder has code of secondary or bonus example. diff --git a/diagrams/Observer-Design-Pattern-generic.jpeg b/diagrams/Observer-Design-Pattern-generic.jpeg new file mode 100644 index 0000000..14b6efc Binary files /dev/null and b/diagrams/Observer-Design-Pattern-generic.jpeg differ diff --git a/diagrams/Observer-Pattern-class-diagram.png b/diagrams/Observer-Pattern-class-diagram.png new file mode 100644 index 0000000..9110b50 Binary files /dev/null and b/diagrams/Observer-Pattern-class-diagram.png differ diff --git a/diagrams/ObserverSequenceDiagram.png b/diagrams/ObserverSequenceDiagram.png new file mode 100644 index 0000000..0ce11b7 Binary files /dev/null and b/diagrams/ObserverSequenceDiagram.png differ diff --git a/pattern/src/com/premaseem/Client.java b/pattern/src/com/premaseem/Client.java deleted file mode 100644 index 15f05df..0000000 --- a/pattern/src/com/premaseem/Client.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.premaseem; - -/* -@author: Aseem Jain -@title: Design Patterns with Java 9 -@link: https://premaseem.wordpress.com/category/computers/design-patterns/ -@copyright: 2018 Packt Publication -*/ -public class Client { - public static void main (String[] args) { - System.out.println("Singleton cook example "); - } -} diff --git a/pattern/src/com/premaseem/client/ClientForShareTrading.java b/pattern/src/com/premaseem/client/ClientForShareTrading.java new file mode 100644 index 0000000..c411e14 --- /dev/null +++ b/pattern/src/com/premaseem/client/ClientForShareTrading.java @@ -0,0 +1,76 @@ +package com.premaseem.client; + +/* +@author: Aseem Jain +@title: Design Patterns with Java 9 +@link: https://premaseem.wordpress.com/category/computers/design-patterns/ +*/ + +import java.util.Random; +import java.util.Scanner; + +import com.premaseem.observable.SharePriceObservable; +import com.premaseem.observable.impl.AppleShares; +import com.premaseem.observable.impl.GoogleShares; +import com.premaseem.observer.ShareTraderObserver; +import com.premaseem.observer.impl.ShareTrader; + +public class ClientForShareTrading { + + public static void main (String[] args) { + Scanner scan = new Scanner(System.in); + int repeatRunFlag = 1; + while (repeatRunFlag == 1) { + + System.out.println("Share trading platform designed using Observer design pattern "); + System.out + .println("Notification service can be turned ON / OFF for multiple company's Share \n "); + ShareTraderObserver shareTrader = new ShareTrader(); + + SharePriceObservable appleShares = new AppleShares(); + SharePriceObservable googleShares = new GoogleShares(); + + System.out + .println("Do you want to observe share price and get notification / updates of Apple inc. shares ? "); + System.out.println("Press 1 for yes and 0 or other digits for no "); + int appleShareWatch = scan.nextInt(); + if (appleShareWatch == 1) { + appleShares.addObserver(shareTrader); + } else { + appleShares.removeObserver(shareTrader); + } + + System.out + .println("Do you want to observe share price and get notification / updates of Google inc. shares ? "); + System.out.println("Press 1 for yes and 0 or other digits for no "); + int googleShareWatch = scan.nextInt(); + if (googleShareWatch == 1) { + googleShares.addObserver(shareTrader); + } else { + googleShares.removeObserver(shareTrader); + } + + System.out.println("Simulating price change in Stock Market ^^--__-_-^^ "); + simulateSharePriceChange(appleShares); + simulateSharePriceChange(googleShares); + System.out.println("========================================"); + System.out + .println("Do you want to Re-run this program - Press 1 for yes and 0 or other digits to EXIT "); + repeatRunFlag = scan.nextInt(); + } + } + + public static void simulateSharePriceChange ( + SharePriceObservable sharePriceObservable) { + Random rnd = new Random(); + for (int i = 0; i < 3; i++) { + sharePriceObservable.setCurrentMarketPrice(rnd.nextInt()); + } + } +} + +/** Lesson Learnt + * Pooling or continuous monitoring is not required + * Loose coupling between Share trader (client-observer) + * and Share company (subject-observable) + * */ \ No newline at end of file diff --git a/pattern/src/com/premaseem/observable/SharePriceObservable.java b/pattern/src/com/premaseem/observable/SharePriceObservable.java new file mode 100644 index 0000000..8236d2a --- /dev/null +++ b/pattern/src/com/premaseem/observable/SharePriceObservable.java @@ -0,0 +1,16 @@ +package com.premaseem.observable; + + +import com.premaseem.observer.ShareTraderObserver; + +public interface SharePriceObservable { + + void addObserver (ShareTraderObserver shareTraderObserver); + + void removeObserver (ShareTraderObserver shareTraderObserver); + + void notifyObservers (); + + // This is just a work around to simulate the price from client side + public void setCurrentMarketPrice (Integer currentMarketPrice); +} diff --git a/pattern/src/com/premaseem/observable/impl/AppleShares.java b/pattern/src/com/premaseem/observable/impl/AppleShares.java new file mode 100644 index 0000000..67e4565 --- /dev/null +++ b/pattern/src/com/premaseem/observable/impl/AppleShares.java @@ -0,0 +1,46 @@ +package com.premaseem.observable.impl; +/* +@author: Aseem Jain +@title: Design Patterns with Java 9 +@link: https://premaseem.wordpress.com/category/computers/design-patterns/ +*/ + +import java.util.ArrayList; + +import com.premaseem.observable.SharePriceObservable; +import com.premaseem.observer.ShareTraderObserver; + +public class AppleShares implements SharePriceObservable { + + public ArrayList shareTraders = new ArrayList(); + private Integer currentMarketPrice = 0; + + @Override + public void addObserver (ShareTraderObserver shareTraderObserver) { + shareTraders.add(shareTraderObserver); + + } + + @Override + public void removeObserver (ShareTraderObserver shareTraderObserver) { + shareTraders.remove(shareTraderObserver); + + } + + @Override + public void notifyObservers () { + for (ShareTraderObserver shareBroker : shareTraders) { + shareBroker.notifyCurrentPrice(getCurrentMarketPrice(), " Apple Inc. "); + } + + } + + public Integer getCurrentMarketPrice () { + return currentMarketPrice; + } + + public void setCurrentMarketPrice (Integer currentMarketPrice) { + this.currentMarketPrice = currentMarketPrice; + notifyObservers(); + } +} diff --git a/pattern/src/com/premaseem/observable/impl/GoogleShares.java b/pattern/src/com/premaseem/observable/impl/GoogleShares.java new file mode 100644 index 0000000..87f1840 --- /dev/null +++ b/pattern/src/com/premaseem/observable/impl/GoogleShares.java @@ -0,0 +1,47 @@ +package com.premaseem.observable.impl; + +/* +@author: Aseem Jain +@title: Design Patterns with Java 9 +@link: https://premaseem.wordpress.com/category/computers/design-patterns/ +*/ + +import java.util.ArrayList; + +import com.premaseem.observable.SharePriceObservable; +import com.premaseem.observer.ShareTraderObserver; + +public class GoogleShares implements SharePriceObservable{ + + public ArrayList shareTraders = new ArrayList(); + private Integer currentMarketPrice=0; + + @Override + public void addObserver(ShareTraderObserver shareTraderObserver) { + shareTraders.add(shareTraderObserver); + + } + + @Override + public void removeObserver(ShareTraderObserver shareTraderObserver) { + shareTraders.remove(shareTraderObserver); + + } + + @Override + public void notifyObservers() { + for(ShareTraderObserver shareBroker : shareTraders){ + shareBroker.notifyCurrentPrice(getCurrentMarketPrice()," Google Inc. "); + } + + } + + public Integer getCurrentMarketPrice() { + return currentMarketPrice; + } + + public void setCurrentMarketPrice(Integer currentMarketPrice) { + this.currentMarketPrice = currentMarketPrice; + notifyObservers(); + } +} diff --git a/pattern/src/com/premaseem/observer/ShareTraderObserver.java b/pattern/src/com/premaseem/observer/ShareTraderObserver.java new file mode 100644 index 0000000..1ff4a43 --- /dev/null +++ b/pattern/src/com/premaseem/observer/ShareTraderObserver.java @@ -0,0 +1,7 @@ +package com.premaseem.observer; + +public interface ShareTraderObserver { + + public void notifyCurrentPrice (Integer shareLatestPrice, String shareCompanyName); + +} diff --git a/pattern/src/com/premaseem/observer/impl/ShareTrader.java b/pattern/src/com/premaseem/observer/impl/ShareTrader.java new file mode 100644 index 0000000..1f09a34 --- /dev/null +++ b/pattern/src/com/premaseem/observer/impl/ShareTrader.java @@ -0,0 +1,20 @@ +package com.premaseem.observer.impl; +/* +@author: Aseem Jain +@title: Design Patterns with Java 9 +@link: https://premaseem.wordpress.com/category/computers/design-patterns/ +*/ + +import com.premaseem.observer.ShareTraderObserver; + +public class ShareTrader implements ShareTraderObserver { + + @Override + public void notifyCurrentPrice(Integer shareLatestPrice, + String shareCompanyName) { + System.out.println(); + System.out.println(this.getClass().getSimpleName() + " received notification for Price change "); + System.out.printf("Price change notification - current price of %S Share is %d", shareCompanyName,shareLatestPrice); + System.out.println(); + } +} diff --git a/pattern/src/com/premaseem/observer/impl/ShareTrader1.java b/pattern/src/com/premaseem/observer/impl/ShareTrader1.java new file mode 100644 index 0000000..40fbcbc --- /dev/null +++ b/pattern/src/com/premaseem/observer/impl/ShareTrader1.java @@ -0,0 +1,15 @@ +package com.premaseem.observer.impl; + +import com.premaseem.observer.ShareTraderObserver; + +public class ShareTrader1 implements ShareTraderObserver { + + @Override + public void notifyCurrentPrice(Integer shareLatestPrice, + String shareCompanyName) { + System.out.println(); + System.out.println(this.getClass().getSimpleName() + ": Notified $$ "); + System.out.printf("Latest price of %S Share is %d ", shareCompanyName,shareLatestPrice); + System.out.println(); + } +} diff --git a/pattern/src/com/premaseem/observer/impl/ShareTrader2.java b/pattern/src/com/premaseem/observer/impl/ShareTrader2.java new file mode 100644 index 0000000..0e96d26 --- /dev/null +++ b/pattern/src/com/premaseem/observer/impl/ShareTrader2.java @@ -0,0 +1,14 @@ +package com.premaseem.observer.impl; + +import com.premaseem.observer.ShareTraderObserver; + +public class ShareTrader2 implements ShareTraderObserver { + @Override + public void notifyCurrentPrice(Integer shareLatestPrice, + String shareCompanyName) { + System.out.println(); + System.out.println(this.getClass().getSimpleName() + ": Notified $$ "); + System.out.printf("Latest price of %S Share is %d ", shareCompanyName,shareLatestPrice); + System.out.println(); + } +} diff --git a/patternBonus/src/com/premaseem/Client.java b/patternBonus/src/com/premaseem/Client.java deleted file mode 100644 index 15f05df..0000000 --- a/patternBonus/src/com/premaseem/Client.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.premaseem; - -/* -@author: Aseem Jain -@title: Design Patterns with Java 9 -@link: https://premaseem.wordpress.com/category/computers/design-patterns/ -@copyright: 2018 Packt Publication -*/ -public class Client { - public static void main (String[] args) { - System.out.println("Singleton cook example "); - } -} diff --git a/patternBonus/src/com/premaseem/ClientJavaApi.java b/patternBonus/src/com/premaseem/ClientJavaApi.java new file mode 100644 index 0000000..f05bee9 --- /dev/null +++ b/patternBonus/src/com/premaseem/ClientJavaApi.java @@ -0,0 +1,54 @@ +package com.premaseem; +/* +@author: Aseem Jain +@title: Design Patterns with Java 9 +@link: https://premaseem.wordpress.com/category/computers/design-patterns/ +*/ + +import java.util.Observable; +import java.util.Observer; +import java.util.Scanner; + +public class ClientJavaApi { + + public static void main(String[] args) { + + // Created subject + Subject subject = new Subject(); + + // Created Observer + Observer observer = new Observer() { + public void update(Observable obj, Object arg) { + System.out.println("Observer notified with update: " + arg); + } + }; + + // registered observer to the subject + subject.addObserver(observer); + + System.out.println("Make text updates in subject: "); + new Thread(subject).start(); + } +} + +class Subject extends Observable implements Runnable { + public void run() { + + // Every time whenever there is an update in subject, + // observer will be notified + while (true) { + String update = new Scanner(System.in).next(); + setChanged(); + notifyObservers(update); + } + } +} + +/** Lesson Learnt + * + * 1. Instead of creating our own observer and observable, + * using (java.util) Java api's implementation of observer and observable + * + * 2. Java 9 has deprecated above apis, WHY ? + * answer is in link -https://stackoverflow.com/questions/46380073/observer-is-deprecated-in-java-9-what-should-we-use-instead-of-it + * */