Sync Bridge to Java 25: H6 file labels, README mapping

This commit is contained in:
2026-06-24 14:27:07 +05:30
parent 8471913dbd
commit 4091345b20
8 changed files with 58 additions and 89 deletions

View File

@@ -1,23 +1,19 @@
package bridge; package bridge;
/** /**
* Refined Abstraction — extends RemoteControl with extra features. * Refined Abstraction — extends RemoteControl with additional capabilities.
* This is how you vary the "abstraction" side independently of the *
* "implementation" side. Both TV and Radio work with this remote, * The device hierarchy doesn't change at all. TV and Radio
* even though they know nothing about it. * automatically support mute() and jumpToChannel() because they
* implement Device. Zero new code on the implementation side.
*/ */
public class AdvancedRemote extends RemoteControl { public class AdvancedRemote extends RemoteControl {
public AdvancedRemote(Device device) { public AdvancedRemote(Device device) {
super(device); super(device);
} }
// Extra feature not in the basic remote
public void mute() { public void mute() {
System.out.println(" Muting " + device.getName()); System.out.println(" Muting " + device.getName());
device.setVolume(0); device.setVolume(0);
} }
public void jumpToChannel(int channel) { public void jumpToChannel(int channel) {
System.out.println(" Jumping to channel " + channel); System.out.println(" Jumping to channel " + channel);
device.setChannel(channel); device.setChannel(channel);

View File

@@ -1,9 +1,8 @@
package bridge; package bridge;
/** /**
* Implementor interface — the "implementation" side of the bridge. * Implementor — the "implementation" side of the bridge.
* This is what the Abstraction delegates its real work to. * All devices (TV, Radio, SmartSpeaker, etc.) implement this.
* TV, Radio, SmartSpeaker etc. all implement this. * The remote controls only know about this interface, never about specific devices.
*/ */
public interface Device { public interface Device {
boolean isEnabled(); boolean isEnabled();

View File

@@ -1,29 +1,14 @@
package bridge; 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 class Main {
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("=== Bridge Design Pattern Demo ===\n"); System.out.println("=== Bridge Design Pattern Demo ===\n");
// Combination 1: Basic Remote + TV // Combination 1: Basic Remote + TV
System.out.println("-- Basic Remote controlling TV --"); System.out.println("-- Basic Remote controlling TV --");
RemoteControl remote1 = new RemoteControl(new TV()); RemoteControl remote1 = new RemoteControl(new TV());
remote1.togglePower(); remote1.togglePower();
remote1.volumeUp(); remote1.volumeUp();
remote1.channelUp(); remote1.channelUp();
System.out.println(); System.out.println();
// Combination 2: Advanced Remote + Radio // Combination 2: Advanced Remote + Radio
System.out.println("-- Advanced Remote controlling Radio --"); System.out.println("-- Advanced Remote controlling Radio --");
AdvancedRemote remote2 = new AdvancedRemote(new Radio()); AdvancedRemote remote2 = new AdvancedRemote(new Radio());
@@ -31,16 +16,13 @@ public class Main {
remote2.volumeUp(); remote2.volumeUp();
remote2.mute(); remote2.mute();
remote2.jumpToChannel(91); remote2.jumpToChannel(91);
System.out.println(); 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 --"); System.out.println("-- Advanced Remote controlling TV --");
AdvancedRemote remote3 = new AdvancedRemote(new TV()); AdvancedRemote remote3 = new AdvancedRemote(new TV());
remote3.togglePower(); remote3.togglePower();
remote3.jumpToChannel(5); remote3.jumpToChannel(5);
remote3.mute(); remote3.mute();
System.out.println("\n=== Demo complete ==="); System.out.println("\n=== Demo complete ===");
System.out.println("3 different remote+device combinations, 0 new classes needed."); System.out.println("3 different remote+device combinations, 0 new classes needed.");
} }

View File

@@ -10,21 +10,23 @@ Decouples remote controls (Abstraction) from devices (Implementation). A basic r
## How to run ## How to run
```bash ```bash
javac bridge/*.java javac bridge/*.java -d out/bridge
java bridge.Main 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 | | Step 1 — The Implementor Interface | `Device.java` |
| `TV.java` / `Radio.java` | Concrete Implementors | | Step 2 — Concrete Implementors (TV and Radio) | `TV.java`, `Radio.java` |
| `RemoteControl.java` | Abstraction (holds Device bridge) | | Step 3 — The Abstraction (RemoteControl) | `RemoteControl.java` |
| `AdvancedRemote.java` | Refined Abstraction | | Step 4 — Refined Abstraction (AdvancedRemote) | `AdvancedRemote.java` |
| `Main.java` | Demo entry point | | 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/ Article: https://ankurm.com/bridge-design-pattern-java/
All patterns: https://ankurm.com/design-patterns-java/ All patterns: https://ankurm.com/design-patterns-java/

View File

@@ -1,28 +1,17 @@
package bridge; package bridge;
// Concrete Implementor #2: Radio
/**
* Concrete Implementor — a radio.
* Same Device interface, completely different internal behaviour.
*/
public class Radio implements Device { public class Radio implements Device {
private boolean on = false; private boolean on = false;
private int volume = 20; private int volume = 20;
private int channel = 1; // FM frequency index simplified private int channel = 1;
@Override public boolean isEnabled() { return on; } @Override public boolean isEnabled() { return on; }
@Override public void enable() { on = true; System.out.println(" [Radio] Powered 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 void disable() { on = false; System.out.println(" [Radio] Powered OFF"); }
@Override public int getVolume() { return volume; }
@Override @Override public void setVolume(int percent) {
public int getVolume() { return volume; }
@Override
public void setVolume(int percent) {
this.volume = Math.max(0, Math.min(100, percent)); this.volume = Math.max(0, Math.min(100, percent));
System.out.println(" [Radio] Volume set to " + this.volume); System.out.println(" [Radio] Volume set to " + this.volume);
} }
@Override public int getChannel() { return channel; } @Override public int getChannel() { return channel; }
@Override public void setChannel(int ch) { this.channel = ch; System.out.println(" [Radio] Frequency -> " + ch); } @Override public void setChannel(int ch) { this.channel = ch; System.out.println(" [Radio] Frequency -> " + ch); }
@Override public String getName() { return "JBL Radio"; } @Override public String getName() { return "JBL Radio"; }

View File

@@ -1,22 +1,18 @@
package bridge; package bridge;
/** /**
* Abstraction — the remote control. It holds a reference to a Device * Abstraction — the remote control.
* (the "bridge") and delegates all real work to it.
* *
* The key: RemoteControl doesn't care whether it talks to a TV or Radio. * Key point: RemoteControl holds a Device (the bridge) and delegates
* It holds a Device and calls Device methods. That's the bridge. * all actual work to it. It adds higher-level semantics on top:
* "togglePower" instead of separate enable()/disable() calls.
*/ */
public class RemoteControl { public class RemoteControl {
protected Device device; // THE BRIDGE
// The bridge — link from Abstraction to Implementation
protected Device device;
public RemoteControl(Device device) { public RemoteControl(Device device) {
this.device = device; this.device = device;
System.out.println("Remote paired with: " + device.getName()); System.out.println("Remote paired with: " + device.getName());
} }
// User action → device operation translation
public void togglePower() { public void togglePower() {
if (device.isEnabled()) { if (device.isEnabled()) {
device.disable(); device.disable();
@@ -24,10 +20,8 @@ public class RemoteControl {
device.enable(); device.enable();
} }
} }
public void volumeUp() { device.setVolume(device.getVolume() + 10); } public void volumeUp() { device.setVolume(device.getVolume() + 10); }
public void volumeDown() { device.setVolume(device.getVolume() - 10); } public void volumeDown() { device.setVolume(device.getVolume() - 10); }
public void channelUp() { device.setChannel(device.getChannel() + 1); } public void channelUp() { device.setChannel(device.getChannel() + 1); }
public void channelDown() { device.setChannel(device.getChannel() - 1); } public void channelDown() { device.setChannel(device.getChannel() - 1); }
} }

View File

@@ -1,28 +1,17 @@
package bridge; package bridge;
// Concrete Implementor #1: Television
/**
* Concrete Implementor — a television.
* Contains device-specific logic for a TV.
*/
public class TV implements Device { public class TV implements Device {
private boolean on = false; private boolean on = false;
private int volume = 30; private int volume = 30;
private int channel = 1; private int channel = 1;
@Override public boolean isEnabled() { return on; } @Override public boolean isEnabled() { return on; }
@Override public void enable() { on = true; System.out.println(" [TV] Powered 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 void disable() { on = false; System.out.println(" [TV] Powered OFF"); }
@Override public int getVolume() { return volume; }
@Override @Override public void setVolume(int percent) {
public int getVolume() { return volume; }
@Override
public void setVolume(int percent) {
this.volume = Math.max(0, Math.min(100, percent)); this.volume = Math.max(0, Math.min(100, percent));
System.out.println(" [TV] Volume set to " + this.volume); System.out.println(" [TV] Volume set to " + this.volume);
} }
@Override public int getChannel() { return channel; } @Override public int getChannel() { return channel; }
@Override public void setChannel(int ch) { this.channel = ch; System.out.println(" [TV] Channel -> " + ch); } @Override public void setChannel(int ch) { this.channel = ch; System.out.println(" [TV] Channel -> " + ch); }
@Override public String getName() { return "Samsung TV"; } @Override public String getName() { return "Samsung TV"; }

View File

@@ -197,6 +197,24 @@ javac 02-structural/adapter/*.java -d out/adapter
java -cp out/adapter adapter.Main 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 ## Reference
- *Design Patterns: Elements of Reusable Object-Oriented Software* — Gamma, Helm, Johnson, Vlissides - *Design Patterns: Elements of Reusable Object-Oriented Software* — Gamma, Helm, Johnson, Vlissides