728x90

어댑터라는 것은 우리 주변에서도 흔히 볼 수 있다. 대표적으로 110V 전용 가전 제품에 220V 어댑터를 끼워 사용하는 것이다.


어댑터를 보면 어댑터 패턴이 무엇인지 대충 감이 올 수도 있겠다.



이 패턴을 사용할만 한 경우를 만들어보면,



"포토뷰어 엔진을 판매하는 회사 A가 있다. 이 A 회사의 엔진이 우리 회사의 포토뷰어 엔진보다 성능이 좋다는 결과를 통보 받았다. 그래서 나는 우리 회사의 포토 뷰어 엔진을 교체 하기 위해 A라는 회사에 엔진을 요청했고 엔진 명세서를 받아봤다."



즉 '나'는 성능의 향상을 위해 포토 뷰어 엔진을 기존의 엔진에서 A 업체가 제공하는 엔진으로 바꿔야만 하는 상황이다.



이제 명세표를 보면 A엔진과 기존 엔진의 구조를 살표보자.


/* 내가 쓰는 엔진 명세 (MyLib) */ class MyLib { public: void printPhoto(String fileName)          { ... } void printPhotoList(String[] listName)    { ... } void deletePhoto(String fileName)        { ... } void addPhoto(String fileName)           { ... } }



/* A 엔진 명세 (ALib) */ class ALib { public:

void printPhoto(String fileName)          { ... } void deletePhoto(String fileName)        { ... } void addPhoto(String fileName)          { ... } }




엔진이 완전히 같다면 좋을텐데 미묘하게 다른 구석이 있다. 차이가 있는 것은 제공 받은 엔진에서 printPhotoList() 가 없다는 것이다. 어쨋든 엔진 교체를 위해 코드 분석에 들어가보자. 아래 코드는 기존 엔진을 사용한 코드이다. 기존 엔진의 이름은 MyLib 이다.


/* 기존 코드 */ int main() { MyLib lib = new MyLib(); String photoList = { "abc.jpg" , "def.jpg" }; lib.printPhotoList(photoList); lib.printPhoto("abc.jpg"); lib.deletePhoto("abc.jpg"); lib.addPhoto("aaa.jpg"); }




자, 이제 함수명이 동일하니 한번 엔진을 바꿔보자.


/* 바뀐 코드 Ver.1 */ int main() { ALib lib = new ALib(); // change String photoList = { "abc.jpg" , "def.jpg" }; for(int i = 0 ; i < photoList.length; i++)    // for문 추가됨

{ lib.printPhoto(photoList[i]); } lib.printPhoto("abc.jpg"); lib.deletePhoto("abc.jpg"); lib.addPhoto("aaa.jpg"); }




이제 프로그램은 잘 돌아갈거라고 생각이 되지만, 기본 로직에 변경이 생겼다. 바로 전에 없었던 for()이 들어가게 된 것이다. 물론 이 코드를 더 이상의 유지 보수를 하지 않을 예정이라면 이대로 놔둬도 상관없겠지만, 프로그램을 만들면 무조건 유지 보수를 해야하기 때문에 이렇게 두는 것은 좋지 않은 방법이다.




따라서 기본 로직을 그대로 이용할 수 있게끔 어댑터 패턴을 사용해보자.


class IPhotoEngine { public:

virtual void printPhoto(String fileName) = 0;     virtual void printPhotoList(String[] listName) = 0;

virtual void deletePhoto(String fileName) = 0; virtual void addPhoto(String fileName) = 0; }




인터페이스 클래스를 만들었다. 이제 어댑터 클래스를 만들어보자.



class ALibAdapter : public IPhotoEngine { private: ALib lib; public: ALibAdapter( ALib lib ) { this.lib = lib; } void printPhoto(String fileName) { lib.printPhoto( fileName ); } void printPhotoList(String[] listName) { for(int i = 0 ; i < listName.length; i++) { lib.printPhoto( listName[i] ); } } void deletePhoto(String fileName) { lib.deletePhoto( fileName ); } void addPhoto(String fileName) { lib.addPhoto( fileName ); } }





이제 이 클래스를 사용해 보자.



/* 바뀐 코드 Ver.2 */
int main()
{
	ALib alib = new ALib();

	PhotoEngine lib = new ALibAdapter( alib );
	String photoList = { "abc.jpg" , "def.jpg" };
	lib.printPhotoList(photoList);
	lib.printPhoto("abc.jpg");
	lib.deletePhoto("abc.jpg");
	lib.addPhoto("aaa.jpg");
}



물론 ALib가 아닌 다른 엔진을 사용할 때에도 마찬가지로 IPhotoEngine 인터페이스를 포함한 어댑터 클래스를 만들기만 하면 언제든 로직을 재사용할 수 있다.


이것이 바로 어댑터 패턴을 사용하는 목적이기도 하다.


만약 기존엔진을 다시 써야하는 상황이 올때를 대비해서 기존 엔진의 어댑터 클래스를 만들어보자.



class MyLibAdapter : public PhotoEngine { private: MyLib lib; public: MyLibAdapter( MyLib lib ) { this.lib = lib; } void printPhoto(String fileName) { lib.printPhoto( fileName ); } void printPhotoList(String[] listName) { lib.printPhotoList( listName ); } void deletePhoto(String fileName) { lib.deletePhoto( fileName ); } void addPhoto(String fileName) { lib.addPhoto( fileName ); } }



그리고 간단하게 기존 엔진을 사용하도록 바꾸면 된다.



/* 바뀐 코드 Ver.3 */
int main()
{
	MyLib myLib = new myLib();
	PhotoEngine lib = new MyLibAdapter( myLib );
	String photoList = { "abc.jpg" , "def.jpg" };
	lib.printPhotoList(photoList);
	lib.printPhoto("abc.jpg");
	lib.deletePhoto("abc.jpg");
	lib.addPhoto("aaa.jpg");
}




출처 : http://jdm.kr/blog/11




728x90

+ Recent posts