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 )