어댑터 패턴(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;
}
결과)