Develope/Programming

[GOF 디자인패턴] Bridge Pattern

고로이 2019. 2. 13. 11:40
반응형

*본 포스팅은 SLiPP 스터디를 진행하면서 위키 작성을 위해 작성하였습니다. SLiPP 충성충성~^^7 

1.개념

  • 구현부와 추상층을 분리한 구조적(Structure) 디자인 패턴 

핵심 키워드: 구현부,추상층 분리



2. 구조


  • Abstraction   (BusinessObject)
    • 추상화된 인터페이스를 정의한다.
    • Implementor 객체에 대한 참조를 유지 관리한다.

  • RefinedAbstraction   (CustomersBusinessObject)
    • 추상화에 의해 정의 된 인터페이스를 확장한다.


  • Implementor   (DataObject)
    • 구현 클래스의 인터페이스를 정의한다. 이 인터페이스는 Abstraction의 인터페이스와 일치 할 필요는 없다.  
    • 일반적으로 구현 인터페이스는 Primitive 연산만을 제공하며, 추상화는 이러한 Primitive가 기반인 상위 수준 연산을 정의한다.
    • 구현 클래스의 인터페이스

  • ConcreteImplementor   (CustomersDataObject)
    • Implementor의 인터페이스를 구현하고 구체적인 구현을 정의한다. 
    • Implementor를 구현하는 구상 서브 클래스


3. 사용

When?  

  • 구현의  run-time 바인딩을 원할 때 (??)

  • 결합 된 인터페이스와 많은 구현들로, 클래스의 확산이 이루어질 때 

  • 여러 객체간에 구현을 공유하려는 경우

  • 구현뿐만 아니라 추상화된 부분까지 변경시켜야 하는 경우 (RefinedAbstraction)


Problem?

Shape 클래스가 있다고 할 때,

모양 이라는 속성에 해당하는 Circle 과 Rectangle  클래스를 하위클래스로 가진다.

이 때 Color라는 개념으로 클래스를 확장할 때, Color에 해당하는 클래스 (RedBlue)를 하위클래스로 생성해야 한다.


예를 들어 삼각형 모양을 추가하려면 각 색상에 하나씩 두 개의 하위 클래스를 추가해야한다. 

그 후에 새로운 색상을 추가하려면, 각 모양에 하나씩 3개의 하위 클래스를 추가적으로 만들어야 한다. 


지금은 4건 이지만, 클래스 계층 구조에 새로운 모양 유형 및 색상을 추가하면 이 수는 기하 급수적으로 커진다.


이러한 문제는 클래스 상속과 관련해서는 매우 일반적인 문제로,

모양과 색상 두 가지 독립적인 차원에서 Shape 클래스를 확장하려고 하기 때문에 발생한다.


The Bridge pattern attempts to solve this problem by switching from inheritance to composition.

브릿지 패턴은 이러한 문제를 상속에서 구성(composition)으로 전환하여 해결한다.



즉, 속성 중 하나를 별도의 클래스 계층 구조로 추출하여

한 클래스 내에 모든 상태 및 동작을 가지는 대신, 새 속성 계층 구조의 객체를 참조하게한다.


Adventages?

장점

  • 구현을 인터페이스에 완전히 결합시키지 않았기 때문에 구현과 추상화된 부분을 분리시킬 수 있다.
  • 추상화된 부분과 실제 구현 부분을 독립적으로 확장 할 수 있다.
  • 추상화된 부분을 구현한 구상 클래스를 바꿔도 클라이언트 쪽에는 영향을 끼치지 않는다.
  • 코드의 단위 테스트
    • Bridge 패턴은 독립적인 테스트가 용이
    • Bridge 패턴을 사용하지 않는다면, 구현 클래스를 테스트 하기 위해 슈퍼클래스가 필요
    • 구현 클래스의 모의 객체를 만들어, 추상 클래스를 테스트

사용 및 단점

  • 여러 플랫폼에서 사용해야 할 그래픽스 및 윈도우 처리 시스템에서 유용하게 쓰인다.
  • 인터페이스와 실제 구현부를 서로 다른 방식으로 변경해야 하는 경우에 유용하게 쓰인다.
  • 디자인이 복잡해진다는 단점이 있다.

(헤드퍼스트 디자인패턴)



4. EXAMPLE

  •  위의 Shape


  •  Remote Controller

Device와 원격 제어(Remote)를 관리하는 앱의 코드를 분리
Device 클래스가 구현, Remote 추상화로서 작용한다

  • Morse (feat. 인프런)


GofBridge.java 원본 펼치기
PrintMorseCode.java 원본 펼치기
MorseCodeFunction.java 원본 펼치기
Morse.java 원본 펼치기
SoundMFC.java 원본 펼치기
DefaultMFC.java 원본 펼치기



5. 기타

  • Bridge Pattern, Adapter Pattern
    : 매우 흡사한 모습을 보인다
    • 개념의 차이
      Adapter : 호환되지 않는 두 개의 인터페이스가 함께 작동
      Bridge : 두 개의 별토 클래스로 추상화와 구현을 분리

    • GOF “Adapter makes things work after they’re designed; Bridge makes them work before they are.“.
      => Adapter : 설계된 후에 작동한다.?
      => Bridge : 설계되기 전에 작동한다.


반응형