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.

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

 

์˜ค๋Š˜ ์‚ดํŽด๋ณผ  Prototype ํŒจํ„ด์€ Creational ํŒจํ„ด์— ์†ํ•œ๋‹ค.  

 

Prototype Pattern Structure



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

- Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype. 

ํ•˜๋‚˜์˜ ํ”„๋กœํ† ํƒ€์ž… ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค๊ณ  ํ•„์š”ํ• ๋•Œ๋งˆ๋‹ค ํ”„๋กœํ† ํƒ€์ž… ์ธ์Šคํ„ด์Šค๋ฅผ ๋ณต์‚ฌํ•ด์„œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•จ 

- Co-opt one instance of a class for use as a breeder of all future instances. 

- The new operator considered harmful.

new ํ‚ค์›Œ๋“œ๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด ์•ˆ์ข‹์€ ์ƒํ™ฉ์ผ ๋•Œ ํ”„๋กœํ† ํƒ€์ž… ํŒจํ„ด์„ ์ด์šฉํ•˜์ž. 

 

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

 

๊ฐ์ฒด ์ƒ์„ฑ ๋น„์šฉ์ด ๋น„์‹ผ๊ฒฝ์šฐ ํ”„๋กœํ† ํƒ€์ž… ์›ํ˜•์„ ๋งŒ๋“ค๊ณ  ํด๋กœ๋‹ ๊ธฐ๋ฒ•์„ ์ด์šฉํ•ด์„œ ๊ฐ์ฒด๋ฅผ ์‰ฝ๊ฒŒ ์ƒ์„ฑํ•˜๊ณ ์ž ํ•˜๊ธฐ ์œ„ํ•จ.


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

Use the Prototype pattern when a system should be independent of how its products are created, composed, and represented; and
ยท when the classes to instantiate are specified at run-time, for example, by dynamic loading; or

ํด๋ž˜์Šค์˜ ๋™์ ๋กœ๋”ฉ์ด ํ•„์š”ํ•  ๋•Œ
ยท to avoid building a class hierarchy of factories that parallels the class hierarchy of products; or

์ œํ’ˆ์˜ ํด๋ž˜์Šค ๊ณ„์ธต๊ณผ ๋™์ผํ•œ ํŒฉํ† ๋ฆฌ ํด๋ž˜์Šค ๊ณ„์ธต์„ ๋งŒ๋“ค๊ณ  ์‹ถ์ง€ ์•Š์„ ๋•Œ
ยท when instances of a class can have one of only a few different combinations of state. It may be more convenient to install a corresponding number of prototypes and clone them rather than instantiating the class manually, each time with the appropriate state.

 

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

ยท Prototype
o declares an interface for cloning itself.
ยท ConcretePrototype
o implements an operation for cloning itself.
ยท Client
o creates a new object by asking a prototype to clone itself. 


์›๋ฆฌ ( Collaborations ) :

ยท A client asks a prototype to clone itself.


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

Prototype has many of the same consequences that Abstract Factory and Builder have: It hides the concrete product classes from the client, thereby reducing the number of names clients know about. Moreover, these patterns let a client work with application-specific classes without modification.


Additional benefits of the Prototype pattern are listed below.


1. Adding and removing products at run-time. Prototypes let you incorporate a new concrete product class into a system simply by registering a prototypical instance with the client. That's a bit more flexible than other creational patterns, because a client can install and remove prototypes at run-time.


2. Specifying new objects by varying values. Highly dynamic systems let you define new behavior through object compositionโ€”by specifying values for an object's variables, for exampleโ€”and not by defining new classes. You effectively define new kinds of objects by instantiating existing classes and registering the instances as prototypes of client objects. A client can exhibit new behavior by delegating responsibility to the prototype. This kind of design lets users define new "classes" without programming. In fact, cloning a prototype is similar to instantiating a class. The Prototype pattern can greatly reduce the number of classes a system needs. In our music editor, one GraphicTool class can create a limitless variety of music objects.


3. Specifying new objects by varying structure. Many applications build objects from parts and subparts. Editors for circuit design, for example, build circuits out of subcircuits.1 For convenience, such applications often let you instantiate complex, user-defined structures, say, to use a specific subcircuit again and again. The Prototype pattern supports this as well. We simply add this subcircuit as a prototype to the palette of available circuit elements. As long as the composite circuit object implements Clone as a deep copy, circuits with different structures can be prototypes.  

 

4. Reduced subclassing. Factory Method often produces a hierarchy of Creator classes that parallels the product class hierarchy. The Prototype pattern lets you clone a prototype instead of asking a factory method to make a new object. Hence you don't need a Creator class hierarchy at all. This benefit applies primarily to languages like C++ that don't treat classes as first-class objects. Languages that do, like Smalltalk and Objective C, derive less benefit, since you can always use a class object as a creator. Class objects already act like prototypes in these languages.


5. Configuring an application with classes dynamically. Some run-time environments let you load classes into an application dynamically. The Prototype pattern is the key to exploiting such facilities in a language like C++. An application that wants to create instances of a dynamically loaded class won't be able to reference its constructor statically. Instead, the run-time environment creates an instance of each class automatically when it's loaded, and it registers the instance with a prototype manager (see the
Implementation section). Then the application can ask the prototype manager for instances of newly loaded classes, classes that weren't linked with the program originally. The ET++ application framework [WGM88] has a run-time system that uses this scheme.
The main liability of the Prototype pattern is that each subclass of Prototype must implement the Clone operation, which may be difficult. For example, adding Clone is difficult when the classes under consideration already exist. Implementing Clone can be difficult when their internals include objects that don't support copying or have circular references.

 

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

 Prototype and Abstract Factory are competing patterns in some ways, as we discuss at the end of this chapter. They can also be used together, however. An Abstract Factory might store a set of prototypes from which to clone and return product objects.
Designs that make heavy use of the Composite and Decorator patterns often can benefit from Prototype as well.

 

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

  • Sometimes creational patterns are competitors: there are cases when either Prototype or Abstract Factory could be used properly. At other times they are complementory: Abstract Factory might store a set of Prototypes from which to clone and return product objects. Abstract Factory, Builder, and Prototype can use Singleton in their implementations.
  • Abstract Factory classes are often implemented with Factory Methods, but they can be implemented using Prototype.
  • Factory Method: creation through inheritance. Protoype: creation through delegation.
  • Often, designs start out using Factory Method (less complicated, more customizable, subclasses proliferate) and evolve toward Abstract Factory, Protoype, or Builder (more flexible, more complex) as the designer discovers where more flexibility is needed.
  • Prototype doesn't require subclassing, but it does require an "initialize" operation. Factory Method requires subclassing, but doesn't require Initialize.
  • Designs that make heavy use of the Composite and Decorator patterns often can benefit from Prototype as well.
  • Prototype co-opts one instance of a class for use as a breeder of all future instances.
  • Prototypes are useful when object initialization is expensive, and you anticipate few variations on the initialization parameters. In this context, Prototype can avoid expensive "creation from scratch", and support cheap cloning of a pre-initialized prototype.
  • Prototype is unique among the other creational patterns in that it doesn't require a class โ€“ only an object. Object-oriented languages like Self and Omega that do away with classes completely rely on prototypes for creating new objects.

 

 

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

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