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 ) :
패턴 사용의 장단점 ( 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.
추가 정보 :
출처 : 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
실생활을 예로 든 좋은 예제는 아래에서 확인하기 바란다.
[디자인패턴] 브리지 패턴 ( Bridge Pattern ) (0) | 2015.11.03 |
---|---|
[디자인패턴] 프록시 패턴 ( Proxy Pattern ) (0) | 2015.11.03 |
[디자인패턴] 어댑터 패턴 ( Adapter Pattern ) (0) | 2015.11.03 |
[디자인패턴] 책임전가 패턴 ( Chain of Responsibility Pattern ) (0) | 2015.11.03 |
[디자인패턴] 비지터(방문자) 패턴 ( Visitor Pattern ) (0) | 2015.11.03 |