어댑터(Adapter) 패턴

2024. 10. 12. 02:57Design Pattern

디자인 패턴: 어댑터(Adapter) 패턴

어댑터 패턴(Adapter Pattern)은 서로 다른 인터페이스를 사용하는 클래스들 사이의 호환성 문제를 해결하기 위해 사용하는 구조 패턴(Structural Pattern) 중 하나입니다.
이를 통해 기존 클래스를 수정하지 않고도, 필요한 인터페이스에 맞게 변환(어댑터)할 수 있어 유연한 설계가 가능합니다.


어댑터 패턴의 개념

어댑터 패턴은 호환되지 않는 인터페이스를 가진 클래스들을 서로 연결하여, 클라이언트가 마치 일관된 인터페이스를 사용하는 것처럼 동작하게 만듭니다. 어댑터 패턴은 기존 클래스를 변경하지 않고도 다른 코드에서 재사용할 수 있게 하며, 시스템을 유연하고 확장성 있게 유지합니다.


주요 구성 요소

  1. Target (대상 인터페이스)
    • 클라이언트가 사용하려고 하는 기대하는 인터페이스입니다.
      클라이언트는 이 인터페이스를 통해 시스템에 접근합니다.
  2. Adaptee (적응 대상 클래스)
    • 기존에 정의된 클래스로, 클라이언트가 원하는 인터페이스와 호환되지 않는 클래스입니다.
      이 클래스의 기능을 재사용할 필요가 있지만, 직접 사용할 수는 없습니다.
  3. Adapter (어댑터)
    • Adaptee의 인터페이스를 Target 인터페이스에 맞게 변환해주는 클래스입니다.
      어댑터는 Adaptee의 메서드를 호출하면서, Target에서 요구하는 인터페이스에 맞도록 변환합니다.
  4. Client (클라이언트)
    • Target 인터페이스를 사용하여 어댑터를 통해 기능을 사용하려는 객체입니다.
      클라이언트는 어댑터 덕분에 Adaptee의 메서드를 직접 알지 못해도 원하는 작업을 수행할 수 있습니다.

어댑터 패턴 구현 예시

1. Target 인터페이스

// Target: 클라이언트가 기대하는 인터페이스
public interface ITarget
{
    void Request();
}

2. Adaptee 클래스

// Adaptee: 호환되지 않는 기존 클래스
public class Adaptee
{
    public void SpecificRequest()
    {
        Console.WriteLine("Adaptee: SpecificRequest 호출됨");
    }
}

3. Adapter 클래스

// Adapter: Adaptee를 Target 인터페이스에 맞게 변환
public class Adapter : ITarget
{
    private readonly Adaptee _adaptee;

    public Adapter(Adaptee adaptee)
    {
        _adaptee = adaptee;
    }

    public void Request()
    {
        // Adaptee의 SpecificRequest 메서드를 Target의 Request로 변환
        _adaptee.SpecificRequest();
    }
}

4. Client 코드

class Program
{
    static void Main(string[] args)
    {
        // Adaptee 객체 생성
        Adaptee adaptee = new Adaptee();
        
        // 어댑터를 통해 Adaptee를 사용
        ITarget target = new Adapter(adaptee);
        
        // 클라이언트는 Target 인터페이스만 알면 됨
        target.Request();
    }
}

출력 결과:

Adaptee: SpecificRequest 호출됨

어댑터 패턴의 장점

  1. 호환성 제공
    • 서로 다른 인터페이스를 가진 클래스들이나 코드들 간의 호환성을 제공하여 기존 시스템을 수정하지 않고도 새로운 기능을 도입할 수 있습니다.
  2. 유연성
    • 어댑터를 통해 기존 코드를 변경하지 않고도 유연한 코드 재사용이 가능합니다. 이를 통해 코드의 확장성유지보수성이 향상됩니다.
  3. 클라이언트와 구현의 분리
    • 클라이언트는 Adaptee의 세부 구현을 알 필요가 없습니다. 대신, Target 인터페이스만 사용하면 되므로 클라이언트 코드가 더욱 단순해지고 유지 관리가 용이해집니다.

어댑터 패턴의 단점

  1. 어댑터 클래스 추가
    • 새로운 어댑터 클래스를 추가해야 하므로, 설계가 다소 복잡해질 수 있습니다. 특히, 인터페이스 변환이 필요한 클래스가 많아지면 어댑터 클래스도 많아질 수 있습니다.
  2. 퍼포먼스 문제
    • 어댑터 패턴을 사용하면 인터페이스 변환을 위한 추가 레이어가 생기므로, 성능이 중요한 시스템에서는 성능 저하가 발생할 수 있습니다.

어댑터 패턴의 사용 사례

  1. 서드파티 라이브러리 통합
    • 외부 서드파티 라이브러리가 기존 코드와 호환되지 않을 때, 어댑터를 사용하여 해당 라이브러리의 인터페이스를 변환하고 시스템에 통합할 수 있습니다.
  2. 레거시 코드와 통합
    • 기존의 레거시 코드와 새로운 시스템 간의 통합 시, 어댑터 패턴을 사용하여 레거시 시스템을 변경하지 않고도 새로운 시스템에 맞게 사용할 수 있습니다.
  3. UI 프레임워크 간의 호환성
    • 서로 다른 UI 프레임워크 간의 호환성을 제공할 때, 어댑터 패턴을 사용하여 동일한 인터페이스로 여러 프레임워크를 통합할 수 있습니다.

어댑터 패턴은 서로 다른 인터페이스를 가진 클래스들 간의 호환성 문제를 해결하여, 기존 클래스를 수정하지 않고도 새로운 환경에 적응할 수 있게 만들어줍니다. 이를 통해 기존 시스템의 유연성을 높이고, 재사용 가능성을 극대화할 수 있습니다. 외부 라이브러리와의 통합, 레거시 시스템과의 통합 등 다양한 상황에서 어댑터 패턴은 유용하게 사용될 수 있습니다.

'Design Pattern' 카테고리의 다른 글

퍼사드(Facade) 패턴  (0) 2024.10.14
데코레이터(Decorator) 패턴  (1) 2024.10.14
빌더(Builder) 패턴  (0) 2024.10.10
옵저버(Observer) 패턴  (5) 2024.10.03
Factory 패턴 및 추상 팩토리 패턴  (0) 2024.10.02