Adapter Pattern은 서로 다른 인터페이스를 가진 클래스를 연결시키는 패턴을 말한다.
이런식의 구조를 가진다. 굉장히 간단하다. 서로 다른 두 인터페이스 A와 B가 있을 때 A를 B처럼 쓰고 싶다면 B를 구현하는 C를 만들고 C가 인자로 A를 받은 뒤 B가 하는 일을 A를 이용해서 만들어주면 끝이다. 위 그림에서 B의 인터페이스가 Target이고 Adaptee가 A이다.
위 방식의 구현을 객체 어댑터 방식이라고하고 또 다른 클래스 어댑터 방식이라는 것이 있다. 이것은 다중상속이 가능한 언어에서만 가능하다.
객체 어댑터와 차이점은 Target과 Adaptee가 클래스이고 Adapter는 이를 다중상속 받는다는 점 밖에 없다.
책에서 데코레이터 패턴과의 차이점을 이야기하고 있는데 뭔가 와닿진 않지만 일단 써보자면 데코레이터 패턴은 인터페이스는 바꾸지 않고 책임(기능)만 추가하는 것이고 어댑터패턴은 하나의 인터페이스를 다른 인터페이스로 바꾸는 패턴이다.
퍼사드 패턴은 복잡한 구조를 가진 시스템을 여러 절차를 거쳐 복잡하게 사용해야 할 때 그 절차들을 묶어 클라이언트가 한번만 호출해도 그 절차를 한번에 수행할 수 있게끔 간단하게 해주는 클래스를 만드는 패턴을 말한다. 책에서 나온 매크로와 비슷한 것 같다.
문서적 정의는 다음과 같다.
"서브시스템에 있는 일련의 인터페이슬르 통합 인터페이스로 묶어 줍니다. 또한 고수준 인터페이스도 정의하므로 서브시스템을 더 편리하게 사용할 수 있다."
이런식으로 퍼사드가 없을 경우에 클라이언트는 영화를 보기 위해 각 클래스 인스턴스를 만들고 여러 인스턴스들의 메소드를 호출해야한다고 했을 때 만약 퍼사드 클래스를 만들어 놓았다면 watchMovie()를 호출하기만해서 그 절차를 다 없앤다는 뜻이다. 이런 패턴을 쓸 때 장점은 당연히 인터페이스를 간단하게 다시 만들어서 편리하다는 점과 클라이언트와 서브시스템(퍼사드가 사용하고 있는 시스템 자체)를 분리시킬 수 있다는 것이다. 만약 서브시스템이 크게 바뀌었다면 기존엔 클라이언트 코드도 같이 많이 바뀌어야하지만 퍼사드 패턴을 쓰면 퍼사드 클래스를 이에 맞게 바꾸어주면 이를 사용하는 클라이언트 코드는 수정하지 않아도 된다는 것이다. 만약 1인 개발자라면 변경하는 코드의 양은 동일하겠지만 여러 사람들이 같이 개발하는 입장이고 서브시스템을 만드는 쪽이 퍼사드 클래스까지 담당하고 있다면 이쪽 개발자들은 서브시스템을 잘 알고 있으므로 비교적 쉽게 퍼사드 클래스를 만들 수 있다는 측면에서 좋다고 볼 수 있다.
객체의 상호작용은 될 수 있으면 제일 가까운 관계의 객체와만 해야한다는 것이다. 책에서 가까운 관계는 아래와 같이 정의하고 있다.
위 원칙을 따르려면 다른 메소드를 호출해서 리턴받은 객체의 메소드를 호출해서도 안된다. 아래 예시를 보자.
public float getTemp(){
Thermometer thermometer = station.getThermometer();
return thermometer.getTemperature();
}
public float getTemp(){
return station.getTemperature();
}
맨 위 함수는 Thermometer 클래스의 변경과도 연관이 지어지기 때문에 좋은 코드가 아니라고 할 수 있다. 대신 Station 클래스가 Thermometer에게서 온도를 받아오는 getTemperature메소드를 새로 만들고 그것을 위 클래스에서 사용해면 의존관계를 2개에서 1개로 줄일 수 있다.
아래의 코드는 위의 4개 경우를 모두 포함하고 있는 좋은 코드의 예시이다.
public class Car {
Engine engine;
public Car(){}
public void start(Key key){
Doors doors = new Doors();
boolean a = key.turns(); //매개변수의 메소드 호출 가능 2번
engine.start(); //4번
B(); //1번
doors.lock(); //3번
}
public void B(){}
}
퍼사드 패턴은 최소지식원칙을 올바르게 수행할 수 있게끔 도와준다. 기존에 여러 클래스와 의존관계를 지니던 클라이언트 클래스 코드를 퍼사드 클래스 단 하나와만 의존하게 되기 때문이다.