diff --git a/02-structural/bridge/AdvancedRemote.java b/02-structural/bridge/AdvancedRemote.java index 452ea75..9e0e46e 100644 --- a/02-structural/bridge/AdvancedRemote.java +++ b/02-structural/bridge/AdvancedRemote.java @@ -1,23 +1,19 @@ package bridge; - /** - * Refined Abstraction — extends RemoteControl with extra features. - * This is how you vary the "abstraction" side independently of the - * "implementation" side. Both TV and Radio work with this remote, - * even though they know nothing about it. + * Refined Abstraction — extends RemoteControl with additional capabilities. + * + * The device hierarchy doesn't change at all. TV and Radio + * automatically support mute() and jumpToChannel() because they + * implement Device. Zero new code on the implementation side. */ public class AdvancedRemote extends RemoteControl { - public AdvancedRemote(Device device) { super(device); } - - // Extra feature not in the basic remote public void mute() { System.out.println(" Muting " + device.getName()); device.setVolume(0); } - public void jumpToChannel(int channel) { System.out.println(" Jumping to channel " + channel); device.setChannel(channel); diff --git a/02-structural/bridge/Device.java b/02-structural/bridge/Device.java index 47ab925..98daaa6 100644 --- a/02-structural/bridge/Device.java +++ b/02-structural/bridge/Device.java @@ -1,9 +1,8 @@ package bridge; - /** - * Implementor interface — the "implementation" side of the bridge. - * This is what the Abstraction delegates its real work to. - * TV, Radio, SmartSpeaker etc. all implement this. + * Implementor — the "implementation" side of the bridge. + * All devices (TV, Radio, SmartSpeaker, etc.) implement this. + * The remote controls only know about this interface, never about specific devices. */ public interface Device { boolean isEnabled(); diff --git a/02-structural/bridge/Main.java b/02-structural/bridge/Main.java index 0952884..358604c 100644 --- a/02-structural/bridge/Main.java +++ b/02-structural/bridge/Main.java @@ -1,29 +1,14 @@ package bridge; - -/** - * Bridge Design Pattern — Runnable Demo - * - * Shows how remotes (abstraction) and devices (implementation) - * can vary independently. 4 combinations from 2+2 classes, - * not 4 hard-coded classes. - * - * Run: javac bridge/*.java && java bridge.Main - * Article: https://ankurm.com/bridge-design-pattern-java/ - */ public class Main { - public static void main(String[] args) { System.out.println("=== Bridge Design Pattern Demo ===\n"); - // Combination 1: Basic Remote + TV System.out.println("-- Basic Remote controlling TV --"); RemoteControl remote1 = new RemoteControl(new TV()); remote1.togglePower(); remote1.volumeUp(); remote1.channelUp(); - System.out.println(); - // Combination 2: Advanced Remote + Radio System.out.println("-- Advanced Remote controlling Radio --"); AdvancedRemote remote2 = new AdvancedRemote(new Radio()); @@ -31,16 +16,13 @@ public class Main { remote2.volumeUp(); remote2.mute(); remote2.jumpToChannel(91); - System.out.println(); - - // Combination 3: Advanced Remote + TV (no new classes needed) + // Combination 3: Advanced Remote + TV (no new classes needed!) System.out.println("-- Advanced Remote controlling TV --"); AdvancedRemote remote3 = new AdvancedRemote(new TV()); remote3.togglePower(); remote3.jumpToChannel(5); remote3.mute(); - System.out.println("\n=== Demo complete ==="); System.out.println("3 different remote+device combinations, 0 new classes needed."); } diff --git a/02-structural/bridge/README.md b/02-structural/bridge/README.md index c13c174..99f9d05 100644 --- a/02-structural/bridge/README.md +++ b/02-structural/bridge/README.md @@ -10,21 +10,23 @@ Decouples remote controls (Abstraction) from devices (Implementation). A basic r ## How to run ```bash -javac bridge/*.java -java bridge.Main +javac bridge/*.java -d out/bridge +java -cp out/bridge bridge.Main ``` -Requires Java 11+. +Requires Java 25. -## Files +## Post Section ↔ File Mapping -| File | Role | +| Post Section | File(s) | |---|---| -| `Device.java` | Implementor interface | -| `TV.java` / `Radio.java` | Concrete Implementors | -| `RemoteControl.java` | Abstraction (holds Device bridge) | -| `AdvancedRemote.java` | Refined Abstraction | -| `Main.java` | Demo entry point | +| Step 1 — The Implementor Interface | `Device.java` | +| Step 2 — Concrete Implementors (TV and Radio) | `TV.java`, `Radio.java` | +| Step 3 — The Abstraction (RemoteControl) | `RemoteControl.java` | +| Step 4 — Refined Abstraction (AdvancedRemote) | `AdvancedRemote.java` | +| Wiring It Together: Main Demo | `Main.java` | + +Note: the "Class Explosion Problem — Visualised" pseudocode and the JDBC/SLF4J snippets shown in the article are illustrative only — they are not part of this repository's runnable example. Article: https://ankurm.com/bridge-design-pattern-java/ All patterns: https://ankurm.com/design-patterns-java/ diff --git a/02-structural/bridge/Radio.java b/02-structural/bridge/Radio.java index 9f67371..f538fea 100644 --- a/02-structural/bridge/Radio.java +++ b/02-structural/bridge/Radio.java @@ -1,29 +1,18 @@ package bridge; - -/** - * Concrete Implementor — a radio. - * Same Device interface, completely different internal behaviour. - */ +// Concrete Implementor #2: Radio public class Radio implements Device { - private boolean on = false; private int volume = 20; - private int channel = 1; // FM frequency index simplified - + private int channel = 1; @Override public boolean isEnabled() { return on; } @Override public void enable() { on = true; System.out.println(" [Radio] Powered ON"); } @Override public void disable() { on = false; System.out.println(" [Radio] Powered OFF"); } - - @Override - public int getVolume() { return volume; } - - @Override - public void setVolume(int percent) { + @Override public int getVolume() { return volume; } + @Override public void setVolume(int percent) { this.volume = Math.max(0, Math.min(100, percent)); System.out.println(" [Radio] Volume set to " + this.volume); } - - @Override public int getChannel() { return channel; } - @Override public void setChannel(int ch) { this.channel = ch; System.out.println(" [Radio] Frequency -> " + ch); } - @Override public String getName() { return "JBL Radio"; } + @Override public int getChannel() { return channel; } + @Override public void setChannel(int ch) { this.channel = ch; System.out.println(" [Radio] Frequency -> " + ch); } + @Override public String getName() { return "JBL Radio"; } } diff --git a/02-structural/bridge/RemoteControl.java b/02-structural/bridge/RemoteControl.java index 238aed8..5107fc8 100644 --- a/02-structural/bridge/RemoteControl.java +++ b/02-structural/bridge/RemoteControl.java @@ -1,22 +1,18 @@ package bridge; - /** - * Abstraction — the remote control. It holds a reference to a Device - * (the "bridge") and delegates all real work to it. + * Abstraction — the remote control. * - * The key: RemoteControl doesn't care whether it talks to a TV or Radio. - * It holds a Device and calls Device methods. That's the bridge. + * Key point: RemoteControl holds a Device (the bridge) and delegates + * all actual work to it. It adds higher-level semantics on top: + * "togglePower" instead of separate enable()/disable() calls. */ public class RemoteControl { - - // The bridge — link from Abstraction to Implementation - protected Device device; - + protected Device device; // THE BRIDGE public RemoteControl(Device device) { this.device = device; System.out.println("Remote paired with: " + device.getName()); } - + // User action → device operation translation public void togglePower() { if (device.isEnabled()) { device.disable(); @@ -24,10 +20,8 @@ public class RemoteControl { device.enable(); } } - public void volumeUp() { device.setVolume(device.getVolume() + 10); } public void volumeDown() { device.setVolume(device.getVolume() - 10); } - public void channelUp() { device.setChannel(device.getChannel() + 1); } public void channelDown() { device.setChannel(device.getChannel() - 1); } } diff --git a/02-structural/bridge/TV.java b/02-structural/bridge/TV.java index c956e4d..dbb46fc 100644 --- a/02-structural/bridge/TV.java +++ b/02-structural/bridge/TV.java @@ -1,29 +1,18 @@ package bridge; - -/** - * Concrete Implementor — a television. - * Contains device-specific logic for a TV. - */ +// Concrete Implementor #1: Television public class TV implements Device { - private boolean on = false; private int volume = 30; private int channel = 1; - @Override public boolean isEnabled() { return on; } @Override public void enable() { on = true; System.out.println(" [TV] Powered ON"); } @Override public void disable() { on = false; System.out.println(" [TV] Powered OFF"); } - - @Override - public int getVolume() { return volume; } - - @Override - public void setVolume(int percent) { + @Override public int getVolume() { return volume; } + @Override public void setVolume(int percent) { this.volume = Math.max(0, Math.min(100, percent)); System.out.println(" [TV] Volume set to " + this.volume); } - - @Override public int getChannel() { return channel; } - @Override public void setChannel(int ch) { this.channel = ch; System.out.println(" [TV] Channel -> " + ch); } - @Override public String getName() { return "Samsung TV"; } + @Override public int getChannel() { return channel; } + @Override public void setChannel(int ch) { this.channel = ch; System.out.println(" [TV] Channel -> " + ch); } + @Override public String getName() { return "Samsung TV"; } } diff --git a/README.md b/README.md index 97dfda6..c41c2c6 100644 --- a/README.md +++ b/README.md @@ -197,6 +197,24 @@ javac 02-structural/adapter/*.java -d out/adapter java -cp out/adapter adapter.Main ``` +### Bridge (`02-structural/bridge/`) + +| Post Section | File(s) | +|---|---| +| Step 1 — The Implementor Interface | `Device.java` | +| Step 2 — Concrete Implementors (TV and Radio) | `TV.java`, `Radio.java` | +| Step 3 — The Abstraction (RemoteControl) | `RemoteControl.java` | +| Step 4 — Refined Abstraction (AdvancedRemote) | `AdvancedRemote.java` | +| Wiring It Together: Main Demo | `Main.java` | + +Note: the "Class Explosion Problem — Visualised" pseudocode and the JDBC/SLF4J snippets are illustrative only — they are not part of this repository's runnable example. + +Run it: +```bash +javac 02-structural/bridge/*.java -d out/bridge +java -cp out/bridge bridge.Main +``` + ## Reference - *Design Patterns: Elements of Reusable Object-Oriented Software* — Gamma, Helm, Johnson, Vlissides