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.

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

 

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

 

Factory Method Pattern Structure


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

 Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ ํŒจํ„ด์€ ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ •์˜ํ•˜๋Š”๋ฐ ์ด๋•Œ ์–ด๋–ค ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๊ฒƒ์ธ์ง€์— ๋Œ€ํ•œ ๊ฒฐ์ •๊ถŒ์€ ์„œ๋ธŒํด๋ž˜์Šค์—๊ฒŒ ์œ„์ž„ํ•œ๋‹ค. 

 

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


ํ”„ ๋ ˆ์ž„์›Œํฌ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์ถ”์ƒํด๋ž˜์Šค๋กœ ๊ฐ์ฒด ์‚ฌ์ด์˜ ๊ด€๊ณ„๋ฅผ ์ •์˜ํ•˜๋Š”๋ฐ, ์ข…์ข… ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•  ๋•Œ๋„ ์žˆ๋‹ค. ์•„๋ž˜ ๋‹ค์ด์–ด๊ทธ๋žจ์€ ๋‹ค์–‘ํ•œ ์ข…๋ฅ˜์˜ ๋ฌธ์„œ๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์˜ ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ์ด๋‹ค. ์•„๋ž˜ ๋‹ค์ด์–ด๊ทธ๋žจ์—์„œ ๊ด€๊ณ„๋ฅผ ๋งบ๊ณ  ์žˆ๋Š” ์ถ”์ƒํด๋ž˜์Šค๋“ค์€ Document์™€ Application์ด๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๊ทธ๋ฆผ๊ทธ๋ฆฌ๊ธฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค๋ ค๋ฉด ๋‘ ์ถ”์ƒํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์•„ DrawingApplication๊ณผ DrawingDocument ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•ด์•ผํ•˜๊ณ , Applicationํด๋ž˜์Šค๋Š” ํ•„์š”์—๋”ฐ๋ผ Document ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑ ํ˜น์€ ์—ด๊ธฐ๊ฐ€ ๊ฐ€๋Šฅํ•ด์•ผ ํ•œ๋‹ค. 

์ž, ๊ทธ๋Ÿฐ๋ฐ ๋ฌธ์ œ๋Š” ํŠน์ • ๋ฌธ์„œ๋Š” ํŠน์ • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์˜์กด์ ์ด๋ผ๋Š” ์ ์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, docx๋Š” ์›Œ๋“œ์—์„œ ์ƒ์„ฑํ•˜๋Š” ๋ฌธ์„œ์ด์ง€ ํ•œ๊ธ€์—์„œ ์ƒ์„ฑํ•˜๋Š” ๋ฌธ์„œ๊ฐ€ ์•„๋‹Œ ๊ฒƒ๊ณผ ๊ฐ™์€ ํ˜„์ƒ์ด๋ผ๊ณ  ๋ณด๋ฉด ๋œ๋‹ค. ๋”ฐ๋ผ์„œ Application์˜ CreateDocument()๋ฅผ ์ถ”์ƒ๋ฉ”์†Œ๋“œ๋กœ ์ •์˜ํ•˜๊ณ  ์ด๋ฅผ ์„œ๋ธŒํด๋ž˜์Šค์—์„œ ๊ตฌํ˜„ํ•˜๋„๋ก ํ•˜์—ฌ ๊ฐ๊ฐ์˜ Application๋งˆ๋‹ค ๊ฐ๊ฐ์˜ Document๋ฅผ ์ƒ์„ฑํ•˜๋„๋ก ํ•œ ๊ฒƒ์ด๋‹ค. ์ด๋•Œ CreateDocument()๋ฅผ ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. 

 

 

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

 Use the Factory Method pattern when


ยท a class can't anticipate the class of objects it must create.
ยท a class wants its subclasses to specify the objects it creates.
ยท classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate.


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

ยท Product (Document)
o defines the interface of objects the factory method creates.
ยท ConcreteProduct (MyDocument)
o implements the Product interface.
ยท Creator (Application)
o declares the factory method, which returns an object of type Product. Creator may also define a default implementation of the factory method that returns a default ConcreteProduct object.
o may call the factory method to create a Product object.
ยท ConcreteCreator (MyApplication)
o overrides the factory method to return an instance of a ConcreteProduct.


