본문 바로가기
Thinking/Concept

브리지 패턴(Bridge Pattern) 이해하기

by Dev_카페인 2024. 11. 15.
반응형

브리지 패턴(Bridge Pattern) 이해하기

브리지 패턴구현과 추상화를 분리하여 독립적으로 확장할 수 있도록 하는 구조적 디자인 패턴입니다. 즉, 기능 계층과 구현 계층을 분리하여 결합을 최소화하는 방식으로, 기능 확장 시 구현 변경 없이 새로운 기능을 추가할 수 있게 합니다. 브리지 패턴은 특히 기능과 구현이 독립적으로 확장해야 할 필요가 있을 때 유용합니다.

이번 포스트에서는 브리지 패턴의 개념과 구조, 구현 방법, 장단점 및 적용 상황을 구체적인 예제와 함께 알아보겠습니다.

브리지 패턴이란?

브리지 패턴은 인터페이스를 통한 추상적인 부분(Abstraction)과 구체적인 구현 부분(Implementation)을 분리하여, 두 부분이 독립적으로 변화할 수 있도록 하는 구조적 디자인 패턴입니다. 브리지 패턴의 핵심은 두 계층을 별도의 클래스 계층으로 분리하여, 추상화와 구현 간의 결합도를 낮추는 데 있습니다.

브리지 패턴을 사용하면 새로운 기능과 구현을 추가할 때 기존 코드를 변경할 필요 없이 각각 독립적으로 확장할 수 있으며, 특히 기능 계층과 구현 계층을 구분해야 할 때 매우 유용합니다.

 

브리지 패턴의 구조

브리지 패턴은 다음과 같은 요소로 구성됩니다.

  1. Abstraction (추상화 클래스): 기능 계층을 정의하는 상위 클래스입니다. Implementor 인터페이스를 통해 구체적인 구현을 위임합니다.
  2. RefinedAbstraction (확장된 추상화 클래스): Abstraction 클래스를 상속받아 추가적인 기능을 구현할 수 있습니다.
  3. Implementor (구현 인터페이스): Abstraction의 기능을 구체적으로 구현할 인터페이스를 정의합니다.
  4. ConcreteImplementor (구체적인 구현 클래스): Implementor 인터페이스를 구현하여 구체적인 기능을 제공합니다.

브리지 패턴의 구현 방법

예제 코드: 다리 종류와 다리 색상 분리 예제

다양한 형태의 다리(Bridge)와 색상을 조합하여 구현하는 예제를 통해 브리지 패턴을 구현해보겠습니다. 예를 들어, 다리에는 여러 형태가 있을 수 있으며, 각 다리는 다양한 색상으로 칠해질 수 있습니다.

// Implementor (구현 인터페이스)
public interface IColor
{
    string ApplyColor();
}

// ConcreteImplementorA (구체적인 구현 클래스 A)
public class RedColor : IColor
{
    public string ApplyColor() => "Red";
}

// ConcreteImplementorB (구체적인 구현 클래스 B)
public class BlueColor : IColor
{
    public string ApplyColor() => "Blue";
}

// Abstraction (추상화 클래스)
public abstract class Bridge
{
    protected IColor Color;

    public Bridge(IColor color)
    {
        Color = color;
    }

    public abstract string Build();
}

// RefinedAbstractionA (확장된 추상화 클래스 A)
public class SuspensionBridge : Bridge
{
    public SuspensionBridge(IColor color) : base(color) {}

    public override string Build()
    {
        return $"Building Suspension Bridge with {Color.ApplyColor()} color.";
    }
}

// RefinedAbstractionB (확장된 추상화 클래스 B)
public class ArchBridge : Bridge
{
    public ArchBridge(IColor color) : base(color) {}

    public override string Build()
    {
        return $"Building Arch Bridge with {Color.ApplyColor()} color.";
    }
}

// Client 코드
class Program
{
    static void Main()
    {
        Bridge redSuspensionBridge = new SuspensionBridge(new RedColor());
        Console.WriteLine(redSuspensionBridge.Build());

        Bridge blueArchBridge = new ArchBridge(new BlueColor());
        Console.WriteLine(blueArchBridge.Build());
    }
}

