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.

์ด ํŒจํ„ด๋“ค์€ ๊ฐ์ฒด๋“ค ์‚ฌ์ด์˜ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์— ๊ด€์‹ฌ์„ ๊ฐ€์ง„๋‹ค.

 

์˜ค๋Š˜ ์‚ดํŽด๋ณผ  Decorator ํŒจํ„ด์€ Structural ํŒจํ„ด์— ์†ํ•œ๋‹ค.  ์ด ํŒจํ„ด์€ ์ปดํฌ์ง€ํŠธ ํŒจํ„ด๊ณผ ๋น„์Šทํ•œ ๋‹ค์ด์–ด๊ทธ๋žจ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. 

 

Decorator Pattern Structure


ํŒจํ„ด์˜ ๋ชฉ์  ( Intent ) : 

 Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

 ๋™์ ์œผ๋กœ ๊ฐ์ฒด์— ์ฑ…์ž„(๊พธ๋ฐˆ)์„ ์ถ”๊ฐ€ํ•œ๋‹ค. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•˜๊ธฐ ์œ„ํ•œ subclassing์ด ์•„๋‹Œ ๋‹ค๋ฅธ ์œ ๋™์ ์ธ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•œ๋‹ค. 


ํŒจํ„ด์ด ๋‚˜์˜ค๊ฒŒ ๋œ ๋™๊ธฐ ( Motivation ) :

์ผ๋ฐ˜์ ์œผ๋กœ ๊ฐ„๋‹จํ•œ ํ”„๋กœ์ ํŠธ๊ฐ€ ์•„๋‹Œ ์ด์ƒ ํ•˜๋‚˜์˜ ํด๋ž˜์Šค ๋‚ด์—์„œ ๋ชจ๋“  ๊ฒƒ์„ ํ•ด๊ฒฐํ•˜๋Š” ์ผ์€ ๊ฑฐ์˜ ์—†๋‹ค. ์œ ์ง€๋ณด์ˆ˜๋ฅผ ์œ„ํ•ด์„œ๋ผ๋„ ๊ธฐ๋Šฅ๋ณ„๋กœ ํด๋ž˜์Šค๋ฅผ ๋‚˜๋ˆ„๊ฒŒ ๋˜๋Š”๋ฐ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด๋„ ์ด๋Ÿฐ ์‹์˜ ์ƒ๊ฐ์—์„œ ๋‚˜์˜ค๊ฒŒ ๋œ ๊ฒƒ์ด๋‹ค. ๊ทธ๋ž˜์„œ ์ƒ์†์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๊ธฐ๋„ ํ•˜๋Š”๋ฐ ์ด๋Š” ๋งค์šฐ ๊ธฐ๋ณธ์ ์ธ ๋ฐฉ๋ฒ•์ด๋ฉฐ flexibleํ•˜์ง€ ์•Š๊ณ  ์ •์ ์ด๋‹ค. ๋”ฐ๋ผ์„œ ๋™์ ์œผ๋กœ ๊ธฐ๋Šฅํ™•์žฅ์ด ์šฉ์ดํ•˜๋„๋ก ํ•œ ๊ฒƒ์ด ๋ฐ”๋กœ ์ด ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์ด๋‹ค. ์•„๋ž˜ ๊ทธ๋ฆผ์€ TextView์— ScrollDecorator์™€ BorderDecorator๋ฅผ ์ด์šฉํ•˜์—ฌ ์ฑ…์ž„(๊พธ๋ฐˆ)์„ ์ถ”๊ฐ€ํ•œ ๊ฒฐ๊ณผ์ด๋‹ค.

 

์œ ์šฉ์„ฑ ( Applicability ) :

Use Decorator

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์€ ์•„๋ž˜์™€ ๊ฐ™์€ ์ƒํ™ฉ์—์„œ ์œ ์šฉํ•˜๋‹ค.


ยท to add responsibilities to individual objects dynamically and transparently, that is, without affecting other objects.

๋‹ค๋ฅธ ๊ฐ์ฒด์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๊ณ  ๋™์ ์œผ๋กœ ํˆฌ๋ช…ํ•˜๊ฒŒ ๋…๋ฆฝ์ ์ธ ๊ฐ์ฒด๋“ค์„ ์ถ”๊ฐ€ํ•  ๋•Œ
ยท for responsibilities that can be withdrawn.

์ฒ ํšŒ๊ฐ€ ๊ฐ€๋Šฅํ•œ ์ฑ…์ž„(๊พธ๋ฐˆ)์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์„ ๋•Œ
ยท when extension by subclassing is impractical. Sometimes a large number of independent extensions are possible and would produce an explosion of subclasses to support every combination. Or a class definition may be hidden or otherwise unavailable for subclassing. 

์„œ๋ธŒํด๋ž˜์‹ฑ์œผ๋กœ ๊ธฐ๋Šฅํ™•์žฅํ•˜๋Š” ๊ฒƒ์ด ๋น„์‹ค์šฉ์ ์ผ ๋•Œ


๋“ฑ์žฅ ์ธ๋ฌผ ( Participants ) :

ยท Component (VisualComponent)
o defines the interface for objects that can have responsibilities added to them dynamically.

๋™์ ์œผ๋กœ ์ถ”๊ฐ€๋˜๋Š” ์ฑ…์ž„์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ์œ„ํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ •์˜ํ•œ๋‹ค.
ยท ConcreteComponent (TextView)
o defines an object to which additional responsibilities can be attached.

์ถ”๊ฐ€์ ์ธ ์ฑ…์ž„์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ์ •์˜ํ•œ๋‹ค.
ยท Decorator
o maintains a reference to a Component object and defines an interface that conforms to Component's interface.

