2024. 10. 17. 00:37ㆍDesign Pattern
Bridge 패턴 - 개념과 구현
Bridge 패턴은 구조 패턴(Structural Pattern) 중 하나로, 구현부와 추상화부를 분리하여 둘을 독립적으로 변화시킬 수 있도록 하는 패턴입니다. 이 패턴은 여러 가지 방식으로 구성을 변경할 수 있는 상황에서 특히 유용합니다. 즉, 클라이언트가 사용하고자 하는 기능과 그 기능의 구현을 독립적으로 발전시킬 수 있는 방법을 제공합니다.
1. Bridge 패턴이란?
Bridge 패턴은 추상화(Abstraction)와 구현(Implementation)을 분리하여 각각을 독립적으로 발전시킬 수 있도록 설계된 구조입니다. 이 패턴을 사용하면 추상화와 그 구현을 서로 독립적으로 확장할 수 있어, 코드의 유연성과 재사용성을 높일 수 있습니다.
언제 사용하는가?
- 다양한 구현 방식이 필요하지만, 각 구현 방식이 독립적으로 변할 수 있는 상황에서.
- 여러 기능이 동시에 존재하며, 각각의 기능에 대한 변경이 빈번한 경우.
- 클래스의 수가 너무 많아지는 것을 방지하고, 코드의 복잡성을 줄이고 싶을 때.
2. Bridge 패턴의 구조
Bridge 패턴은 크게 Abstraction, RefinedAbstraction, Implementor, ConcreteImplementor의 네 가지 요소로 구성됩니다.
1. Abstraction (추상화)
- 클라이언트가 사용하게 되는 인터페이스로, 구현 객체를 참조하여 특정 작업을 수행합니다.
2. RefinedAbstraction (구체화된 추상화)
- Abstraction을 상속받아 좀 더 구체적인 기능을 구현한 클래스입니다.
3. Implementor (구현자)
- 실제 구현이 이루어지는 인터페이스로, ConcreteImplementor 클래스가 이 인터페이스를 구현합니다.
4. ConcreteImplementor (구체적 구현)
- Implementor를 구현한 클래스들로, 구체적인 기능을 제공하는 클래스입니다.
3. Bridge 패턴의 구현 예시 (C#)
// Implementor: 구현 인터페이스
public interface IDrawingAPI
{
void DrawCircle(double x, double y, double radius);
}
// ConcreteImplementor: 구체적인 구현
public class DrawingAPI1 : IDrawingAPI
{
public void DrawCircle(double x, double y, double radius)
{
Console.WriteLine($"Drawing Circle in API1: ({x}, {y}) with radius {radius}");
}
}
public class DrawingAPI2 : IDrawingAPI
{
public void DrawCircle(double x, double y, double radius)
{
Console.WriteLine($"Drawing Circle in API2: ({x}, {y}) with radius {radius}");
}
}
// Abstraction: 추상화
public abstract class Shape
{
protected IDrawingAPI _drawingAPI;
protected Shape(IDrawingAPI drawingAPI)
{
_drawingAPI = drawingAPI;
}
public abstract void Draw(); // 추상 메서드
}
// RefinedAbstraction: 구체화된 추상화
public class Circle : Shape
{
private double _x, _y, _radius;
public Circle(double x, double y, double radius, IDrawingAPI drawingAPI)
: base(drawingAPI)
{
_x = x;
_y = y;
_radius = radius;
}
public override void Draw()
{
_drawingAPI.DrawCircle(_x, _y, _radius); // 구현부의 메서드를 호출
}
}
위 코드에서 IDrawingAPI는 구현 인터페이스이며, DrawingAPI1과 DrawingAPI2는 실제 구현을 제공합니다.
Shape는 추상화된 클래스이고, Circle은 구체화된 추상화입니다.
Circle 클래스는 IDrawingAPI의 메서드를 사용하여 원을 그리는 작업을 수행합니다.
클라이언트 코드
public class Program
{
public static void Main(string[] args)
{
Shape shape1 = new Circle(5, 10, 2, new DrawingAPI1());
Shape shape2 = new Circle(7, 14, 3, new DrawingAPI2());
shape1.Draw(); // Drawing Circle in API1: (5, 10) with radius 2
shape2.Draw(); // Drawing Circle in API2: (7, 14) with radius 3
}
}
클라이언트 코드에서는 Circle 객체를 생성할 때, 어떤 DrawingAPI를 사용할지 결정합니다.
이때 각기 다른 구현체를 사용하여 원을 그릴 수 있습니다.
4. Bridge 패턴의 장단점
장점:
- 유연성: 추상화와 구현을 독립적으로 발전시킬 수 있어, 새로운 기능을 추가하기 용이합니다.
- 코드 재사용: 다양한 구현을 동일한 추상화로 사용할 수 있어, 코드 중복을 줄이고 재사용성을 높입니다.
- 구조 단순화: 클래스의 수를 줄일 수 있으며, 계층 구조를 단순화할 수 있습니다.
단점:
- 복잡성 증가: 초기 설계가 복잡해질 수 있으며, 모든 경우에 필요한 것은 아닙니다.
- 문서화 필요: 각 부분의 역할과 관계를 명확히 이해하고 문서화해야 합니다.
5. Bridge 패턴의 사용 사례
5.1. 그래픽 시스템
다양한 그래픽 API (OpenGL, DirectX 등)와 그 위에 존재하는 그래픽 객체(선, 원, 도형 등)를 분리하여, 새로운 그래픽 API를 쉽게 추가할 수 있도록 설계할 수 있습니다.
5.2. 데이터베이스와 ORM
데이터베이스의 여러 종류(MySQL, SQL Server, SQLite 등)와 ORM(Object-Relational Mapping) 구현을 분리하여, 새로운 데이터베이스를 추가할 때 기존 코드에 영향을 주지 않도록 할 수 있습니다.
5.3. UI 구성 요소
다양한 UI 프레임워크와 UI 컴포넌트를 분리하여, 새로운 UI 프레임워크를 사용하더라도 기존 컴포넌트를 그대로 활용할 수 있습니다.
Bridge 패턴은 추상화와 구현을 분리하여 둘의 독립적인 발전을 가능하게 하는 구조 패턴입니다.
이를 통해 코드의 유연성과 재사용성을 높일 수 있으며, 다양한 상황에서 활용될 수 있습니다.
Bridge 패턴을 이해하고 적용함으로써, 더 나은 소프트웨어 설계를 할 수 있습니다.
'Design Pattern' 카테고리의 다른 글
이터레이터(Iterator) 패턴 (1) | 2024.10.17 |
---|---|
커맨드(Command) 패턴 (0) | 2024.10.17 |
프록시(Proxy) 패턴 (0) | 2024.10.17 |
컴포지트(Composite) 패턴 (0) | 2024.10.17 |
프로토타입(Prototype) 패턴 (0) | 2024.10.14 |