본문 바로가기

Language/Design Pattern

Adapter vs Bridge, Composite vs Decorator vs Proxy 비교

구조 패턴은 코드와 객체를 구조화하기 위해 언어가 제공하는 아주 작은 범위의 개념을 이용하기 때문에 각 패턴의 구조가 비슷할 수밖에 없다. 이러한 패턴들의 차이점은 왜 이 패턴을 써야 하는가에 있다.



Adapter vs Bridge


Adapter 패턴과 Bridge 패턴은 둘다 다른 객체에 대한 직접 접근 대신에 다른 우회적 방법으로 접근함으로써 유연성을 증대시킨다.
두 패턴간의 가장 큰 차이는 목적이 무엇인가 하는 것이다. Adapter의 목적은 이미 존재하는 두 인터페이스간의 불일치를 해결하려는 것이다.
그러나 Adapter패턴은 어떤 인터페이스를 어떻게 구현하게 할 것인가라든가, 인터페이스와 구현을 독립적으로 발전시키는 방법은 무엇일까 등의 사항은 전혀 고려치 않는다. 
이에 비해 Bridge 패턴의 경우는 추상화 개념과 구현을 따로 만들고, 이들을 연결시키려는 것이 주 목적이다.
Adapter는 두 클래스간의 종속성을 미리 예측하지 못하고 개발했을 경우에 필요한 패턴이고 Bridge는 이미 사용자가 추상화 개념을 구현하는 방법이 여러가지이고 이들 각각이 독립적으로 진화할수 있음을 파악한 상태에서 적용하는 패턴이다.


1. Adapter 와 Bridge에는 본질적인 차이가 없다. 즉 두 패턴은 동일한 것이다. 따라서 구조적인 차이 또한 없다.
2. 하지만 두 개의 의미상의 차이와 사용하고자 하는 목적의 차이는 분명 있다.

  • Adatper는 어떤 클래스의 인터페이스가 다른 코드에서 기대하는 것과 다를 때 (기능은 같은 데, 함수명이 다른...) 어댑터를 중간에 두어서 맞춰주는 것이다.

  •  Bridge는 추상과 구현을 분리하는 것이다. (추상 클래스는 추상 클래스 대로, 구현은 구현 대로 변경해도 서로 간에 영향을 주지 않는다.)

  • 결국 Adapter는 어떤 코드에 맞게끔 기존의 코드를 쓰기 위해 그 당시 만들어서 사용하는 경우 사용되어지고, Bridge는 확장성을 고려하여 미리 예상하여 bridge class를 구현 해 두어 코드를 진행해 나갈 때 사용되어진다. ( Bridge - Abstract 상속 받는 경우 : 함수와 기능의 확장성 고려 객체를 생성자에서 파라미터로 받는 경우 : 객체 종류의 수의 증가와 확장을 고려 )



Composite vs Decorator vs Proxy


Composite와 Decorator 패턴은 비슷한 구조를 갖고 있는데, 이 두 패턴 모두가 여러 객체를 조직화하기 위해 재귀적 합성 기법을 사용하기 때문이다.
이런 구조적 유사성으로 Decorator 객체를 약화된 합성 객체로 간주할 수도 있겠지만, 이는 Decorator의 중요한 특성을 놓치고 있는 것이다. 이 두 패턴의 공통성은 구조에서만 나타날 뿐 그 목적은 전혀 다르다.

Decorator 패턴은 상속없이 객체에 새로운 서비스를 추가하려는 목적을 갖는다. 그러므로 이미 만들어 둔 서비스 클래스들의 조합이 필요할 때마다 클래스를 생성해야 하는 문제를 해결해야 한다.
Composite패턴의 경우는 클래스의 구조화에 초점이 맞추어진 것으로서 어떻게 하면 관련된 객체들을 하나의 인터페이스로 다룰 수 있도록 일관성을 부여할 것인가가 중요한 관건이다. 즉 여러객체들을 하나의 객체로 통일시키고 싶은 것이다.
Decorator 패턴과 비슷한 구조를 갖는 것이 하나 더 있는데 바로 Proxy패턴이다. 두 패턴 모두 다른 객체에 간접적으로 접근할 수 있고, 프록시와 데코레이터를 구현할 때 메시지를 전달할 상대 객체에 대한 참조자를 관리하는 공통점이 있지만, 두패턴의 목적이 다르다.
Decorator와 같이 Proxy도 객체들을 합성하여 클라이언트에게는 동일한 인터페이스를 제공한다. 그러나 Proxy는 Decorator와 달리 동적으로 어떤기능성을 추가 했다 제거했다 하지는 않는다. Proxy의 목적은 서비스를 제공하는 대상에 대한 참조자를 직접관리하는 불편함을 해결하려는 것이다.
Decorator를 사용하는 목적은 컴파일할 때 모든 서비스의 객체를 다 결정할 수 없는 상황에서 적절하게 대응하기 위해서다. 

이런 차이들은 매우 중요하다. 구조가 비슷해 보여도 이들 패턴은 각기 서로다른 객체지향 설계의 특정 문제를 해결하려는 목적을 갖고 있기 때문이다. 그렇다고 이들 패턴을 서로 합쳐서 사용할 수 없다는 것은 아니다. Proxy-Decorator쌍은 Proxy에 추가적인 기능을 제공할 수 있고, Decorator-Proxy쌍의 경우는 원격지에 떨어진 객체에도 새로운 기능을 추가할 수 있게 한다. 이처럼 패턴의 조합은 매우 유용하다.