Search code examples
design-patternsbridge

About the Bridge pattern again


I'm trying to understand the Bridge pattern. With examples from Wiki all is ok. But what if we have the next design:

enter image description here

How can I implement different remote controls (e.g. Infra-red and Wi-Fi)? Should I use Bridge pattern and how to do it? By analogy with an examples I need to combine all methods to the single wide interface with hardware implementation like on the next figure. But I don't think it's a good idea.

enter image description here


Solution

  • The bridge pattern is a lot like the adapter pattern.

    Following your model, let's suppose you have an RemoteControl abstract class:

    public abstract class RemoteControl
    {
          protected HadwareRemoteControl hardwareBridge;
    
          //Can be injected using DI
          public RemoteControl(HadwareRemoteControl hardwareBridge)
          {
               this.hardwareBridge= hardwareBridge;
          }
    
          public void on()
          {
               hardwareBridge.on();
          }
    
          public void off()
          {
               hardwareBridge.off();
          }
    }
    

    And two implementations for that class:

    public class TVRemoteControl extends RemoteControl
    {
          public TVRemoteControl(TVHardwareRemoteControl hardwareBridge) {
               super(hardwareBridge);
          }
    
          public void nextChannel() {
               ((TVHardwareRemoteControl)hardwareBridge).nextChannel();
          }
    
          public void previousChannel() {
               ((TVHardwareRemoteControl)hardwareBridge).previousChannel();
          }
    }
    
    public class ModelRemoteControl extends RemoteControl
    {
          public ModelRemoteControl (ModelHardwareRemoteControl hardwareBridge) {
               super(hardwareBridge);
          }
    
          public void moveForward() {
               ((ModelHardwareRemoteControl)hardwareBridge).moveForward();
          }
    
          public void moveBack() {
               ((ModelHardwareRemoteControl)hardwareBridge).moveBack();
          }     
    }
    

    Now, for the hardware bridge, we have a base interface:

    public interface HadwareRemoteControl
    {
          public void on();
          public void off();
    }
    

    And two more interfaces:

    public interface TVHadwareRemoteControl extends HardwareRemoteControl
    {
          public void nextChannel();
          public void previousChannel();
    }
    
    public interface ModelHardwareRemoteControl extends HardwareRemoteControl
    {
          public void moveForward();
          public void moveBack();
    }
    

    And, as in your desing, two implementations:

    public class InfraredRemoteControl implements TVHardwareRemoteControl, ModelHardwareRemoteControl
    {
          public void on()
          {
             //Hardware Turn on
          }
    
          public void off()
          {
             //Hardware Turn off
          }
    
          public void nextChannel()
          {
             //Hardware Next channel
          }
    
          public void previousChannel()
          {
             //Hardware Previous channel
          }
    
          public void moveForward()
          {
             //Hardware Move Forward
          }
    
          public void moveBack()
          {
             //Hardware Move Back
          }
    }
    
    
    public class WifiRemoteControl implements TVHardwareRemoteControl, ModelHardwareRemoteControl
    {
          public void on()
          {
             //Hardware Turn on
          }
    
          public void off()
          {
             //Hardware Turn off
          }
    
          public void nextChannel()
          {
             //Hardware Next channel
          }
    
          public void previousChannel()
          {
             //Hardware Previous channel
          }
    
          public void moveForward()
          {
             //Hardware Move Forward
          }
    
          public void moveBack()
          {
             //Hardware Move Back
          }
    }
    

    From an external project, a client of your API may use the hardware more transparently, not even aware of these implementations:

    TVRemoteControl tvRemote = Factory.CreateTVRemote();
    
    //Depending on the injected hardware implementation, it may call InfraredRemoteControl or WifiRemoteControl
    tvRemote.on();
    tvRemote.nextChannel();