기록하자..
어댑터 & 퍼사드 패턴 (Adapter & Facade Pattern) 본문
어댑터 패턴
어댑터 패턴을 사용하고자 하는 경우는 다음과 같다.
- 기존 클래스를 사용하고 싶은데 해당 클래스가 제공하는 인터페이스가 필요한 인터페이스와 다른 경우
- 객체가 어떤 공통 인터페이스를 가지고 있지 않은 클래스들과 상호작용을 해야하는 경우
- 기존 여러 하위 클래스가 제공하고 있지 않은 어떤 공통 기능을 추가하고 싶지만 이 기능을 상위 클래스에 추가할 수 없는 경우
'이미 제공되어 있는 것'과 '필요한 것'의 차이를 없애줄 수 있는 패턴이다.
Head First Design Pattern에서 Duck 인터페이스와 Turkey 인터페이스를 예로 들며 설명하고 있다.

public class TurkeyAdapter implements Duck {
private Turkey turkey;
public TurkeyAdapter(Turkey turkey) {
this.turkey = turkey;
}
public void quack() {
turkey.gobble();
}
public void fly() {
for(int i = 0; i < 5; i++)
turkey.fly();
}
}
Duck 객체가 모자라서 Turkey 객체를 대신 사용해야 하는 상황이라고 해보자. 이때 Turkey 타입을 Duck타입으로 바꿀 필요가 있는데 이때 TurkeyAdpater를 사용해서 Turkey 를 Duck 타입으로 바꾸어준다.
이제 클래스의 다이어그램을 살펴보자

- Target interface : 클라이언트가 사용하고 싶은 interface
- Cilent : Target interface를 사용해야 하는 객체
- 어댑티(Adaptee) : 클라이언트가 사용해야 하지만 Target interface를 제공하지 않는 객체
- 어댑터(Adapter) : 어댑티를 Target interface로 사용할 수 있도록 해주는 객체
다이어그램에서 클라이언트는 Target 인터페이스만 알고 있는 것을 확인할 수 있다. Adapter는 Adaptee를 멤버로 가지며 Has-a관계를 유지하고 있는 것을 확인할 수 있다.
클래스 어댑터 VS 객체 어댑터
어댑터에는 두 종류가 있는데 하나는 클래스 어댑터, 다른 하나는 객체 어댑터이다. 먼저 간단하게 설명하자면, 클래스 어댑터는 상속을 이용하여 어댑터를 구현하는 방식이고, 객체 어댑터는 포함관계를 이용하여 어댑터를 구현한다.
- 클래스 어댑터는 다중상속을 이용하기 때문에 자바에서는 사용할 수 없다.. 하지만 자바에서도 adaptee를 상속받고 새 인터페이스를 제공하는 형태로 클래스 어댑터 형태로 구현이 가능하다.
- 위의 TurkeyAdapter는 객체 어댑터로서 객체 어댑터는 adaptee를 멤버로 가지고 있다.
각 어댑터의 다이어그램을 살펴보자


- 클래스 어댑터는 adaptee를 멤버변수로 가지지 않고, 객체 어댑터는 adaptee를 멤버변수를 가지고 있다는 차이를 볼 수 있다.
- 클래스 어댑터는 상속을 이용하기 때문에 특정 클래스 하나에 대해서만 어댑터 역할을 할 수 있지만 객체 어댑터는 포함 관계를 이용하기 때문에 하나의 클래스를 이용하여 계층 구조에 있는 다양한 객체에 대한 어댑터로 사용할 수 있다.
- 클래스 어댑터는 상속을 사용하기 때문에 기본적으로 양방향 어댑터로 사용할 수 있다.
- 양방향 어댑터 : 어댑터를 어댑티가 필요한 곳에서도 사용할 수 있는 어댑터
- 어댑터에 추가된 코드 때문에 어댑티 환경에서 사용할 때 원래 어댑티와 다르게 행동할 수 있다.
어댑터패턴의 장단점
- 장점
- 어댑터 클래스는 SRP에 충실한 클래스이다. (adaptee를 target interface로 변환)
- 어댑터는 OCP를 제공하는 한 가지 방법이다. 기존 클래스를 수정하지 않고 서비스를 제공한다.
- 단점
- 경우에 따라 어댑터를 만들기보다 어댑터를 바꾸는 것이 간단할 수 있다. 보통 어댑티와 클라이언트를 모두 수정하기 힘들거나 적절하지 않을 때 사용하는 패턴
퍼사드 패턴
서브 시스템의 일련의 인터페이스에 대한 통합된 인터페이스를 제공하여 준다. Facade 패턴은 결국 서브 시스템을 좀 더 사용하기 쉽도록 상위 수준의 인터페이스를 정의해준다.

질문
Head First Design Pattern에서 질문을 통해 여러 정보를 알려준다.
- Facade 패턴을 사용하면 하위 레벨 객체들에 대한 접근이 봉쇄되는 것은 아닌가?
- 아니다. 그냥 서브 시스템의 기능을 사용할 수 있는 간단한 인터페이스를 제공하는 것 뿐이다. 원하면 각 서브 시스템의 객체들을 직접 접근할 수 있다.
- 각 서브시스템은 하나의 Facade만을 가지는가?
- 아니다. 여러 개의 Facade를 만들 수 있다.
- Adapter와 Facade의 차이점은 무엇인가?
- Adapter와 Facade의 차이는 용도에 있다. Adapter는 인터페이스를 변경해서 클라이언트에서 필요로 하는 인터페이스를 적응시키기 위한 용도로 사용한다.
Facade는 서브 시스템을 사용하기 편리하도록 해주는 것이다.
- Adapter와 Facade의 차이는 용도에 있다. Adapter는 인터페이스를 변경해서 클라이언트에서 필요로 하는 인터페이스를 적응시키기 위한 용도로 사용한다.
퍼사드패턴의 장단점
- 장점
- 클라이언트는 복잡한 서브시스템을 관리하고 간단하게 사용할 수 있다.
- 클라이언트가 의존관계에 있는 클래스의 수를 줄일 수 있다.
- 서브 시스템과 클라이언트간에 느슨하게 연결되기 때문에 서브 시스템에 대한 개선, 보완을 클라이언트와 독립적으로 수행할 수 있다.
- 단점
- 퍼사드는 너무 많은 종류의 객체와 상호작용할 수 있다.
'디자인패턴공부' 카테고리의 다른 글
| 템플릿 메서드 패턴 (Template Method Pattern) (0) | 2021.12.03 |
|---|---|
| 명령 패턴(Command Pattern) (0) | 2021.11.28 |
| 생성 패턴(Factory Pattern) (0) | 2021.11.28 |
| Decorator 패턴 (0) | 2021.10.26 |
| 관찰자 패턴(Observer Pattern) (0) | 2021.10.19 |