도서 요약 / / 2023. 1. 15. 21:13

[JAVA 언어로 배우는 디자인 패턴 입문] Bridge 패턴

'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 패턴의 특징은 기능과 구현의 계층을 분리하는 것이다.
  • 기능은 기능 클래스에 추가하면 된다.
  • 위임을 통해 약한 결합을 사용한다.



반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유