2011년 5월 23일 월요일

The Bridge Pattern

7. The Bridge Pattern
하나의 클래스가 한 종류의 인터페이스를 다른 종류의 인터페이스로 변환하기 위해 사용되었기 때문에 Adapter패턴과 매우 닮았다고 생각하기 쉽다. 그러나 Adapter 패턴은 한 개 이상의 클래스 인터페이스를 특정 클래스의 인터페이스와 동일하게 간주하기 위해 의도된 것이다. 이와 반대로 Bridge 패턴은 개발자가 클라이언트의 코드 내용을 변경하지 않고도 구현 내용을 바꾸거나 대체할 수 있도록 클래스의 인터페이스와 구현 내용을 분리시킨 것이다.
Bridge 패턴을 구성하는 요소는 다음과 같다.
v 클래스의 인터페이스를 정의하는 추상화(Abstraction)
v 해당 인터페이스를 상속하고 구현하는 정제된 추상화(Refined Abstraction)
v 구현 클래스에 대한 인터페이스를 정의하는 구현자(Implementor)
v 구현 클래스인 ConcreteImplementor
구조
*


역할
v Abstraction의 역할
‘기능의 클래스 계층’의 최상위에 있는 클래스입니다. Implementor 역할의 메소드를 사용해서 기본적인 기능만 기술되어 있는 클래스 입니다. 이 인스턴스는 Implementor 역할을 가지고 있습니다.
v RefindedAbstraction의 역할
Abstraction 역할에다 기능을 추가한 역할입니다.
v Implementor의 역할
‘구현의 클래스 계층’의 최상위에 있는 클래스입니다. Abstractor 역할의 인터페이스(API)를 구현하기 위한 메소드를 규정하는 역할입니다.
v ConcreteImplementor의 역할
Implementor 역할의 인터페이스(API)를 구체적으로 구현하는 역할입니다.
의도
‘기능의 클래스 계층’과 ‘구현의 클래스 계층’을 분리하는 것. 두 개로 클래스 계층을 나눠두면 각각의 클래스 계층을 독립적으로 확장할 수 있다.
적용시기
Bridge 패턴을 사용하면, 다음과 같은 장점이 있습니다.
  • Bridge 패턴은 해당 인터페이스를 클라이언트의 프로그램에서 일정하게 유지하기 위해 의도되는 패턴으로, 개발자가 출력하거나 사용하는 실제 클래스를 변경할 수 있게 한다. 이것은 개발자가 사용자 인터페이스 모듈의 어려운 부분을 다시 컴파일해야 할 수고를 덜어주고, Bridge 패턴 자체와 실제 최종 출력 클래스 부분만 다시 컴파일하면 된다.
  • 개발자는 클래스의 구현 내용과Bridge클래스를 각각 별도로 상속할 수 있으며, 일반적으로 서로 지나치게 상호 작용할 필요가 없다.
  • 클라이언트 프로그램으로부터 구현 내용을 훨씬 쉽게 감출 수 있다.

예제소스
*


예제 소스
l 구현 계층 소스
public abstract class DisplayImpl {
public abstract void rawOpen();
public abstract void rawPrint();
public abstract void rawClose();
}
public class HtmlDisplayImpl extends DisplayImpl {
private String string;
private StringBuffer buffer = new StringBuffer();
public HtmlDisplayImpl(String string) {
this.string = string;
}
public void rawOpen() {
buffer.append("<table>\n");
}
public void rawPrint() {
buffer.append("<tr><td>"+string+"</td></tr>\n");
}
public void rawClose() {
buffer.append("</table>\n");
System.out.println(buffer.toString());
}
}
public class StringDisplayImpl extends DisplayImpl {
private String string;
private int width;
public StringDisplayImpl(String string) {
this.string = string;
this.width = string.getBytes().length;
}
public void rawOpen() {
printLine();
}
public void rawPrint() {
System.out.println("|" + string + "|");
}
public void rawClose() {
printLine();
}
private void printLine() {
System.out.print("+");
for (int i = 0; i < width; i++) {
System.out.print("-");
}
System.out.println("+");
}
}


l 기능 계층 소스
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();
}
/**
* Template Method
*/
public final void display() {
open();
print();
close();
}
}
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();
}
}
public class mainClass {
public static void main(String[] args) {
Display stringDisplay = new Display(new StringDisplayImpl("Hello, hurukku."));
Display htmlDisplay = new Display(new HtmlDisplayImpl("Hello, hurukku."));
CountDisplay countStringDisplay = new CountDisplay(new StringDisplayImpl("Hello, hurukku."));
CountDisplay countHtmlDisplay = new CountDisplay(new HtmlDisplayImpl("Hello, hurukku."));
stringDisplay.display();
htmlDisplay.display();
countStringDisplay.multiDisplay(5);
countHtmlDisplay.multiDisplay(5);
}
}


관련패턴
  • Template Method : Template Method 패턴에서는 구현 클래스 계층을 이용합니다. 상위 클래스에서는 추상 메소드를 사용해서 프로그래밍을 실행하고 하위 클래스에서는 그 추상 메소드를 구현 합니다.
  • Abstract Factory : Bridge 패턴에 등장하는 ConcreteImplementor 역할을 환경에 맞춰서 적절히 구축하기 위해 Abstract Factory 패턴이 이용되는 경우가 있습니다.
  • Adapter : Bridge 패턴은 기능의 클래스 계층과 구현의 클래스 계층을 확실히 분리한 다음에 연결시키는 패턴입니다. Adapter 패턴도 기능은 비슷하지만 인터페이스(API)가 다른 클래스를 결합시키는 패턴입니다.

댓글 없음:

댓글 쓰기

ETL 솔루션 환경

ETL 솔루션 환경 하둡은 대용량 데이터를 값싸고 빠르게 분석할 수 있는 길을 만들어줬다. 통계분석 엔진인 “R”역시 하둡 못지 않게 관심을 받고 있다. 빅데이터 역시 데이터라는 점을 볼때 분산처리와 분석 그 이전에 데이터 품질 등 데이...