프로그래밍 Design Pattern 이해하기 - 7 어댑터패턴&파사드패턴


Android/번역본 2014.08.31 15:50





어댑터 패턴 & 퍼사드 패턴 




만약 미국에서 만든 랩탑을 유럽에서 쓰려고 한다면, AC Power Adapter가 필요하다.


아답터가 어떤 역활을 하는지 우린 알고있다. 랩탑의 플러그와 유럽의 콘센트와 연결을 하기 위해 필요한 것이다. 코드 상에서 이 실제세계의 어댑터를 적용해보면, interface와 클라이언트단의 어떤 것과 연결을 해주는 것이다. 즉, 한 클래스의 인터페이스를 클라이언트에서 사용하고자 하는 다른 인터페이스로 변환할 수 있다. 


OO Adapter(Object oriented adapter) 는 새로운 벤더클래스를 이미 구현되어 있는 곳에 붙일 때 사용된다. 




어댑터는 클라이언트의 요청을 벤더클래스로 전달할 때 사용된다. 

그렇게 되면, 기존에 있는 코드들은 수정을 하지 않아도 되며, 벤더클래스에도 역시 코드 수정이 일어나지 않는다. 

오로지 어댑터만 수정하면 된다. 


코드로 알아보자. 챕터 1의 Duck을 기억하는가?




이 Duck클래스를 상속받아 MallardDuck을 만들었다. 




자 이제 새로운 것을 만들어보자. 




Turkey와 Duck은 서로 다른 interface를 가지고 있다. 이런 경우 서로 다른 인터페이스를 이용해보면,




실제로 적용해보자!








즉 우리는 클라이언트가 request()를 하게 되면, Adapter가 해당 Request를 받아 translateRequest()를 Client에게 전달하게 된다. 

TurkeyAdapter가 Adapter의 역활을 하게 되고, 실제 Turkey interface에게 전달하게 된다. 



어댑터 패턴을 정의해보면, 


 interface를 다른 클라이언트 에서 사용할 수 있는 interface로 변환하는 패턴이다.








구식의 110v(옛날코드)를 220v (신규작성코드)아답터를 꼽으면 새코드를 사용할 수 있는 것과 같이 옛날코드를 새로운 코드로 사용할 수 있다는 장점이 있다.




 

 위쪽의 그림처럼, Duck class와 Turkey class를 받아 request를 요청했을 때 변환해주는 어댑터를 만들면 되는데, 중요한 점은, '자바'에서는 다중상속이 되지 않는다. 때문에 (클래스 어댑터 패턴은 적용불가능) 객체 어댑터 패턴을 사용해,  request하는 쪽을 interface로 만든 뒤 "Adapter"클래스는 Duck interface를 상속이 아닌 implement 하는 방식으로 사용한다. 





 퍼사드!(Facade) Light, Camera, Facade!

Facade 는 "외관"이란 단어의 의미로 사용 됨.









"HomeTeatherFacade"는 가정용 극장의 "외관"역활을 한다. '영화를 재생, 혹은 종료' 시킬 수 있고 '음악듣기, 끄기' '라디오 켜기, 끄기' 

의 기능을 가지고 있고, Facade class(HomeTeatherFacade)를 서브클래싱한 Projector, TheatherLights 등이 존재한다.


 이렇게 된 패턴을 사용하면 외부에서 리모콘으로 '영화보기()'를 클릭하면, watchMovie()가 호출되게 되고, 불이켜지고, DVDPlayer, 프로젝터, 스크린이 켜지고, 팝콘을 만들게 되죠. 파사드는 직접적으로 서브클래스들을 제어한다.


 - 파사드로 하위 클래스들을 캡슐화한다면, 클라이언트가 로우레벨이 있는 기능을 쓰고 싶을 때에는 어떻게 하죠?

답 : 파사드는 "캡슐화"하는 것이 아니다. 단지 간단한 기능을 수행하는 단순한 interface로 사용이 된다. 서브시스템 클래스들은 그들 각각의 인스턴스를 만들어 직접적으로 접근이 가능하며, 간단한 인터페이스로 모든 기능에 대해 접근할 수 있도록 만들어놓은 것이 파사드의 장점이다.


 - 그럼 서브시스템들은 꼭 하나의 파사드를 가져야 하나요?

답 : 여러개의 파사드를 가져도 된다. 


- 파사드의 장점이 뭔가요? 그냥 간단한 interface를 쓰면 안되나요?

답 : 파사드 패턴은 서브클래스들이 중복되지 않고 하나의 subSystem으로 동작하도록 하게 해준다. 만약에 가정용 극장안에 있는 기기들을 업그레이드 했을 때 새로운 컴포넌트들이 생길 것이고 이런 경우 facade 에 있는 코드를 수정하기만 하면 된다. 하위에 있는 코드들은 수정하지 않아도 된다. 때문에 파사드 클래스 하나만 계속 수정을 해나가면 되는 것이다!





 



파사드 패턴을 쓰면 바로 이 이론에 부합한다. 


그 전에 지금까지 나온 이론들을 살펴보자. 

- 인터페이스에 맞춰서 프로그래밍을 하자!

- 최대한 결합도를 낮춰라!

- OCP(개방 폐쇄 원칙) 수정에는 닫혀있되 확장에는 열려있어라!

- 의존성 뒤집기 원칙 추상화 된 것에 의존하도록 하라. 

그리고 이번 패턴을 통해 부합되는 원칙은 바로


Principle of least knowledge (정말 친한 친구하고만 이야기하라!) - 최소 지식 원칙 


- 시스템을 디자인할 때 어떤 객체든 상호작용을 하는 클래스의 갯수에 주의해야 하며, 그런 객체들과 어떤식으로 상호작용을 하는지에 주의를 기울어야 한다. 클래스들끼리 상호작용을 할 때 '정말 친한 친구'끼리 이야기하라라는 원칙.


 그러면, '파사드패턴'과 '어댑터패턴'의 차이점은 무엇일까?

어댑터패턴은 인터페이스를 변경해 클라이언트에서 필요로 하는 인터페이스로 변경적용하기 위한 용도

파사드 패턴은 어떤 서브시스템에 간단한 인터페이스를 제공하기 위한 용도

즉, 파사드는 인터페이스의 단순화 용도, 어댑터는 인터페이스를 다른 인터페이스로 변환하기 위한 용도!


- 기존 클래스를 재사용하려고 하는데 인터페이스가 맞지 않는 경우 어댑터를 쓰자!
- 여러 인터페이스를 단순화시키거나 통합하는 경우 패서트패턴을 쓰자!

- 파사드 패턴은 서비시스템을 가진 파사드를 만들고, 실제 작업은 서브클래스한테 맡긴다!

- 한 서브시스템에 파사드가 여러개여도 된다. 

- 어댑터 패턴에서는, 객체 어댑터와 클래스 어댑터 패턴이 있는데, 클래스 어댑터를 쓰려면 다중 상속 기능이 필요하다. 





저작자 표시 비영리 변경 금지
신고

WRITTEN BY
ShakeJ

0 ,