interface Device {
    boolean isEnabled();
    void enable();
    void disable();
    int getVolume();
    void setVolume(int percent);
}

class TV implements Device {
    private boolean on = false;
    private int volume = 30;

    public boolean isEnabled() { return on; }
    public void enable() { on = true; }
    public void disable() { on = false; }
    public int getVolume() { return volume; }
    public void setVolume(int percent) { volume = percent; }
}

class Radio implements Device {
    private boolean on = false;
    private int volume = 20;

    public boolean isEnabled() { return on; }
    public void enable() { on = true; }
    public void disable() { on = false; }
    public int getVolume() { return volume; }
    public void setVolume(int percent) { volume = percent; }
}

class Remote {
    protected Device device;
    Remote(Device device) { this.device = device; }

    void togglePower() {
        if (device.isEnabled()) device.disable();
        else device.enable();
    }

    void volumeDown() {
        device.setVolume(device.getVolume() - 10);
    }

    void volumeUp() {
        device.setVolume(device.getVolume() + 10);
    }
}

public static void main(String[] args) {
    TV tv = new TV();
    Remote remote = new Remote(tv);
    remote.togglePower();
    remote.volumeUp();
}
Back to Design Patterns
Structural Design Pattern

Bridge

The Bridge pattern decouples an abstraction from its implementation so that the two can vary independently. It uses composition over inheritance by separating the abstraction (the high-level control logic) from the implementation (the platform-specific details) into separate class hierarchies. This is useful when both the abstraction and the implementation may need to be extended independently.