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.

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

 

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

 

์ด ํŒจํ„ด์„ ์ ์šฉํ•ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

1. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์ƒ์„ฑ๋˜๋Š” ๊ฐ์ฒด์˜ ์ˆ˜๊ฐ€ ์—„์ฒญ๋‚˜๊ฒŒ ํด ๋•Œ

2. ๊ฐ์ฒด์˜ ์ƒ์„ฑ์ด ๋ฉ”๋ชจ๋ฆฌ์— ๋งŽ์€ ๋ถ€ํ•˜๋ฅผ ์ฃผ๊ณ  ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆด ๋•Œ


์ข€ ๋” ์ž์„ธํžˆ ์ด ํŒจํ„ด์— ๋Œ€ํ•ด์„œ ์งš์–ด๋ณด์ž.

 

Flyweight Pattern Structure

  


 
The following object diagram shows how flyweights are shared:

 

 


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

Use sharing to support large numbers of fine-grained objects efficiently.

ํ”Œ๋ผ์ด์›จ์ดํŠธ ํŒจํ„ด์€ ๋งŽ์€ ์ˆ˜์˜ ๊ฐ์ฒด๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ œ๊ณตํ•˜๊ธฐ์œ„ํ•ด ๊ณต์œ ๊ฐœ๋…์„ ์ด์šฉํ•œ๋‹ค.  

 

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

 Flyweight ํŒจํ„ด์€ ๋™์ผํ•œ ํด๋ž˜์Šค์— ๋Œ€ํ•œ ๋งŽ์€ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•  ๋•Œ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค. ๊ฐ ๊ฐ์ฒด๋งˆ๋‹ค ๋ฉ”๋ชจ๋ฆฌ์™€ ๊ณต๊ฐ„์„ ์žก์•„๋จน๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์–‘์ด ๋‚ฎ์€ ์ปดํ“จํ„ฐ๋‚˜ ๋ชจ๋ฐ”์ผ ๊ธฐ๊ธฐ์—์„œ๋Š” ๋ฉ”๋ชจ๋ฆฌ์™€ ๊ณต๊ฐ„์— ๋Œ€ํ•œ ์ œ์•ฝ์„ ํ”ผํ•  ์ˆ˜ ์—†๋Š”๋ฐ ๋งŒ์•ฝ ๋‚ด๊ฐ€ ๋งŒ๋“œ๋Š” ํ”„๋กœ๊ทธ๋žจ์ด ์—„์ฒญ ๋งŽ์€ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค๋ฉด ์ด ํŒจํ„ด์„ ๊ณต๋ถ€ํ•ด์„œ ์ ์šฉํ•ด๋ณด๊ธฐ ๋ฐ”๋ž€๋‹ค. ํ”Œ๋ผ์ด์›จ์ดํŠธ ํŒจํ„ด์€ ๊ฐ์ฒด๋ฅผ ๊ณต์œ ํ•จ์œผ๋กœ์จ ๋ฉ”๋ชจ๋ฆฌ ๋ถ€ํ•˜๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. 


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

The Flyweight pattern's effectiveness depends heavily on how and where it's used.

ํ”Œ๋ผ์ด์›จ์ดํŠธ ํŒจํ„ด์˜ ํšจ๊ณผ๋Š” ์–ด๋–ป๊ฒŒ ์–ด๋””์„œ ์‚ฌ์šฉ๋˜๋Š๋ƒ์— ๋”ฐ๋ผ ์‹ฌํ•˜๊ฒŒ ์ขŒ์ง€์šฐ์ง€ ๋œ๋‹ค.


Apply the Flyweight pattern when all of the following are true:

์•„๋ž˜ ๋‚ด์šฉ๊ณผ ๋ชจ๋‘ ๋งž์•„ ๋–จ์–ด์ง€๋Š” ์ƒํ™ฉ์—์„œ๋งŒ ์ด ํŒจํ„ด์„ ์ ์šฉํ•˜๋ฉด ๋œ๋‹ค.


ยท An application uses a large number of objects.

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ •๋ง ๋งŽ์€ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ
ยท Storage costs are high because of the sheer quantity of objects.

์ €์žฅ๋น„์šฉ์ด ๋†’์„ ๋•Œ( ๊ฐ์ฒด ๊ฐœ์ˆ˜๊ฐ€ ๋งŽ์•„์„œ )
ยท Most object state can be made extrinsic.

