Add all 23 GoF design pattern implementations
This commit is contained in:
22
03-behavioral/observer/AlertObserver.java
Normal file
22
03-behavioral/observer/AlertObserver.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package observer;
|
||||
|
||||
/** Fires an alert when the price changes by more than a threshold % */
|
||||
public class AlertObserver implements StockObserver {
|
||||
private final String name;
|
||||
private final double thresholdPercent;
|
||||
|
||||
public AlertObserver(String name, double thresholdPercent) {
|
||||
this.name = name;
|
||||
this.thresholdPercent = thresholdPercent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPriceChanged(String ticker, double oldPrice, double newPrice) {
|
||||
double change = Math.abs((newPrice - oldPrice) / oldPrice * 100);
|
||||
if (change >= thresholdPercent) {
|
||||
System.out.printf(" [ALERT:%s] %s moved %.1f%% — ALERT TRIGGERED%n", name, ticker, change);
|
||||
} else {
|
||||
System.out.printf(" [Alert:%s] %s moved %.1f%% — within threshold%n", name, ticker, change);
|
||||
}
|
||||
}
|
||||
}
|
||||
36
03-behavioral/observer/Main.java
Normal file
36
03-behavioral/observer/Main.java
Normal file
@@ -0,0 +1,36 @@
|
||||
package observer;
|
||||
|
||||
/**
|
||||
* Observer Design Pattern — Runnable Demo
|
||||
* Run: javac observer/*.java -d out/observer && java -cp out/observer observer.Main
|
||||
* Article: https://ankurm.com/observer-design-pattern-java/
|
||||
*/
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("=== Observer Design Pattern Demo ===\n");
|
||||
|
||||
StockMarket aapl = new StockMarket("AAPL", 175.00);
|
||||
|
||||
StockObserver alert = new AlertObserver("RiskEngine", 2.0);
|
||||
StockObserver alice = new PortfolioObserver("Alice", 100);
|
||||
StockObserver bob = new PortfolioObserver("Bob", 50);
|
||||
|
||||
aapl.subscribe(alert);
|
||||
aapl.subscribe(alice);
|
||||
aapl.subscribe(bob);
|
||||
|
||||
System.out.println();
|
||||
aapl.setPrice(178.50); // +2% — should trigger alert
|
||||
|
||||
System.out.println();
|
||||
aapl.setPrice(179.00); // small move
|
||||
|
||||
System.out.println("\n-- Bob unsubscribes --");
|
||||
aapl.unsubscribe(bob);
|
||||
|
||||
System.out.println();
|
||||
aapl.setPrice(165.00); // big drop — Bob doesn't hear it
|
||||
|
||||
System.out.println("\n=== Demo complete ===");
|
||||
}
|
||||
}
|
||||
19
03-behavioral/observer/PortfolioObserver.java
Normal file
19
03-behavioral/observer/PortfolioObserver.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package observer;
|
||||
|
||||
/** Updates portfolio value whenever a held stock changes price */
|
||||
public class PortfolioObserver implements StockObserver {
|
||||
private final String ownerName;
|
||||
private final int sharesHeld;
|
||||
|
||||
public PortfolioObserver(String ownerName, int sharesHeld) {
|
||||
this.ownerName = ownerName;
|
||||
this.sharesHeld = sharesHeld;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPriceChanged(String ticker, double oldPrice, double newPrice) {
|
||||
double gain = (newPrice - oldPrice) * sharesHeld;
|
||||
System.out.printf(" [Portfolio:%s] %s×%d P&L change: %+.2f%n",
|
||||
ownerName, ticker, sharesHeld, gain);
|
||||
}
|
||||
}
|
||||
32
03-behavioral/observer/README.md
Normal file
32
03-behavioral/observer/README.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Observer Design Pattern — Java Example
|
||||
|
||||
**Pattern:** Behavioral → Observer
|
||||
**Article:** https://ankurm.com/observer-design-pattern-java/
|
||||
|
||||
## What this example shows
|
||||
|
||||
A stock market subject that notifies subscribers without knowing what they do with the notification. `StockObserver` is the one-method interface every subscriber implements. `StockMarket` is the subject: it holds the observer list and pushes both the old and new price to every subscriber whenever `setPrice()` is called. `AlertObserver` and `PortfolioObserver` are two concrete observers that react completely differently to the same notification — one watches for threshold breaches, the other computes a P&L delta. `Main` subscribes all three, moves the price twice, then unsubscribes Bob before a third move so his portfolio observer never sees it.
|
||||
|
||||
## How to run
|
||||
|
||||
```bash
|
||||
javac observer/*.java -d out/observer
|
||||
java -cp out/observer observer.Main
|
||||
```
|
||||
|
||||
Requires Java 25.
|
||||
|
||||
## Post Section ↔ File Mapping
|
||||
|
||||
| Post Section | File(s) |
|
||||
|---|---|
|
||||
| Implementation: Stock Price Monitoring — the Observer interface | `StockObserver.java` |
|
||||
| Implementation: Stock Price Monitoring — the Subject | `StockMarket.java` |
|
||||
| Implementation: Stock Price Monitoring — AlertObserver | `AlertObserver.java` |
|
||||
| Implementation: Stock Price Monitoring — PortfolioObserver | `PortfolioObserver.java` |
|
||||
| Implementation: Stock Price Monitoring — wiring it together | `Main.java` |
|
||||
|
||||
Note: the "Push vs Pull Notification Models" pull-model snippet (`PullAlertObserver`) and the "Thread Safety" `CopyOnWriteArrayList` snippet are illustrative only — they are not part of this repository's runnable example.
|
||||
|
||||
Article: https://ankurm.com/observer-design-pattern-java/
|
||||
All patterns: https://ankurm.com/design-patterns-java/
|
||||
36
03-behavioral/observer/StockMarket.java
Normal file
36
03-behavioral/observer/StockMarket.java
Normal file
@@ -0,0 +1,36 @@
|
||||
package observer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Subject (Observable) — maintains a list of observers and notifies them
|
||||
* when the stock price changes. Observers register and deregister freely.
|
||||
*/
|
||||
public class StockMarket {
|
||||
private final String ticker;
|
||||
private double price;
|
||||
private final List<StockObserver> observers = new ArrayList<>();
|
||||
|
||||
public StockMarket(String ticker, double initialPrice) {
|
||||
this.ticker = ticker;
|
||||
this.price = initialPrice;
|
||||
System.out.println("[Market] " + ticker + " initialised at $" + initialPrice);
|
||||
}
|
||||
|
||||
public void subscribe(StockObserver observer) { observers.add(observer); }
|
||||
public void unsubscribe(StockObserver observer) { observers.remove(observer); }
|
||||
|
||||
public void setPrice(double newPrice) {
|
||||
double old = this.price;
|
||||
this.price = newPrice;
|
||||
System.out.printf("[Market] %s price: $%.2f -> $%.2f%n", ticker, old, newPrice);
|
||||
notifyObservers(old, newPrice);
|
||||
}
|
||||
|
||||
private void notifyObservers(double old, double newPrice) {
|
||||
for (StockObserver o : observers) {
|
||||
o.onPriceChanged(ticker, old, newPrice);
|
||||
}
|
||||
}
|
||||
}
|
||||
6
03-behavioral/observer/StockObserver.java
Normal file
6
03-behavioral/observer/StockObserver.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package observer;
|
||||
|
||||
/** Observer interface — all subscribers implement this */
|
||||
public interface StockObserver {
|
||||
void onPriceChanged(String ticker, double oldPrice, double newPrice);
|
||||
}
|
||||
Reference in New Issue
Block a user