์›๋ฆฌ ( Collaborations ) :

ยท Creator relies on its subclasses to define the factory method so that it returns an instance of the appropriate ConcreteProduct.


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

 Factory methods eliminate the need to bind application-specific classes into your code. The code only deals with the Product interface; therefore it can work with any user-defined ConcreteProduct classes. A potential disadvantage of factory methods is that clients might have to subclass the Creator class just to create a particular ConcreteProduct object. Subclassing is fine when the client has to subclass the Creator class anyway, but otherwise the client now must deal with another point of evolution. 

 

Here are two additional consequences of the Factory Method pattern:


1. Provides hooks for subclasses. Creating objects inside a class with a factory method is always more flexible than creating an object directly. Factory Method gives subclasses a hook for providing an extended version of an object.
In the Document example, the Document class could define a factory method called CreateFileDialog that creates a default file dialog object for opening an existing document. A Document subclass can define an application-specific file dialog by overriding this factory method. In this  case the factory method is not abstract but provides a reasonable default implementation.


2. Connects parallel class hierarchies. In the examples we've considered so far, the factory method is only called by Creators. But this doesn't have to be the case; clients can find factory methods useful, especially in the case of parallel class hierarchies.
Parallel class hierarchies result when a class delegates some of its responsibilities to a separate class. Consider graphical figures that can be manipulated interactively; that is, they can be stretched, moved, or rotated using the mouse. Implementing such interactions isn't always easy.
It often requires storing and updating information that records the state of the manipulation at a given time. This state is needed only during manipulation; therefore it needn't be kept in the figure object. Moreover, different figures behave differently when the user manipulates them. For example, stretching a line figure might have the effect of moving an endpoint, whereas stretching a text figure may change its line spacing. With these constraints, it's better to use a separate Manipulator object that implements the interaction and keeps track of any manipulation-specific state that's needed. Different figures will use different Manipulator subclasses to handle particular interactions. The resulting Manipulator class hierarchy parallels (at least partially) the Figure class hierarchy:


The Figure class provides a CreateManipulator factory method that lets clients create a Figure's corresponding Manipulator. Figure subclasses override this method to return an instance of the Manipulator subclass that's right for them. Alternatively, the Figure class may implement CreateManipulator to return a default Manipulator instance, and Figure subclasses may simply inherit that default. The Figure classes that do so need no corresponding Manipulator subclassโ€”hence the hierarchies are only partially parallel.
Notice how the factory method defines the connection between the two class hierarchies. It localizes knowledge of which classes belong together.

 

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

 Abstract Factory is often implemented with factory methods. The Motivation example in the Abstract Factory pattern illustrates Factory Method as well.
Factory methods are usually called within Template Methods. In the document example above, NewDocument is a template method.
Prototypes don't require subclassing Creator. However, they often require an Initialize operation on the Product class. Creator uses Initialize to initialize the object. Factory Method doesn't require such an operation.

 

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

 
  • Abstract Factory classes are often implemented with Factory Methods, but they can be implemented using Prototype.
  • Factory Methods are usually called within Template Methods.
  • Factory Method: creation through inheritance. Prototype: creation through delegation.
  • Often, designs start out using Factory Method (less complicated, more customizable, subclasses proliferate) and evolve toward Abstract Factory, Prototype, 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.
  • The advantage of a Factory Method is that it can return the same instance multiple times, or can return a subclass rather than an object of that exact type.
  • Some Factory Method advocates recommend that as a matter of language design (or failing that, as a matter of style) absolutely all constructors should be private or protected. It's no one else's business whether a class manufactures a new object or recycles an old one.
  • The new operator considered harmful. There is a difference between requesting an object and creating one. The new operator always creates an object, and fails to encapsulate object creation. A Factory Method enforces that encapsulation, and allows an object to be requested without inextricable coupling to the act of creation.

 

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

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