Lee's Grow up

[디자인패턴/Design Pattern] Bridge Pattern / 브리지 패턴 본문

PROGRAMMING/디자인패턴

[디자인패턴/Design Pattern] Bridge Pattern / 브리지 패턴

효기로그 2019. 12. 26. 07:52
반응형

관련 내용은 [자바 언어로 배우는 디자인 패턴 입문],[Head First Design Pattern]의 내용을 참고해서 정리한 내용입니다. 잘못된 부분은 댓글로 피드백 부탁드립니다.

1. Bridge 패턴이란?


'기능 클래스 계층'과 '구현 클래스 계층'을 연결해주는 패턴입니다.

  • 기능 클래스 계층이란 ?
    • A라는 상위 클래스를 상속받는 B라는 하위 클래스에서 새로운 기능을 추가하는 계층을 말합니다.
  • 구현 클래스 계층이란 ?
    • A라는 인터페이스(API)를 구현한 B라는 객체가 존재할 때 구현 클래스 계층이라고 말합니다.

2. Bridge 패턴의 등장인물


  • Abstraction(추상화)의 역할
    1. 기능 클래스 계층의 상위 클래스입니다. 기본 기능만 정의되어 있습니다.
  • RefinedAbstaction(개선된 추상화)의 역할
    1. 기능 클래스 계층의 하위 클래스입니다. 기능을 추가한 역할입니다.
  • Implementor(구현자)의 역할
    1. 구현 클래스 계층의 상의 클래스입니다. 인터페이스(API)를 규정합니다.
  • Concrete Implementor(구체적인 구현자)의 역할
    1. 구현 클래스 계층의 하위 클래스입니다. 인터페이스를(API)를 정의합니다.
Bridge 패턴의 클래스 다이어그램

3. 예제


예제를 통해 내용을 구체화하겠습니다.

3-1. 예제 클래스 다이어그램

3-2. 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();
    }
}
3-3. 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();
    }
}
3-4. DisplayImpl 인터페이스

구현 클래스 계층의 최상위에 해당하며 구현할 메소드를 정의한 인터페이스(API)입니다.

public interface DisplayImpl {
    public void rawOpen();
    public void rawPrint();
    public void rawClose();
}
3-5. StringDisplayImpl 클래스

구현 클래스의 하위에 해당하며, 상위 인터페이스 또는 클래스의 메소드를 규현합니다.

public class StringDisplayImpl implements DisplayImpl {

    private String string;
    private int width;

    public StringDisplayImpl(String string) {
        this.string = string;
        this.width = string.getBytes().length;
    }

    @Override
    public void rawClose() {
        printLine();
    }

    @Override
    public void rawOpen() {
        printLine();
    }

    @Override
    public void rawPrint() {
        System.out.println("|" + string + "|");
    }

    private void printLine() {
        System.out.print("+");
        for (int i = 0; i < width; i++) {
            System.out.print("-");
        }
        System.out.println("+");
    }
}
3-6. Main 클래스
public class Main {
    public static void main(String[] args) {
        Display d1 = new Display(new StringDisplayImpl("Hello, Lee"));
        Display d2 = new CountDisplay(new StringDisplayImpl("Hello, world"));

        CountDisplay d3 = new CountDisplay(new StringDisplayImpl("Hello, Universe"));

        d1.display();
        d2.display();
        d3.display();
        d3.multiDisplay(5);
    }
}
실행 결과
+----------+
|Hello, Lee|
+----------+
+------------+
|Hello, world|
+------------+
+---------------+
|Hello, Universe|
+---------------+
+---------------+
|Hello, Universe|
|Hello, Universe|
|Hello, Universe|
|Hello, Universe|
|Hello, Universe|
+---------------+
그렇다면 왜 사용할까?
  • 두 계층을 분리함으로써 확장이 편리해집니다. 서로 변경이 되어도 클라이은트 쪽에는 영향이 없습니다.
  • 여러 플랫폼에서 사용해야 할 그래픽스 및 윈도우처리 시스템에서 유용하게 쓰입니다.

단 단점으로 패턴을 매우 응집력있는 클래스에 적용하면 코드가 더 복잡해질 수 있습니다.

4. 관련 패턴


  • Template Method 패턴 : 해당 패턴에서 구현의 클래스 계층을 이용합니다. link
  • Abstract Factory 패턴 : Bridge 패턴의 ConcreteImplementor 역할을 해당 패턴이 이용되는 경우가 있습니다. link
  • Adapter 패턴 : 해당 패턴은 Bridge와 비슷하지만, 인터페이스(API)가 다른 클래스를 결합시키는 패턴입니다. link

5. 비교하기


  • Adapter 패턴 : 서로 다른 인터페이스(API)를 연결해줍니다. link
  • Bridge 패턴 : 구현 계층과 기능(추상) 계층을 연결해줍니다. link

 

반응형
Comments