์ด ํŒจํ„ด์˜ ๋ฉ”์ธ์ด๋‹ค. ์ปดํฌ๋„ŒํŠธ ๊ฐ์ฒด์˜ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ, ์ปดํฌ๋„ŒํŠธ์™€ ์กฐํ™”๋ฅผ ์ด๋ฃจ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ •์˜ํ•œ๋‹ค.
ยท ConcreteDecorator (BorderDecorator, ScrollDecorator)
o adds responsibilities to the component.

์ปดํฌ๋„ŒํŠธ์— ์ฑ…์ž„์„ ๋ถ€๊ณผํ•œ๋‹ค. 


์›๋ฆฌ ( Collaborations ) :

ยท Decorator forwards requests to its Component object. It may optionally perform additional operations before and after forwarding the request.


ํŒจํ„ด ์‚ฌ์šฉ์˜ ์žฅ๋‹จ์  ( Consequences ): 

The Decorator pattern has at least two key benefits and two liabilities:

 

1. More flexibility than static inheritance. ์ •์ ์ธ ์ƒ์†๋ณด๋‹ค ํ›จ์”ฌ ์œ ๋™์ ์ด๋‹ค. The Decorator pattern provides a more flexible way to add responsibilities to objects than can be had with static (multiple) inheritance. With decorators, responsibilities can be added and removed at run-time simply by attaching and detaching them. In contrast, inheritance requires creating a new class for each additional responsibility (e.g., BorderedScrollableTextView, BorderedTextView). This gives rise to many classes and increases the complexity of a system.
Furthermore, providing different Decorator classes for a specific Component class lets you mix and match responsibilities.
Decorators also make it easy to add a property twice. For example, to give a TextView a double border, simply attach two BorderDecorators. Inheriting from a Border class twice is error-prone at best.


2. Avoids feature-laden classes high up in the hierarchy. Decorator offers a pay-as-you-go approach to adding responsibilities. Instead of trying to support all foreseeable features in a complex, customizable class, you can define a simple class and add functionality incrementally with Decorator objects. Functionality can be composed from simple pieces. As a result, an application needn't pay for features it doesn't use. It's also easy to define new kinds of Decorators independently from the classes of objects
they extend, even for unforeseen extensions. Extending a complex class tends to expose details unrelated to the responsibilities you're adding.


3. A decorator and its component aren't identical. A decorator acts as a transparent enclosure. But from an object identity point of view, a decorated component is not identical to the component itself. Hence you shouldn't rely on object identity when you use decorators.


4. Lots of little objects. A design that uses Decorator often results in systems composed of lots of little objects that all look alike. The objects differ only in the way they are interconnected, not in their class or in the value of their variables. Although these systems are easy to customize by those who understand them, they can be hard to learn and debug. 

 

๊ด€๋ จ ํŒจํ„ด๋“ค : 

Adapter : A decorator is different from an adapter in that a decorator only changes an object's responsibilities, not its interface; an adapter will give an object a completely new interface. 

 Composite : A decorator can be viewed as a degenerate composite with only one component. However, a decorator adds additional responsibilitiesโ€”it isn't intended for object aggregation.
Strategy : A decorator lets you change the skin of an object; a strategy lets you change the guts. These are two alternative ways of changing an object.


์ถ”๊ฐ€ ์ •๋ณด :  

  • Adapter provides a different interface to its subject. Proxy provides the same interface. Decorator provides an enhanced interface.
  • Adapter changes an object's interface, Decorator enhances an object's responsibilities. Decorator is thus more transparent to the client. As a consequence, Decorator supports recursive composition, which isn't possible with pure Adapters.
  • Composite and Decorator have similar structure diagrams, reflecting the fact that both rely on recursive composition to organize an open-ended number of objects.
  • A Decorator can be viewed as a degenerate Composite with only one component. However, a Decorator adds additional responsibilities - it isn't intended for object aggregation.
  • Decorator is designed to let you add responsibilities to objects without subclassing. Composite's focus is not on embellishment but on representation. These intents are distinct but complementary. Consequently, Composite and Decorator are often used in concert.
  • Composite could use Chain of Responsibility to let components access global properties through their parent. It could also use Decorator to override these properties on parts of the composition.
  • Decorator and Proxy have different purposes but similar structures. Both describe how to provide a level of indirection to another object, and the implementations keep a reference to the object to which they forward requests.
  • Decorator lets you change the skin of an object. Strategy lets you change the guts.
  • Decorator pattern is helpful in providing runtime modification abilities and hence more flexible. Its easy to maintain and extend when the number of choices are more.
  • The disadvantage of decorator pattern is that it uses a lot of similar kind of objects (decorators).
    ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์˜ ๋‹จ์ ์€ ์œ ์‚ฌํ•œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๊ฐ์ฒด๊ฐ€ ๋งŽ์•„์งˆ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค.
  • Decorator pattern is used a lot in Java IO classes, such as FileReader, BufferedReader etc.
    ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์€ FileReader๋‚˜ BufferedReader์™€ ๊ฐ™์€ Java IO ํด๋ž˜์Šค๋“ค์—์„œ ๋งŽ์ด ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋‹ค.

 

์ถœ์ฒ˜ :  http://sourcemaking.com/design_patterns/decorator

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

http://www.journaldev.com/1540/decorator-pattern-in-java-example-tutorial

 

 

 

์‹ค์ƒํ™œ์„ ์˜ˆ๋กœ ๋“  ์ข‹์€ ์˜ˆ์ œ๋Š” ์•„๋ž˜์—์„œ ํ™•์ธํ•˜๊ธฐ ๋ฐ”๋ž€๋‹ค.

http://warmz.tistory.com/757