디자인 패턴 중 Bridge 패턴에 대해 설명합니다.
개념
두 개의 독립적인 계층으로 분리 가능한 하나의 클래스를 분리하여 책임을 분산시키는 패턴입니다. 상속 대신 집합(aggregation)을 사용하며, 분리된 각 계층을 Abstraction, Implementation이라고 부릅니다.
- Abstraction: 하이레벨의 컨트롤 로직으로써, Implementation 객체를 포함하고 클라이언트와 상호작용합니다. 특정 행위들에 대해서 Implementation에게 위임하고 클라이언트에 결과를 반환합니다.
- Implementation: Abstraction에 포함되는 객체입니다. 특정 행위를 수행하여 Abstraction에게 반환합니다.
클라이언트는 Abstraction 생성 시 Implementation을 주입하고 Abstraction하고 상호작용을 하게 됩니다.
다음과 같은 장점이 있습니다.
- Single Responsibility Principle: 하나의 클래스에서 has-a 관계로 표현할 수 있는 로직을 분리하여 책임을 분산합니다.
- Open-Closed Principle: 분리된 Abstraction과 Implementation 확장을 통해 기능을 수정/추가합니다.
- 상속을 남용하여 필요 이상 많은 클래스가 추가되는 클래스 폭발(class explosion)을 막을 수 있습니다
적용 예시
그래픽 소프트웨어를 개발중이라고 가정합니다. 기본적으로 래스터방식의 렌더링을 지원하는데 벡터 방식의 렌더링에 대한 요구사항 등장했습니다.
이를 상속으로 해결할 수 있지만 도형의 종류가 다양할수록, 렌더링이 추가될수록 클래스 수가 기하급수적으로 증가하게 됩니다. Bridge 패턴을 사용하면 이를 해결할 수 있습니다.
from abc import ABC, abstractmethod
class Renderer(ABC):
@abstractmethod
def render(self): ...
class RasterRenderer(Renderer):
def render(self):
print("raster")
class VectorRenderer(Renderer):
def render(self):
print("vector")
class Shape:
def __init__(self, renderer: Renderer) -> None:
self._renderer = renderer
def render(self):
return self._renderer.render()
class Circle(Shape): ...
renderer = VectorRenderer()
circle = Circle(renderer=renderer)
circle.render()
렌더링 관련 구현부를 분리하여 Shape를 Abstraction으로, Renderer를 Implementaion으로 정의합니다. 도형이 늘어나거나 렌더링방식이 늘어나도 효과적으로 관리할 수 있습니다.
참조
'객체 지향 > 디자인 패턴' 카테고리의 다른 글
디자인 패턴 - Decorator (1) | 2023.10.25 |
---|---|
디자인 패턴 - Composite (0) | 2023.10.22 |
디자인 패턴 - Adapter (0) | 2023.10.12 |
디자인 패턴 - Singleton (0) | 2023.10.11 |
디자인 패턴 - Prototype (0) | 2023.10.09 |