본문 바로가기
스터디/디자인패턴

[design-pattern]디자인패턴 브릿지패턴의 이해와 의미

by zendyne 2023. 1. 1.

브리지는 큰 클래스 또는 밀접하게 관련된 클래스들의 집합을 두 개의 개별 계층구조​(추상화 및 구현)​로 나눈 후 각각 독립적으로 개발할 수 있도록 하는 구조 디자인 패턴입니다.

문제

? ? 어렵게 들리시나요? 진정하세요. 그리고 간단한 예시를 한번 살펴봅시다.

Circle​(원) 및 Square​(직사각형)​라는 한 쌍의 자식 클래스들이 있는 기하학적 Shape​(모양) 클래스가 있다고 가정해 봅시다. 이 클래스 계층 구조를 확장하여 색상을 도입하기 위해 Red​(빨간색) 및 Blue​(파란색) 모양들의 자식 클래스들을 만들 계획입니다. 그러나 이미 두 개의 자식 클래스가 있으므로 Blue­Circle​(파란색 원) 및 Red­Square​(빨간색 직사각형)​와 같은 네 가지의 클래스 조합을 만들어야 합니다.

 

새로운 모양 유형들과 색상 유형들을 추가할 때마다 계층 구조는 기하급수적으로 성장합니다. 예를 들어, 삼각형 모양을 추가하려면 각 색상별로 하나씩 두 개의 자식 클래스들을 도입해야 합니다. 그리고 그 후에 또 새 색상을 추가하려면 각 모양 유형별로 하나씩 세 개의 자식 클래스를 만들어야 합니다. 유형들이 많아지면 많아질수록 코드는 점점 복잡해집니다.

 해결책

이 문제는 모양과 색상의 두 가지 독립적인 차원에서 모양 클래스들을 확장하려고 하기 때문에 발생합니다. 이것은 클래스 상속과 관련된 매우 일반적인 문제입니다.

브리지 패턴은 상속에서 객체 합성으로 전환하여 이 문제를 해결하려고 시도합니다. 이것이 의미하는 바는 차원 중 하나를 별도의 클래스 계층구조로 추출하여 원래 클래스들이 한 클래스 내에서 모든 상태와 행동들을 갖는 대신 새 계층구조의 객체를 참조하도록 한다는 것입니다.

이 접근 방식을 따르면, 색상 관련 코드를 Red  Blue라는 두 개의 자식 클래스들이 있는 자체 클래스로 추출할 수 있습니다. 그런 다음 Shape 클래스는 색상 객체들 중 하나를 가리키는 참조 필드를 받습니다. 이제 모양은 연결된 색상 객체에 모든 색상 관련 작업을 위임할 수 있습니다. 이 참조는 Shape  Color 클래스들 사이의 브리지​(다리) 역할을 할 것입니다. 이제부터 새 색상들을 추가할 때 모양 계층구조를 변경할 필요가 없으며 그 반대의 경우도 마찬가지입니다.

추상화와 구현

GoF의 디자인 패턴 은 브리지 패턴 정의의 일부로   이라는 용어들을 소개합니다. 저는 위 용어들이 너무 학문적이라 그로 인해 패턴이 실제보다 더 복잡하게 들린다고 생각합니다. 그러면 GoF의 책의 난해한 용어들 뒤에 숨겨진 의미를 모양과 색상이 있는 간단한 예를 통해 해독해 보겠습니다.

(라고도 함)​는 일부 개체​(entity)​에 대한 상위 수준의 제어 레이어입니다. 이 레이어는 자체적으로 실제 작업을 수행해서는 안 되며, 작업들을  레이어​(이라고도 함)​에 위임해야 합니다.

참고로 지금 우리가 이야기하는 것은 당신이 선호하는 프로그래밍 언어의 이나  이 아닙니다. 이것들은 같은 것이 아닙니다.

실제 앱을 예로 들면 추상화는 그래픽 사용자 인터페이스이며 구현은 그래픽 사용자 인터페이스 레이어가 사용자와 상호작용하여 그 결과로 호출하는 배경 운영 체제 코드​(API)​입니다.

일반적으로 이러한 앱은 두 가지 독립적인 방향으로 확장할 수 있습니다.

  • 다른 여러 가지의 그래픽 사용자 인터페이스를 가진다 (예: 일반 고객 또는 관리자용으로 맞춘 인터페이스들).
  • 여러 다른 API들을 지원한다 (예: 맥, 리눅스 및 윈도우에서 앱을 실행할 수 있는 API들).

최악의 경우 이 앱은 수백 개의 조건문들이 코드 전체에 다양한 API와 다양한 유형의 그래픽 사용자 인터페이스들을 연결한 거대한 스파게티 코드 그릇처럼 형성됩니다.

 

 

를 잘 이해해야 하므로 모놀리식 코드베이스는 간단한 변경을 하는 것조차 매우 어렵습니다. 반면에 잘 정의된 작은 모듈들을 변경하는 것이 훨씬 쉽습니다.

당신은 특정 인터페이스-플랫폼 조합들과 관련된 코드를 별도의 클래스들로 추출하여 이 복잡함에 질서를 부여할 수 있으나, 곧 이러한 클래스들이  있다는 것을 알게 될 것입니다. 새로운 그래픽 사용자 인터페이스를 추가하거나 다른 API를 지원하려면 점점 더 많은 클래스를 생성해야 하므로 클래스 계층구조는 기하급수적으로 성장할 것입니다.

브리지 패턴으로 이 문제를 해결해 봅시다. 브리지 패턴은 클래스들을 두 개의 계층구조로 분리하라고 제안합니다:

  • 추상화: 앱의 그래픽 사용자 인터페이스 레이어.
  • 구현: 운영 체제의 API.

 

 

추상화 객체는 앱의 드러나는 모습을 제어하고 연결된 구현 객체에 실제 작업들을 위임합니다. 서로 다른 구현들은 공통 인터페이스를 따르는 한 상호 호환이 가능하며, 이에 따라 같은 그래픽 사용자 인터페이스는 리눅스와 윈도우에 동시에 작동할 수 있습니다.

따라서 당신은 API 관련 클래스들을 건드리지 않고 그래픽 사용자 인터페이스 클래스들을 변경할 수 있습니다. 그리고 다른 운영 체제에 대한 지원을 추가하려면 구현 계층구조 내에 자식 클래스를 생성하기만 하면 됩니다.