본문 바로가기

DEV

Design Patterns - 4. Adapter Pattern

기존 코드를 재사용하기 위해 외부 인터페이스를 변환하는 작업이 많은데, 어댑터 패턴은 기존의 코드를 재사용하기 위해 내적, 외적 구조를 변환할 때 사용한다.
어댑터 패턴을 적용하면 클라이언트의 입장에서는 변화된 것 없이 기존 방식과 동일하게 코드를 작성해서 사용할 수 있다.
Adapter 패턴은 한 클래스의 프로그래밍 인터페이스를 다른 클래스의 프로그래밍 인터페이스로 변환할 때 사용된다. 하나의 프로그램에서 서로 연관 관계가 없는 클래스들을 서로 연결하려 할 때 이 패턴을 사용할 수 있다.

이것을 구현하는 경우, 상속(Inheritance)을 이용하거나 객체 컴포지션(Object Composition)을 사용하는 두 가지 방법이 있다.

첫째, 상속을 이용하는 방법은 상이한 인터페이스를 가진 클래스로부터 새로운 클래스를 상속하고, 요구된 인터페이스를 만족하는 새로운 메소드를 추가하는 방식으로 이루어진다. 이러한 방식을 ‘Class Adapter’라 한다.
둘째, 객체 컴포지션을 이용한 방법은 새로운 클래스 안에 상이한 인터페이스를 가진 클래스를 포함시키고, 새로운 클래스에 호출을 호환하기 위해 메소드를 새로 만드는 방식으로 구현된다. 이러한 방식을 ‘Object Adapter’라고 부른다.

JDK에서 Adapter 사용 예: WindowAdapter Class
https://docs.oracle.com/javase/10/docs/api/java/awt/event/WindowAdapter.html

 

■ UML Class Diagram

 

 

 

 

■ Code Snippet

 

class Rect
{
   public double l;
   public double w;
}

class Triangle
{
   public double b;//base
   public double h;//height
   public Triangle(int b, int h)
   {
      this.b = b;
      this.h = h;
   }
}

/*Calculator can calculate the area of a rectangle. To calculate the area we need a Rectangle input.*/
class Calculator
{
   Rect rectangle;
   public double getArea(Rect r)
   {
      rectangle=r;
      return rectangle.l * rectangle.w;
   }
}

/*Calculate the area of a Triangle using CalculatorAdapter. Please note here: this time our input is a Triangle.*/
class CalculatorAdapter
{
   Calculator calculator;
   Triangle triangle;
   public double getArea(Triangle t)
   {
      calculator = new Calculator();
      triangle=t;
      Rect r = new Rect();
      //Area of Triangle=0.5*base*height
      r.l = triangle.b;
      r.w = 0.5*triangle.h;
      return calculator.getArea(r);
   }
}

public class AdapterPattern
{
   public static void main(String[] args)
   {
      System.out.println("***Adapter Pattern Demo***");
      CalculatorAdapter cal = new CalculatorAdapter();
      Triangle t = new Triangle(20,10);
      System.out.println("\nAdapter Pattern Example\n");
      System.out.println("Area of Triangle is :" + cal.getArea(t));
   }
}

 

√ 실행 결과

 

■ 정리

1) 어댑터 패턴은 기능상으로 문제없이 동작하는 코드가 단지 인터페이스 차이 때문에 사용할 수 없는 경우 많이 응용되는 패턴이다.

2) 또는 기존 코드에 오류가 있거나 보정 작업이 필요한 경우에도 유용하다.

3) 객체 컴포지션을 사용하면 어댑터에 새로운 메서드를 재구성할 때마다 코드 수정이 필요하다.

4) 인터페이스를 처리한다는 점 또는 보정 및 버그를 개선하기 위해 추가한다는 점에서 Bridge Pattern, Facade Pattern, Decorator Pattern과 유사한 면이 많다.

 

※ 참고 자료

1) 『Java Design Patterns A Tour of 23 Gang of Four Design Patterns in Java』 (Apress, 2016)

2) https://en.wikipedia.org/wiki/Adapter_pattern