ㅎ1. 어댑터 패턴이란?

어댑터(Adapter) 패턴은 두 개의 호환되지 않는 인터페이스를 연결해주는 디자인 패턴입니다. 마치 110V만 지원하는 전자제품을 220V 콘센트에 꽂을 수 있게 하는 변압기처럼, 서로 다른 코드 구조를 간단히 연결할 수 있습니다. 이 패턴은 코드 재사용성을 높이고 기존 클래스를 변경하지 않으면서 새 요구 사항을 만족시킬 수 있다는 장점이 있습니다. 🎯

 


2. 핵심 개념

어댑터 패턴은 다음 세 가지 구성요소로 이루어집니다:

  • 클라이언트(Client): 원하는 기능을 호출하는 측.
  • 타깃(Target): 클라이언트가 요구하는 인터페이스.
  • 어댑터(Adapter): 기존 클래스(Adaptee)를 타깃 인터페이스에 맞게 변환하는 클래스.

간단히 말해, 어댑터는 기존 코드의 "모양"을 변경해 클라이언트가 사용할 수 있도록 돕는 역할을 합니다. 🤝


3. C# 구현 예제

다음은 어댑터 패턴을 C#으로 구현한 예제입니다.

요구사항

클라이언트는 IRenderer 인터페이스를 사용하여 물체를 렌더링해야 합니다. 하지만, 기존의 두 클래스 LegacyRendererAdvancedLegacyRenderer는 이 인터페이스를 따르지 않습니다.

// Target Interface
public interface IRenderer
{
    void Render();
}

// Existing Class (Adaptee 1)
public class LegacyRenderer
{
    public void LegacyRender()
    {
        Console.WriteLine("Rendering using LegacyRenderer");
    }
}

// Existing Class (Adaptee 2)
public class AdvancedLegacyRenderer
{
    public void AdvancedRender()
    {
        Console.WriteLine("Rendering using AdvancedLegacyRenderer");
    }
}

// Adapter Class
public class RendererAdapter : IRenderer
{
    private readonly object _adaptee;

    public RendererAdapter(object adaptee)
    {
        _adaptee = adaptee;
    }

    public void Render()
    {
        if (_adaptee is LegacyRenderer legacyRenderer)
        {
            legacyRenderer.LegacyRender();
        }
        else if (_adaptee is AdvancedLegacyRenderer advancedRenderer)
        {
            advancedRenderer.AdvancedRender();
        }
        else
        {
            throw new NotSupportedException("Unsupported adaptee type");
        }
    }
}

// Client Code
class Program
{
    static void Main()
    {
        LegacyRenderer legacyRenderer = new LegacyRenderer();
        AdvancedLegacyRenderer advancedRenderer = new AdvancedLegacyRenderer();

        IRenderer renderer1 = new RendererAdapter(legacyRenderer);
        IRenderer renderer2 = new RendererAdapter(advancedRenderer);

        renderer1.Render(); // Output: Rendering using LegacyRenderer
        renderer2.Render(); // Output: Rendering using AdvancedLegacyRenderer
    }
}

설명

  1. 클라이언트는 IRenderer 인터페이스만 사용합니다.
  2. 기존 클래스 LegacyRendererAdvancedLegacyRendererIRenderer를 따르지 않지만, 어댑터 RendererAdapter를 통해 연결되었습니다.
  3. 어댑터는 각 클래스의 메서드를 호출하면서도 클라이언트의 기대에 맞는 인터페이스를 제공합니다. 🧩

4. 어댑터가 필요한 순간 🧐

어댑터 패턴은 다음과 같은 상황에서 특히 유용합니다:

  1. 레거시 코드 통합: 기존 시스템과 새로운 시스템을 연결할 때.
  2. 다른 인터페이스 간 호환성 확보: 서로 다른 팀에서 개발된 모듈을 연결해야 할 때.
  3. 인터페이스 변경 없이 기능 확장: 기존 클래스를 수정하지 않고 기능을 추가해야 할 때.

주의: 어댑터 패턴을 너무 자주 사용하면 코드가 복잡해질 수 있습니다. 따라서 필요 이상으로 사용하지 않도록 주의하세요! ⚠️


5. 결론

어댑터 패턴은 기존 코드를 재사용하며 새로운 요구 사항에 대응할 수 있는 강력한 도구입니다. 하지만, 단순히 코드 구조를 맞추는 역할만 하기 때문에 지나치게 남용하면 오히려 유지보수가 어려워질 수 있습니다.

언제 사용하는 것이 적절할지 신중하게 판단하고, 필요할 때만 적용하는 것이 중요합니다. 🚀


6. 관련 링크

반응형

+ Recent posts