Sync Bridge to Java 25: H6 file labels, README mapping
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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/
|
||||||
|
|||||||
@@ -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"; }
|
||||||
|
|||||||
@@ -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); }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"; }
|
||||||
|
|||||||
18
README.md
18
README.md
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user