๋Œ€๋ถ€๋ถ„์˜ ๊ฐ์ฒด์˜ ์ƒํƒœ๊ฐ€ ๋ถ€๋Œ€์ ์ธ ๊ฒƒ์ผ ๋•Œ
ยท Many groups of objects may be replaced by relatively few shared objects once extrinsic state is removed.

๋ถ€๋Œ€์ ์ธ ์ƒํƒœ๊ฐ€ ์ œ๊ฑฐ๋์„ ๋•Œ์—๋Š” ์ ์€ ์ˆ˜์˜ ๊ณต์œ  ๊ฐ์ฒด๋กœ ๋งŽ์€ ์ˆ˜์˜ ๊ฐ์ฒด๋ฅผ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ์„ ๋•Œ
ยท The application doesn't depend on object identity. Since flyweight objects may be shared, identity tests will return true for conceptually distinct objects.

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๊ฐ์ฒด์˜ identity์— ์˜์กด์ ์ด์ง€ ์•Š์„ ๋•Œ 


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

ยท Flyweight
o declares an interface through which flyweights can receive and act
on extrinsic state.
ยท ConcreteFlyweight (Character)
o implements the Flyweight interface and adds storage for intrinsic state, if any. A ConcreteFlyweight object must be sharable. Any state it stores must be intrinsic; that is, it must be independent of the ConcreteFlyweight object's context.
ยท UnsharedConcreteFlyweight (Row, Column)
o not all Flyweight subclasses need to be shared. The Flyweight interface enables sharing; it doesn't enforce it. It's common for
UnsharedConcreteFlyweight objects to have ConcreteFlyweight objects as children at some level in the flyweight object structure
(as the Row and Column classes have).
ยท FlyweightFactory
o creates and manages flyweight objects.
o ensures that flyweights are shared properly. When a client requests a flyweight, the FlyweightFactory object supplies an existing
instance or creates one, if none exists.  

ยท Client
o maintains a reference to flyweight(s).
o computes or stores the extrinsic state of flyweight(s).


์›๋ฆฌ ( Collaborations ) :

ยท State that a flyweight needs to function must be characterized as either intrinsic or extrinsic. Intrinsic state is stored in the ConcreteFlyweight object; extrinsic state is stored or computed by Client objects. Clients pass this state to the flyweight when they invoke its operations.
ยท Clients should not instantiate ConcreteFlyweights directly. Clients must obtain ConcreteFlyweight objects exclusively from the FlyweightFactory object to ensure they are shared properly.


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

 
Flyweights may introduce run-time costs associated with transferring, finding, and/or computing extrinsic state, especially if it was formerly stored as intrinsic state. However, such costs are offset by space savings, which increase as more
flyweights are shared.


Storage savings are a function of several factors:


ยท the reduction in the total number of instances that comes from sharing
ยท the amount of intrinsic state per object
ยท whether extrinsic state is computed or stored.


The more flyweights are shared, the greater the storage savings. The savings increase with the amount of shared state. The greatest savings occur when the objects use substantial quantities of both intrinsic and extrinsic state, and the extrinsic state can be computed rather than stored. Then you save on storage in two ways: Sharing reduces the cost of intrinsic state, and you trade extrinsic state for computation time.
The Flyweight pattern is often combined with the Composite (183) pattern to represent a hierarchical structure as a graph with shared leaf nodes. A consequence of sharing is that flyweight leaf nodes cannot store a pointer to their parent. Rather, the parent pointer is passed to the flyweight as part of its extrinsic state. This has a major impact on how the objects in the hierarchy  communicate with each other. 

 

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

The Flyweight pattern is often combined with the Composite pattern to implement a logically hierarchical structure in terms of a directed-acyclic graph with shared leaf nodes.

It's often best to implement State and Strategy objects as flyweights. 


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

  • Whereas Flyweight shows how to make lots of little objects, Facade shows how to make a single object represent an entire subsystem.
  • Flyweight is often combined with Composite to implement shared leaf nodes.
  • Terminal symbols within Interpreter's abstract syntax tree can be shared with Flyweight.
  • Flyweight explains when and how State objects can be shared.
  • Flyweight pattern introduces complexity and if number of shared objects are huge then there is a trade of between memory and time, so we need to use it judiciously based on our requirements.
  • Flyweight pattern implementation is not useful when the number of intrinsic properties of Object is huge, making implementation of Factory class complex.

 

 

 

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

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

http://www.journaldev.com/1562/flyweight-pattern-in-java-example-tutorial