Bridge Pattern
태그 :
- 개념
- - 구현 뿐만 아니라 추상화된 부분가지 변경시켜야 하는 경우 사용
I. 의도
구현과 추상화 개념을 분리하는 것
정의 : 기능의 클래스 계층과 구현의 클래스 계층을 분리하는 패턴
: 구현 뿐만 아니라 추상화된 부분가지 변경시켜야 하는 경우 사용
II. 활용
- 추상화 개념과 이에 대한 구현간의 종속성을 없애고 싶거나, 또는 런타임시 구현 방법을 선택하거나 구현 내용을 변경하고 싶을 경우
- 추상화 개념과 구현 모두가 독립적으로 상속에 의해 확장 가능할 경우
- 추상화 개념에 대한 구현 내용을 변경하는 것은 다른 관련 프로그램에 아무 영향 없다. 추상화 개념에 해당하는 클래스를 사용하는 코드들은 구현 클래스가 변경되었다고 해서 다시 컴파일될 필요 없다
- 클라이언트로 부터 구현을 은닉하길 원할 때
- 클래스 계층도에서 클래스 수가 급증하는 것을 방지하고자 할 때
- 여러 객체들에 걸쳐 구현을 공유할 때 또는 이런 사실을 다른 코드에 공개하고 싶지 않을 때
III. 결과
- 인터페이스와 구현의 결합도 약화
- 확장성 제고 – abstraction과 implementor를 독립적으로 확장
- 구현 사항 은닉
관련 패턴: Abstract Factory 패턴을 이용해서 특정 Bridge를 생성하고 합성할 수 있도록 한다.
Adapter 패턴을 이용해서 서로 관련없는 클래스들을 연결할 수도 있다. 이는 이미 설계가 끝난 클래스와 통합을 해야 하는 경우에 필요하다.
참여객체 |
역할 |
Abstraction |
-기능 클래스 계층의 최상위에 있는 클래스 -Implementor 의 메소드를 사용해서 기본적인 기능만을 제공하는 클래스 -예제 : Display 클래스가 해당됨 |
RefinedAbstraction |
-Abstraction에 기능을 추가(확장)역할 -예제 : CountDisplay 클래스가 해당됨 |
Implementor |
-구현 클래스 계층의 최상위에 있는 클래스 -Abstraction 역할의 인터페이스를 구현하기 위한 메소드를 규정하는 역할 -예제 : DisplayImpl 클래스가 해당됨 |
ConcreteImplementor |
-Implementor 역할의 인터페이스를 구체적으로 구현하는 역할 -예제 : WinImpl, MacImpl클래스가 해당됨 |
<예제> Bridge Pattern 코드
가. Class Diagram
나. Abstraction
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();
}
}
다. RefinedAbstaction
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();
}
}
라. Implementor
public interface DisplayImpl {
void rawOpen();
void rawPrint();
void rawClose();
}
마. Concrete Implementor
public class StringDisplayImpl implements DisplayImpl {
private String str;
private int width;
public StringDisplayImpl(String str) {
this.str = str;
this.width = str.getBytes().length;
}
@Override
public void rawOpen() {
printLine();
}
@Override
public void rawPrint() {
System.out.println("|" + str + "|");
}
@Override
public void rawClose() {
printLine();
}
private void printLine() {
System.out.print("+");
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, World."));
CountDisplay d3 = new CountDisplay(new StringDisplayImpl("Hellow, Universe."));
d1.display();
d2.display();
d3.display();
d3.multiDisplay(5);
}
}