어댑터 패턴(Adapter Pattern) 

 

220V콘센트를 110V플러그에 꽂으려면 어댑터를 끼워줘야 함

어댑터 패턴은 말 그대로 둘 사이를 연결해줄 수 있는 어댑터를 만드는 패턴

 

한 클래스의 인터페이스를 사용하고자 하는 다른 인터페이스로 변환해서 사용할 수 있게 만드는 패턴

구조패턴의 한 종류이며 Wrapper 패턴이라고도 불림

 

 

 

Adapter 패턴을 사용하는 이유

 

1) 이미 잘 만들어진 클래스를 부품으로 재사용하기 위해
2) 구현이 빠르고 오류잡기가 쉬움

기존의 잘 만들어진 클래스의 인터페이스만 개조하는 클래스를 만드는 방식이므로 필요한 기능 구현이 빠름
기존의 클래스를 전혀 수정하지 않고 사용하고자 하는곳의 인터페이스에 맞추기만 하는 것
기존 클래스가 문제없다는것이 보장된다면 어댑터만 잘 만들면 되므로 오류잡기도 쉬움

또한 클래스 내부를 몰라도 인터페이스만 안다면 새로운 클래스를 만들수도 있으니 문제되지 않음

그러므로 이미 만들어진 클래스를 새로운 인터페이스에 맞게 개조할땐 Adapter 패턴을 사용한다.

 

 

 

Adapter 패턴의 종류

 

1) 클래스에 의한 어댑터 패턴(상속을 위한 어댑터)

2) 객체에 의한 어댑터 패턴(위임을 위한 어댑터)

 

 

 

Adapter 패턴 사용예시

 

#include <iostream>
#include <string>
using namespace std;

class stringNum // 숫자로된 문자열을 저장하는 기존의 클래스
{
public:
	stringNum(std::string data) : _data(data) {} // 생성자

	string getStringNum() { return _data; } // 문자열반환

private:
	string _data;
};

/* 
원래 숫자를 문자열로 저장하는 구조만 사용해왔는데
숫자만 매개변수로 받아주는 함수를 만나서
★기존의 클래스는 건들지 않고★ 단지 기존의 "문자열로된 숫자"를 "숫자"로 변환해주는 어댑터 생성
*/

// 추상클래스
class Adapter
{
public:
	virtual int func() = 0;
};

// 객체 어댑터 패턴
class instance_Adapter : public Adapter 
{
public:
	instance_Adapter(string data) : sn(data) {} // 생성자
	int func() override { return stoi(sn.getStringNum()); }

private:
	stringNum sn; // 객체를 내부에 선언해서 활용
};

// 클래스 어댑터 패턴
class class_Adapter : public Adapter, stringNum // 다중상속받은 후 사용
{
public:
	class_Adapter(string data) : stringNum(data) {}
	int func() override { return stoi(getStringNum()); }
};

// main
int main()
{
	instance_Adapter iA("12345"); 
	// 클래스 어댑터를 쓰려면 class_Adapter cA("12345");
	
	int num = iA.func(); 
	// 기존의 클래스는 건들지 않고 어댑터만으로 문자->숫자로 변환 성공
	cout << num;

	return 0;
}

결과)