-
[구조 패턴] BridgeCS/디자인패턴 2021. 6. 3. 17:55
해당 게시글은 "JAVA DESIGN PATTERNS - REUSABLE SOLUTIONS TO COMMON PROBLEMS"의 내용을 기반으로 정리한 것입니다.
1. Bridge(브리지) 패턴
Bridge 패턴은
To Decouple an Abstaction from its Implementation
(추상과 구상의 분리)라는 목적이 있는 패턴입니다.
객체지향 프로그래밍에서 여러 클래스에서 공통적인 속성 혹은 메서드의 제공을 위한 방법으로 상속을 사용하곤 합니다. 이때, 상속을 두 가지 관점에서 바라볼 수 있습니다.
- 구현 관점: 부모 클래스에서 정의한 기능을 자식 클래스에 맞게 재정의(재구현)
- 기능 관점: 자식 클래스에서 사용할 메소드를 추가
이러한 관점에서 클래스를 상속받는 것은 해당 클래스를 상속받은 다른 클래스들과 다음 세 가지 관계에 있다는 의미가 됩니다.
- 같은 구현, 다른 기능
- 다른 구현, 같은 기능
- 다른 구현, 다른 기능
결국, 한 클래스로부터 파생되는 클래스에 N개의 다른 구현이 있고 M개의 다른 기능이 존재한다고 할 때, N x M개의 클래스를 작성하고 관리해야 한다는 의미가 됩니다.
이를 Bridge 패턴을 사용하면 N + M개의 클래스만으로 N x M개의 클래스를 만든 것 같은 효과를 얻을 수 있습니다.
2. Structure
Structure of Bridge Pattern - Abstraction: 구현을 담당하는 클래스의 인터페이스
- RefinedAbstaction: Abstraction을 구현한 구현체
- Implementor: 기능을 담당하는 클래스의 인터페이스
- ConcreteImplementor: Implementor을 구현한 구현체
브리지 패턴 구조의 핵심은 Abstraction과 Implementor 사이의 관계에 있습니다. 단순하게 이해하면, Abstraction이 속성으로 Implementor을 갖고 있다는 것입니다. 즉, RefinedAbstraction에 어떤 ConcreteImplementor를 제공하느냐에 따라 RefinedAbstraction의 동작이 달라지게 된다는 것입니다.
3. 예제
브리지 관계에 집중하기 위해서 위의 구조를 조금 더 간략화 시켜 다음과 같은 구조의 예제를 작성해 볼 수 있다.
리모컨 객체를 만드는 예제이다. 리모컨에서 기능은 각 장치를 컨트롤 하는 것이다. 우선 각 장치의 기능을 먼저 정의해보자.
장치들은 공통적으로 전원을 켜고 끄는 기능과 조작과 관련된 기능이 있기에 다음과 같이 인터페이스를 만들고 이를 구현하는 TV와 Radio 클래스를 만들어 볼 수 있습니다.
public interface Device { public boolean isEnable(); public void enable(); public void disable(); public void control(); }
public class TV implements Device { prviate boolean isEnable; public TV() { this.isEnable = false; } @Override public boolean isEnable() { return this.isEnable; } @Override public void enable() { this.isEnable = true; } @Override public void disable() { this.isEnable = false; } @Override public void control() { if (this.isEnable) { System.out.print("TV Control"); } } }
public class Radio implements Device { public boolean isEnable; public Radio() { this.isEnable = false; } @Override public boolean isEnable() { return this.isEnable; } @Override public void enable() { this.isEnable = true; } @Override public void disable() { this.isEnable = false; } @Override public void control() { if (this.isEnable) { System.out.print("Radio Control"); } } }
위에서 정의한 장치들을 사용하는 구현 클래스인 Remote를 아래와 같이 만들 수 있습니다. Remote가 Device객체를 갖는 것으로 구현과 기능 사이의 다리를 놓았습니다.
public class Remote { Device device; public Remote(Device device) { this.device = device; } public void powerToggle() { if (this.device.isEnable()) { this.device.disable(); } else { this.device.Enable(); } } public void control() { this.device.control(); } }
Remote를 사용하는 관점에서 다음과 같은 코드를 통해 TV 리모컨과 Radio 리모컨을 사용할 수 있습니다.
Remote tvRemote = new Remote(new TV()); tvRemote.powerToggle(); tvRemote.control(); Remote radioRemote = new Remote(new Radio()); radioRemote.powerToggle(); radioRemote.control();
References
- Rohit Joshi. 2015. "Java Design Pattern". Java Code Geek (https://www.javacodegeeks.com/2015/09/bridge-design-pattern.html#what_is_bridge_pattern)
- https://refactoring.guru/design-patterns/bridge. accessed 2021.06.03
'CS > 디자인패턴' 카테고리의 다른 글
[구조 패턴] Adapter (0) 2021.05.26 [생성 패턴] Singleton (0) 2021.05.25 [생성 패턴] Builder (0) 2021.05.21 [생성 패턴] Prototype (0) 2021.05.20 [생성 패턴] Abstract Factory Method (0) 2021.05.19