위 코드에서 Bridge는 다리의 추상화 클래스로, 색상(IColor)의 구현을 별도의 인터페이스로 분리했습니다. SuspensionBridge와 ArchBridge는 다리의 형태에 따라 확장된 기능을 제공하며, 색상은 RedColor와 BlueColor 클래스를 통해 구현됩니다.

출력 결과는 다음과 같습니다.

Building Suspension Bridge with Red color.
Building Arch Bridge with Blue color.

이 예제에서는 다리의 형태와 색상이 독립적으로 변경될 수 있습니다. 예를 들어, 새로운 형태의 다리나 색상을 추가할 때 기존 클래스들을 수정하지 않고도 조합하여 사용할 수 있습니다.

 

브리지 패턴의 장단점

장점

  1. 기능과 구현의 독립적 확장: 기능과 구현을 별도로 확장할 수 있어 유지보수와 코드 관리가 용이합니다.
  2. 결합도 감소: 추상화와 구현을 별도의 클래스 계층으로 분리하므로, 두 계층 간의 결합도가 낮아집니다.
  3. 유연한 구조: 다양한 조합이 가능하여 클래스 수를 줄이고 코드의 유연성을 높입니다.

단점

  1. 복잡성 증가: 추상화와 구현 계층을 분리하는 구조를 갖추어야 하므로 코드 구조가 다소 복잡해질 수 있습니다.
  2. 설계 요구: 브리지 패턴을 사용하기 위해서는 구현 계층과 기능 계층을 명확하게 구분할 필요가 있어 초기 설계가 중요합니다.

 

언제 브리지 패턴을 사용해야 할까?

브리지 패턴은 기능 계층과 구현 계층이 독립적으로 변해야 할 필요가 있을 때 적합합니다. 다음과 같은 경우에 유용하게 사용됩니다.

  1. 여러 구현이 필요하고, 각각의 구현이 독립적으로 변경될 수 있을 때: 예를 들어, 다리의 형태와 색상이 독립적으로 변경될 수 있는 경우에 브리지 패턴이 유용합니다.
  2. 기능 확장이 빈번히 발생하고, 구현이 변경될 가능성이 있을 때: 기능 확장과 구현 변경이 잦은 경우, 두 계층을 분리하여 관리하면 코드 유지보수가 쉬워집니다.
  3. 여러 조합이 필요한 경우: 다수의 구현을 조합하여 사용해야 하는 경우, 기능과 구현을 분리하면 각 구현의 조합을 독립적으로 관리할 수 있습니다.

 

브리지 패턴과 어댑터 패턴의 차이점

브리지 패턴과 어댑터 패턴은 모두 클래스 간의 결합을 줄이는 구조적 패턴이지만, 목적과 사용 방식에서 차이가 있습니다.

  • 브리지 패턴: 추상화와 구현을 독립적으로 확장할 수 있도록 구조를 분리하는 데 중점을 둡니다. 서로 다른 기능과 구현을 조합하기 위해 사용됩니다.
  • 어댑터 패턴: 기존 클래스의 인터페이스를 클라이언트가 기대하는 인터페이스로 변환하는 데 중점을 둡니다. 호환되지 않는 인터페이스를 연결하기 위해 사용됩니다.

따라서, 기능과 구현을 분리하여 독립적으로 확장해야 할 때는 브리지 패턴을, 호환되지 않는 인터페이스를 변환하여 기존 클래스를 재사용하고자 할 때는 어댑터 패턴을 사용하는 것이 적절합니다.

 

마무리하며

브리지 패턴은 추상화와 구현을 분리하여 독립적으로 확장할 수 있게 하는 강력한 디자인 패턴입니다. 기능과 구현을 분리함으로써 코드의 유연성과 확장성을 높이고, 유지보수를 용이하게 합니다. 브리지 패턴을 활용하면 독립적인 기능 확장이 필요한 소프트웨어 설계에서 코드의 결합도를 줄이고 재사용성을 높일 수 있습니다.

다양한 기능과 구현 조합이 필요한 경우, 브리지 패턴을 사용하여 효율적이고 확장 가능한 구조를 만들어 보세요.

반응형