'JAVA 언어로 배우는 디자인 패턴 입문'의 내용을 정리한 것입니다.
Bridge 패턴
- Bridge 패턴은 두 장소를 연결하는 역할을 한다.
- 다리 역할을 하는 장소는 '기능의 클래스 계층'과 '구현의 클래스 계층'이다.
클래스 계층의 두 가지 역할
새로운 '기능'을 추가하고 싶을 때는...
Something 클래스에 새로운 기능을 추가하고 싶을 때는 하위 클래스(자식 클래스, 파생 클래스, 확장 클래스)로 SomethingGood 클래스를 만든다.
Something
⎿ SomethingGood
- 상위 클래스는 기본적인 기능을 가지고 있다.
- 하위 클래스는 새로운 기능을 추가한다.
이 클래스 계층을 '기능의 클래스 계층'이라고 부른다.
SomethingGood에 새로운 기능을 추가한다고 하자. 이 경우 SomethingGood의 하위 클래스로 SomethingBetter 클래스로 만든다.
Something
⎿ SomethingGood
⎿ SomethingBetter
새로운 '구현'을 추가하고 싶을 때는...
Template Method 패턴과 같이 상위 클래스는 추상 메소드로 인터페이스를 규정하고 하위 클래스에서 추상 메소드를 구현하는 역할을 한다.
AbstractClass
⎿ ConcreteClass
이 클래스 계층을 '구현의 클래스 계층'이라고 부른다.
또 다른 구현을 만들면 AnotherConcreteClass라고 하면 또 변화된다.
AbstractClass
⎿ ConcreteClass
⎿ AnotherConcreteClass
클래스 계층의 혼재와 클래스 계층의 분리
하위 클래스를 만들고자 할 때는 자신의 의도를 확인해야 한다.
- 나는 기능을 추가하려고 하는가? 아니면 구현하려고 하는가?
그래서 '기능의 클래스 계층'과 '구현의 클래스 계층'을 두 개의 독립된 클래스 계층으로 나눈다. 두 클래스 계층 사이에 다리를 놓을 필요가 있다.
예제 프로그램
기능의 클래스 계층: Display 클래스
public class Display {
private DisplayImpl impl;
public Display(DisplayImpl impl) {
this.impl = impl;
}
public void open() {
impl.rawOpen();
}
public void print() {
impl.rawPrint();
}
public void close() {
impl.rawClose();
}
public final void display() {
open();
print();
close();
}
}
기능의 클래스 계층: CountDisplay 클래스
public class CountDisplay extends Display {
public CountDisplay(DisplayImpl impl) {
super(impl);
}
public void multiDisplay(int times) {
open();
for (int i=0; i<times; i++) {
print();
}
close();
}
}
구현의 클래스 계층: DisplayImpl 클래스
public abstract class DisplayImpl {
public abstract void rawOpen();
public abstract void rawPrint();
public abstract void rawClose();
}
구현의 클래스 계층: StringDisplayImpl 클래스
public class StringDisplayImpl extends DisplayImpl {
private String string;
private int width;
public StringDisplayImpl(String string) {
this.string = string;
this.width = string.length();
}
@Override
public void rawOpen() {
printLine();
}
@Override
public void rawPrint() {
System.out.println("|" + string + "|");
}
@Override
public void rawClose() {
printLine();
}
private void printLine() {
System.out.println("+");
for (int i=0; i<width; i++) {
System.out.print("-");
}
System.out.println("+");
}
}
Main 클래스
public class Main {
public static void main(String[] args) {
Display d1 = new Display(new StringDisplayImpl("Hello, Korea"));
Display d2 = new CountDisplay(new StringDisplayImpl("Hello, Korea"));
CountDisplay d3 = new CountDisplay(new StringDisplayImpl("Hello, Universe"));
d1.display();
d2.display();
d3.display();
d3.multiDisplay(5);
}
}
실행 결과
+------------+
|Hello, Korea|
+------------+
+------------+
|Hello, Korea|
+------------+
+---------------+
|Hello, Universe|
+---------------+
+---------------+
|Hello, Universe|
|Hello, Universe|
|Hello, Universe|
|Hello, Universe|
|Hello, Universe|
+---------------+
Abstraction(추상화) 역
- '기능의 클래스 계층'의 최상위 클래스
- Display 클래스가 이 역할
RefinedAbstraction(개선된 추상화) 역
- Abstraction 역에 기능을 추가
- CountDisplay 클래스가 이 역할
Implementor(구현자) 역
- '구현의 클래스 계층'의 최상위 클래스
- DisplayImpl 클래스가 이 역할
ConcreteImplementor(구체적인 구현자) 역
- Implementor 역의 인터페이스를 구현
- StringDisplayImpl 클래스가 이 역할
정리
- Bridge 패턴의 특징은 기능과 구현의 계층을 분리하는 것이다.
- 기능은 기능 클래스에 추가하면 된다.
- 위임을 통해 약한 결합을 사용한다.
반응형