본문 바로가기
SWE/C++ OOP

[디자인 패턴] Adapter Pattern 어댑터 패턴

by S나라라2 2021. 9. 23.
반응형

어댑터 패턴 Adapter Pattern

 

어댑터 패턴이란 클래스의 인터페이스를 사용자가 기대하는 다른 인터페이스로 변환하는 패턴이다.

 

우리가 해외여행 갈 때 챙겨가는 어댑터를 떠올리면 이해가 쉽다.

한국 전원 플러그는 보통 220V를 사용하는데 해외는 110V 전압을 사용하고 플러그 핀 갯수나 모양도 다르다.

따라서 한국 전자제품을 해외로 가져가서 사용할 때 해외 규격에 맞춰서 변환해주는 '어댑터'가 필요하다.

어댑터 패턴도 이와 같은 역할을 한다. 우리가 원하는 규격으로 변환해주는 패턴이다.

 

 

예제

 

사각형을 그리는 클래스로 예시를 들어보겠다.

 

예를 들어, 기존에 사각형을 그리는 클래스를 제공해주고 있었는데, 새로운 업체에서는 사각형 클래스의 메소드 인자 타입을 변경하였다.

각 업체마다 제공해주는 형식이 다르기 때문에, 기존 코드는 수정하지 않고, 호환될 수 있도록 어댑터 패턴을 사용하는 상황이다.

 

기존 사각형 메소드 - Rectangle 클래스

void drawRectangle(int x, int y, int width, int height)
{
	...
}

void setLineColor(QString color)
{
	...
}

기존 코드에서는 사각형 그리는 메소드의 인자로 int형 4개를 받고 있다.

사각형의 선은 QString 으로 색상을 지정할 수 있다.

drawRectangle(0, 0, 100, 100), setLineColor("#ff0000") 와 같이 호출될 것이다.

 

신규 사각형 메소드 - NewRectangle 클래스

void drawNewRectangle(QSize& size)
{
	...
}

void setNewLineColor(QColor& color)
{
	...
}

새로운 업체에서 구현한 인자 형식은 이와 같다. 

사각형의 좌표와 크기는 QSize를 통해 요청하고 사각형의 선은 QColor를 이용하여 지정한다. 

drawRectangle(QSize(0, 0, 100, 100)), setLineColor(QColor("#ff0000")) 와 같이 호출될 것이다.

 

기존 형식으로 신규 클래스 사용 가능하도록 변환해주는 어댑터 - Adapter 클래스

public class Adapter implements Rectangle{
	NewRectangle newRectangle;
    
    public Adapter(newRectangle newOne)
    {
    	this.newRectangle = newOne;
    }
    
    public void drawRectangle(int x, int y, int width, int height)
    {
    	newRectangle.drawRectangle(QSize(x, y, width, height));
    }
    
    public void setLineColor(QString color)
    {
    	newRectangle.setLineColor(QColor(color));
    }
}

 

어댑터 클래스에서 중요한 포인트 2가지

(1) 어댑터 클래스는 기존 인터페이스(Rectangle)를 상속받고 있다.

따라서 client 에서 사용할 때는 변경된 사실을 모른채 기존(Rectangle)을 호출하듯 사용할 수 있다.

 

(2) 어댑터 패턴에서는 객체 구성(Composition)을 사용한다.

새로 바뀐 인터페이스 newRectangle을 멤버변수로 가지면서 감싸주고 있다.

Composition을 사용할 경우 변경 사항이 있을 때 유연성이 좋다.

 

// 테스트 코드

void main()
{

	// 1. 기존 Rectangle 클래스 사용
    Rectangle rectangle = new Rectangle();
    testRectangle(rectangle, "#00ff00", 0,0,100,100);


	// 2. 신규 NewRectangle 클래스를 사용하지만, 
    // Adapter로 감쌌기 때문에 기존 형식 유지가 가능하다.
    NewRectangle newOne = new NewRectangle();
    Rectangle adapter = new Adapter(newOne);
    testRectangle(adapter, "#00ff00", 0,0,100,100);

}

void testRectangle(Rectangle rectangle,
					int x, int y, int width, int height,
					QString color)
{
	rectangle.setLineColor(color);
    rectangle.drawRectangle(x, y, width, height);
}

어댑터에서는 setLineColor(string) -> setLineColor(QColor), 

drawRectangle(int, int, int, int) -> drawRectangle(QSize)로 변환해준다. 

즉, rectangle 타입을 newRectangle로 변환하여 호출한다.

 

 

클래스 다이어그램

client에서 target 호출 : 클라이언트에서는 변경사항을 알 필요없이 기존과 동일한 형식으로 target을 사용하면 된다. 

Adapter에서 Adaptee 컴포지션 : 사용자가 기존 target으로 호출한 것을 adaptee로 호환해서 사용한다.

반응형