어댑터패턴 (1)

 Creational Patterns ( 생성 패턴 )

These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. 

생성패턴은 객체의 생성로직을 숨기고 new 명령어를 통하지 않고 객체를 생성하는 방법들을 제공한다. 이는 특정 상황에서 어떤 방법으로 객체를 생성해야할지를 결정하는데 있어서 유연성을 제공한다. 


 Structural Patterns ( 구조적 패턴 )

These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 

구조적 패턴들은 클래스와 객체의 구성에 관여한다.

 

 Behavioral Patterns ( 행위적 패턴 )

These design patterns are specifically concerned with communication between objects.

이 패턴들은 객체들 사이의 커뮤니케이션에 관심을 가진다.

 

오늘 살펴볼  Adapter 패턴은 Structural 패턴에 속한다.  

 

어 댑터가 뭐냐? 우리가 맨날 쓰는 그 어댑터가 바로 지금 말하고자하는 어댑터이다. 어댑터의 역할이 뭐냐? 서로 맞물리지 않는 두개의 객체를 연결시켜주는 일을 하는 것이 어댑터의 역할이다. 이 생각을 가지고 아래 내용을 훑어보기 바란다.

 

Adapter Pattern Structure

 A class adapter uses multiple inheritance to adapt one interface to another:

클래스 어댑터는 하나의 인터페이스를 다른 인터페이스와 연결시키기 위해서 다중상속을 이용한다.

 

 

An object adapter relies on object composition:

객체 어댑터는 객체의 구성에 의존한다. ( 뭔 말인지 모르겠다 일단 넘어가자 )



 

패턴의 목적 ( Intent ) : 

Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.

어댑터 패턴의 목적은 클라이언트가 원하는 인터페이스를 제공하기 위해서 클래스의 형태를 변형하는 것이다.(이는 서로 연결을 시켜줌으로써 아웃풋을 변형한다는 의미이지 실제로 변형한다는 의미가 아니다) 어댑터는 서로 맞물리지 않는 인터페이스들을 서로 연결시켜주는 역할을 한다.

 

 

패턴이 나오게 된 동기 ( Motivation ) :

예 를 들어 이런 경우가 있을 것이다. 고객이 원하는 기능을 구현을 했다고 하자. 이 기능은 인풋으로 A객체를 받아들이고 아웃풋으로 X객체를 던지며 고객이 만든 API와 연결이 된다. 그런데 얼마가 지나서 고객이 인풋으로 Y객체를 달라고 한다. 그런데 전에 만들어 줬던 기능의 일부분만 Y객체를 아웃풋으로 내보내야 한다는 것이다. 당신이라면 어떻게 해결할 것인가? 물론 생각해야할 인자들이 무수히 많을 것이고 그것들에 따라 해결책도 다를 것이다. 여기서는 그 중 하나의 해결책으로 어댑터 패턴을 말하고자 한다. A -> DoSomething -> X 기능을 하는 기능은 여전히 존재해야만 하며 DoSomething -> Y 기능을 추가해야한다. 하지만 이 두가지는 엄연히 동일한 기능을 한다고 가정한다. 어댑터 패턴을 이용해야하니까. 그러면 우리는 A -> DoSomething -> X -> Y 가 될 수 있게끔 X -> Y 기능을 하는 어댑터를 추가하면 된다.

 

쉽게말하자면소켓에 맞는 어댑터를 추가하는 것이다. 아래 그림처럼 말이다.


 

 


유용성 ( Applicability ) :

Use the Adapter pattern when
· you want to use an existing class, and its interface does not match the one you need.

기존의 클래스를 사용하고 싶지만 내가 필요로 하는 형태가 아닐때
· you want to create a reusable class that cooperates with unrelated or unforeseen classes, that is, classes that don't necessarily have compatible interfaces.

특정 호환성을 가진 클래스가 아닌 광범위한 호환성을 가진 재사용가능한 클래스를 만들고 싶을때
· (object adapter only) you need to use several existing subclasses, but it's impractical to adapt their interface by subclassing every one. An object adapter can adapt the interface of its parent class.

 

등장 인물 ( Participants ) :

· Target (Shape)o defines the domain-specific interface that Client uses.
· Client (DrawingEditor)
o collaborates with objects conforming to the Target interface.
· Adaptee (TextView)
o defines an existing interface that needs adapting.
· Adapter (TextShape)
o adapts the interface of Adaptee to the Target interface.

 

원리 ( Collaborations ) : 

· Clients call operations on an Adapter instance. In turn, the adapter calls Adaptee operations that carry out the request.


패턴 사용의 장단점 ( Consequences ): 


Class and object adapters have different trade-offs.  

클래스 어댑터와 객체어댑터는 서로의 장단점이 있다.  

A class adapter  

· adapts Adaptee to Target by committing to a concrete Adapter class. As a consequence, a class adapter won't work when we want to adapt a class and all its subclasses.

· lets Adapter override some of Adaptee's behavior, since Adapter is a subclass of Adaptee.
· introduces only one object, and no additional pointer indirection is needed to get to the adaptee.

 

An object adapter
· lets a single Adapter work with many Adaptees—that is, the Adaptee itself and all of its subclasses (if any). The Adapter can also add functionality to all Adaptees at once.
· makes it harder to override Adaptee behavior. It will require subclassing Adaptee and making Adapter refer to the subclass rather than the Adaptee itself.


관련 패턴들 : 

Bridge has a structure similar to an object adapter, but Bridge has a different intent: It is meant to separate an interface from its implementation so that they can be varied easily and  independently. An adapter is meant to change the interface of an existing object.
Decorator
enhances another object without changing its interface. A decorator is thus more transparent to the application than an adapter is. As a consequence, Decorator supports  recursive composition, which isn't possible with pure adapters.
Proxy
defines a representative or surrogate for another object and does not change its interface.

 

추가 정보 :     

  • Adapter makes things work after they're designed; Bridge makes them work before they are.
  • Bridge is designed up-front to let the abstraction and the implementation vary independently. Adapter is retrofitted to make unrelated classes work together.
  • Adapter provides a different interface to its subject. Proxy provides the same interface. Decorator provides an enhanced interface.
  • Adapter is meant to change the interface of an existing object. Decorator enhances another object without changing its interface. Decorator is thus more transparent to the application than an adapter is. As a consequence, Decorator supports recursive composition, which isn't possible with pure Adapters.
  • Facade defines a new interface, whereas Adapter reuses an old interface. Remember that Adapter makes two existing interfaces work together as opposed to defining an entirely new one.

 

 

 

출처 : http://sourcemaking.com/design_patterns/adapter

         Design Patterns : Element of Reusable Object Oriented Software ( by GoF, 1994 )