13. Bridge Pattern

2021. 11. 14. 22:14Computer Sciences/Design Patterns

문제

TV를 작동시키는 리모컨은 여러 제조사가 있다. 그래서 TV를 모든 리모컨으로 동작시키기 위해서는 리모컨을 인터페이스화 하고 TV를 컴포지션하여 사용할 수 있었다. 그런데 이젠 TV 제조사가 많아졌다. 기존에는 삼성이 모든 TV를 만들었지만 이젠 LG도 TV를 생산한다고 한다. 이를 어떻게 풀어야 할까?

해결 방안

이 문제를 해결하는 방법은 간단하다. 리모컨에서 한 것처럼 TV도 인터페이스화하고 리모컨에서는 TV 인터페이스를 컴포지션하면 된다. 클래스 다이어그램으로 나타내면 다음과 같다.

그리고 RemoteControl과 TV의 관계를 브릿지 관계라고 한다.

Java 코드로 구현하면 다음과 같다.

public class Client {
    public static void main(String[] args) {
        TVFactory tvFactory = new TVFactory();
        SpecialRemote remoteSamsung = new SpecialRemote(tvFactory);
        System.out.println("리모컨을 사용하기 전에 TV를 설정하세요.");
        remoteSamsung.setTV("Samsung");
        remoteSamsung.on();
        remoteSamsung.up();
        remoteSamsung.down();
        remoteSamsung.off();

        GenericRemote remoteLG = new GenericRemote(tvFactory);
        System.out.println("리모컨을 사용하기 전에 TV를 설정하세요.");
        remoteLG.setTV("LG");
        remoteLG.on();
        remoteLG.setNextChannel();
        remoteLG.setPrevChannel();
        remoteLG.off();
    }
}
public abstract class RemoteControl {
    TV tv;
    TVFactory tvFactory;
    public RemoteControl(TVFactory tvFactory) {
        this.tvFactory = tvFactory;
    }
    public void on() {
        this.tv.on();
    }
    public void off() {
        this.tv.off();
    }
    public void setChannel(int channel) {
        tv.tuneChannel(channel);
    }
    public int getChannel() {
        return tv.getChannel();
    }
    public void setTV(String type) {
        try {
            tv = tvFactory.getTV(type);
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}
public class GenericRemote extends RemoteControl {
    public GenericRemote(TVFactory tvFactory) {
        super(tvFactory);
    }
    public void setNextChannel() {
        int channel = this.getChannel();
        this.setChannel(channel+1);
    }
    public void setPrevChannel() {
        int channel = this.getChannel();
        this.setChannel(channel-1);
    }
}
public class SpecialRemote extends RemoteControl {
    public SpecialRemote(TVFactory tvFactory) {
        super(tvFactory);
    }
    public void up() {
        int channel = this.getChannel();
        this.setChannel(channel+1);
    }
    public void down() {
        int channel = this.getChannel();
        this.setChannel(channel-1);
    }
}
public abstract class TV {
    abstract void on();
    abstract void off();
    abstract void tuneChannel(int channel);
    abstract int getChannel(); 
}
public class LG extends TV {
    int station = 1;
    public void on() {
        System.out.println("Turning on the LG TV");
    }
    public void off() {
        System.out.println("Turning off the LG TV");
    }
    public void tuneChannel(int station) {
        this.station = station;
        System.out.println("Set the LG TV station to " + this.station);
    }
    public int getChannel() {
        return station;
    }
}
public class Samsung extends TV {
    int channel = 0;
    public void on() {
        System.out.println("Turning on the Samsung TV");
    }
    public void off() {
        System.out.println("Turning off the Samsung TV");
    }
    public void tuneChannel(int channel) {
        this.channel = channel;
        System.out.println("Set the Samsung TV Channel to " + this.channel);
    }
    public int getChannel() {
        return channel;
    }
}
public class TVFactory {
    public TV getTV(String type) throws Exception {
        if (type.equals("LG")) {
            return new LG();
        } else if (type.equals("Samsung")) {
            return new Samsung();
        } else {
            throw new Exception("Invalid TV Type");
        }
    }
}

장단점

장점

  • 구상 클래스와 인터페이스를 완전히 결합하지 않았기 때문에 구현과 추상화된 부분을 분리시킬 수 있다.
  • 추상화된 부분과 실제 구현 부분을 독립적으로 확장할 수 있다.
  • 추상화된 부분을 구현한 구상 클래스를 바꿔도 클라이언트 측에는 영향을 끼치지 않는다.

단점

  • 디자인이 복잡해진다.

활용법

  • 여러 플랫폼에서 사용해야 할 그래픽스 및 윈도우 처리 시스템에서 유용하게 사용된다.
  • 인터페이스와 실제 구현부를 서로 다른 방식으로 변경해야 하는 경우에 유용하게 사용된다.

'Computer Sciences > Design Patterns' 카테고리의 다른 글

Prototype Pattern  (0) 2021.12.11
14. Chain of Responsibility Pattern  (0) 2021.11.14
12. State Pattern  (0) 2021.10.15
11. Composite Pattern  (0) 2021.10.15
10. Iterator Pattern  (0) 2021.10.15