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.
์ด ํจํด๋ค์ ๊ฐ์ฒด๋ค ์ฌ์ด์ ์ปค๋ฎค๋์ผ์ด์ ์ ๊ด์ฌ์ ๊ฐ์ง๋ค.
์ค๋ ์ดํด๋ณผ Facade ํจํด์ Structural ํจํด์ ์ํ๋ค. ์ด ํจํด์ ์ปดํฌ์งํธ ํจํด๊ณผ ๋น์ทํ ๋ค์ด์ด๊ทธ๋จ์ ๊ฐ์ง๊ณ ์๋ค.
Facade๋ ํผ์ฌ๋๋ผ๊ณ ์ฝ๋๋ค. ํผ์ผ์ด๋, ํจ์ผ์ด๋ ์ด๋ด์์ผ๋ก ์ฝ๋๊ฒ ์๋๋ค.
Facade Pattern Structure
ํจํด์ ๋ชฉ์ ( Intent ) :
Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.
ํผ์ฌ๋ ํจํด์ ์๋ธ์์คํ ๋ด๋ถ์ ์๋ ํด๋์ค์ ์ ๊ทผํ ์ ์๋ ํ๋์ ํตํฉ๋ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๋ ํจํด์ด๋ค.
ํจํด์ด ๋์ค๊ฒ ๋ ๋๊ธฐ ( Motivation ) :
ํฐ ์์คํ ์ ์์ ์์คํ ์ผ๋ก ๋๋๋ ๊ฒ์ ์์คํ ์ ๋ณต์ก๋๋ฅผ ๋ฎ์ถฐ์ค๋ค. ๊ทธ๋ฆฌ๊ณ ๋์์ธ์ ๊ณตํต ๋ชฉํ๋ ์๋ธ์์คํ ๋ค ์ฌ์ด์ ์์กด์ฑ์ ์ค์ด๊ณ ์ปค๋ฎค๋์ผ์ด์ ํ์๋ฅผ ์ค์ด๋ ๊ฒ์ธ๋ฐ ํผ์ฌ๋ ํจํด์ด ์ด๋ฅผ ์ํ ๋ฐฉ๋ฒ์ค ํ๋์ด๋ค. ์๋ ๊ทธ๋ฆผ์์ ์ปค๋ค๋ ์ฌ๊ฐํ์ด ์๋ธ์์คํ ์ด๊ณ ๊ทธ ์์ ์์ ์ฌ๊ฐํ๋ค์ ์๋ธ์์คํ ์ ํด๋์ค๋ค์ ์๋ฏธํ๋ค. ๊ทธ๋ฆฌ๊ณ ์๋ธ์์คํ ๋ฐ์๋ ํด๋ผ์ด์ธํธ๊ฐ ์๋ธ์์คํ ์ ์ ๊ทผํ ๋ ์ฌ์ฉ๋๋ ํด๋์ค๋ค์ด ์๋ค.
๊ทธ๋ฐ๋ฐ ์ผ์ชฝ ๊ทธ๋ฆผ์ ๋ณด๋ฉด ์๋ธ์์คํ ์ ์ ๊ทผํ๊ธฐ ์ํด์ ํด๋ผ์ด์ธํธ ํด๋์ค๊ฐ ์ง์ ์ ์ผ๋ก ์๋ธ์์คํ ๋ด๋ถ์ ํด๋์ค๋ฅผ ํธ์ถํ๋ ๋ฐฉ์์ด๋ค. ๊ทธ๋ฆผ์ผ๋ก๋ด๋ ๋ญ๊ฐ ๋ณต์กํด ๋ณด์ธ๋ค. ์๋ธ์์คํ ์ด ๋ณ๊ฒฝ๋๋ฉด?? ํด๋ผ์ด์ธํธ ์ชฝ์์๋ ์์ ํด์ผํ๋ ๋ถ๋ถ์ด ์๊ธธ ๊ฒ์ด๊ณ ํฐ ํ๋ก์ ํธ์๋ค๋ฉด ์ด๋๋ฅผ ์์ ํด์ผ ํ ์ง ์ฐพ์๋ด๊ธฐ๋ ํ๋ค๊ฒ์ด๋ค. ๊ทธ๋์ ์ด๋ฅผ ํผ์ฌ๋ ํจํด์ ์ ์ฉํด์ ๋ฐ๊พธ๋ฉด ์ค๋ฅธ์ชฝ๊ณผ ๊ฐ์ ๊ทธ๋ฆผ์ด ๋์จ๋ค. ํด๋ผ์ด์ธํธ ํด๋์ค๋ค์ด ํผ์ฌ๋๋ฅผ ํตํด์ ์๋ธ์์คํ ์ ์ ๊ทผํ๋๋ก ํ ๊ฒ์ด๋ค. ์ด๋ ๊ผญ ํผ์ฌ๋๋ฅผ ํตํด์๋ง ์๋ธ์์คํ ์ ์ ๊ทผํ ์ ์์ด์ผ ํ๋ค๋ ๊ฒ์ ์๋๋ค. ๋จ์ง ํผ์ฌ๋๋ฅผ ํตํด์ ์๋ธ์์คํ ์ ์ ๊ทผํ ์ ์๋๋ก ๊ธธ์ ์ด๊ณ ๊ทธ๋ ๊ฒ ์ ๋๋ง ํ๋ ๊ฒ์ด๋ค. ๊ฐ์ ์ฑ์ด ์๋ค๋ ๋ป์ด๋ค.
์ด ํจํด์ ์ฌ์ฉํ๋ ๋ํ์ ์ธ ์๊ฐ ์ปดํ์ผ๋ฌ์ด๋ค. ์ปดํ์ผ๋ฌ๋ ์๋์ ๊ฐ์ด ๊ตฌํ๋๋ค.
์ ์ฉ์ฑ ( Applicability ) :
Use the Facade pattern when
ยท you want to provide a simple interface to a complex subsystem.
Subsystems often get more complex as they evolve. Most patterns, when
applied, result in more and smaller classes. This makes the subsystem
more reusable and easier to customize, but it also becomes harder to use
for clients that don't need to customize it. A facade can provide a
simple default view of the subsystem that is good enough for most
clients. Only clients needing more customizability will need to look
beyond the facade.
๋ณต์กํ ์๋ธ์์คํ
์ ์ ๊ทผํ ์ ์๋ ๊ฐ๋จํ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๊ณ ์ถ์ ๋ ์ฌ์ฉ
ยท there are many dependencies between clients and the implementation classes of an abstraction. Introduce a facade to decouple the subsystem from clients and other subsystems, thereby promoting subsystem independence and portability.
์๋ธ์์คํ ์ ํด๋ผ์ด์ธํธ ๋๋ ๋ค๋ฅธ ์๋ธ์์คํ ์ผ๋ก๋ถํฐ ๋์ปคํ์ํด์ผ๋ก์จ ๋ ๋ฆฝ์ฑ๊ณผ ํด๋์ฑ(์ด์์ฑ)์ ๋์ด๊ธฐ ์ํด์ ์ฌ์ฉ
ยท you want to layer your subsystems.
Use a facade to define an entry point to each subsystem level. If
subsystems are dependent, then you can simplify the dependencies between
them by making them communicate with each other solely through their
facades.
๋ฑ์ฅ ์ธ๋ฌผ ( Participants ) :
o knows which subsystem classes are responsible for a request.
o delegates client requests to appropriate subsystem objects.
ยท subsystem classes (Scanner, Parser, ProgramNode, etc.)
o implement subsystem functionality.
o handle work assigned by the Facade object.
o have no knowledge of the facade; that is, they keep no references to it.
์๋ฆฌ ( Collaborations ) :
ยท Clients communicate with the subsystem by sending requests to Facade, which forwards them to the appropriate subsystem object(s). Although the subsystem objects perform the actual work, the facade may have to do work of its own to translate its interface to subsystem interfaces.
ํด๋ผ์ด์ธํธ๋ ํผ์ฌ๋์ ์์ฒญ์ ํจ์ผ๋ก์จ ๋ณต์กํ ์๋ธ์์คํ
์ ์ ๊ทผํ๋ค.
ยท Clients that use the facade don't have to access its subsystem objects directly.
ํด๋ผ์ด์ธํธ๋ ๋ณต์กํ ์๋ธ์์คํ ์ ๊ฐ์ฒด์ ์ง์ ์ ์ผ๋ก ์ ๊ทผํ ํ์๊ฐ ์๋ค.
ํจํด ์ฌ์ฉ์ ์ฅ๋จ์ ( Consequences ):
The Facade pattern offers the following benefits:
1. It shields clients from subsystem components, thereby reducing the number of objects that clients deal with and making the subsystem easier to use. ์ฌ์ฉ์๊ฐ ์์์ผ ํ๋ ์๋ธ์์คํ
์ ๋ฒ์๋ฅผ ์ค์ฌ์ค๋ค.
2. It promotes weak coupling between the subsystem and its clients. 1๋ฒ์ ์ด์ ๋ก ์ฌ์ฉ์์ ์๋ธ์์คํ
์ฌ์ด์ ์ปคํ๋ง ๊ด๊ณ๋ฅผ ์ฝํ์์ผ์ค๋ค. Often
the components in a subsystem are strongly coupled. Weak coupling lets
you vary the components of the subsystem without affecting its clients.
Facades help layer a system and the dependencies between objects. They
can eliminate complex or circular dependencies. This can be an important
consequence when the client and the subsystem are implemented
independently. Reducing compilation dependencies is vital in large
software systems. You want to save time by minimizing recompilation when
subsystem classes change. Reducing compilation dependencies with
facades can limit the recompilation needed for a small change in an
important subsystem. A facade can also simplify porting systems to other
platforms, because it's less likely that building one subsystem
requires building all others.
3. It doesn't prevent applications from using subsystem classes if they need to. ์ฌ์ฉ์๊ฐ ์ํ ๋์๋ ์๋ธ์์คํ
์ ์ง์ ์ ๊ทผํ์ฌ ๋ด๋ถ ํด๋์ค๋ฅผ ์ฌ์ฉํ ์ ์๋ค.Thus you can choose between ease of use and generality.
๊ด๋ จ ํจํด๋ค :
Abstract Factory can
be used with Facade to provide an interface for creating subsystem
objects in a subsystem-independent way. Abstract Factory can also be
used as an alternative to Facade to hide platform-specific classes.
Mediator is
similar to Facade in that it abstracts functionality of existing
classes. However, Mediator's purpose is to abstract arbitrary
communication between colleague objects, often centralizing
functionality that doesn't belong in any one of them. A mediator's
colleagues are aware of and communicate with the mediator instead of
communicating with each other directly. In contrast, a facade merely
abstracts the interface to subsystem objects to make them easier to use;
it doesn't define new functionality, and subsystem classes don't know
about it.
Usually only one Facade object is required. Thus Facade objects are often Singletons.
์ถ๊ฐ ์ ๋ณด :
- Facade defines a new interface, whereas Adapter uses an old interface. Remember that Adapter makes two existing interfaces work together as opposed to defining an entirely new one.
- Whereas Flyweight shows how to make lots of little objects, Facade shows how to make a single object represent an entire subsystem.
- Mediator is similar to Facade in that it abstracts functionality of existing classes. Mediator abstracts/centralizes arbitrary communications between colleague objects. It routinely "adds value", and it is known/referenced by the colleague objects. In contrast, Facade defines a simpler interface to a subsystem, it doesn't add new functionality, and it is not known by the subsystem classes.
- Abstract Factory can be used as an alternative to Facade to hide platform-specific classes.
- Facade objects are often Singletons because only one Facade object is required.
- Adapter and Facade are both wrappers; but they are different kinds of wrappers. The intent of Facade is to produce a simpler interface, and the intent of Adapter is to design to an existing interface. While Facade routinely wraps multiple objects and Adapter wraps a single object; Facade could front-end a single complex object and Adapter could wrap several legacy objects.
- Facade pattern is more like a helper for client applications, it doesnโt hide subsystem interfaces from the client. Whether to use Facade or not is completely dependent on client code.
- Facade pattern can be applied at any point of development, usually when the number of interfaces grow and system gets complex.
- Subsystem interfaces are not aware of Facade and they shouldnโt have any reference of the Facade interface.
- Facade pattern should be applied for similar kind of interfaces, its purpose is to provide a single interface rather than multiple interfaces that does the similar kind of jobs.
- We can use Factory Pattern with Facade to provide better interface to client systems.
์ด๋ํฐ ํจํด๊ณผ ํผ์ฌ๋ ํจํด์ ์ฐจ์ด์ ์ ์ผ๋ง๋ ๋ง์ ํด๋์ค๋ฅผ wrapํ๋๋๊ฐ ์๋๋ค. Adapter ํจํด์ ํ๋ ์ด์์ ํด๋์ค๋ฅผ ๋ฌถ์ด์ ํด๋ผ์ด์ธํธ๊ฐ ์ํ๋ ์ถ๋ ฅ์ด ๋์ค๋๋ก ํ๋ ๊ฒ์ด๊ณ Facade ํจํด์ ํด๋ผ์ด์ธํธ๊ฐ ์ฌ์ฉํ๊ธฐ์๋ ๋ณต์กํ ์ธํฐํ์ด์ค๋ฅผ ํ๋๋ก ๋ฌถ๊ณ ๊ฐ๋จํ ์ ๊ทผ๊ฒฝ๋ก๋ฅผ ์ ๊ณตํจ์ผ๋ก์จ ํด๋ผ์ด์ธํธ๊ฐ ์์ฝ๊ฒ ๋ณต์กํ ์ธํฐํ์ด์ค ๋ด๋ถ์ ๊ธฐ๋ฅ์ ํ์ฉํ ์ ์๋๋ก ํ๋ ๊ฒ์ด๋ค.
์ถ์ฒ : http://sourcemaking.com/design_patterns/facade
Design Patterns : Element of Reusable Object Oriented Software ( by GoF, 1994 )
http://www.journaldev.com/1557/facade-pattern-in-java-example-tutorial
'๐ป Programming > GoF Design Pattern' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[๋์์ธํจํด] ์ปค๋งจ๋ ํจํด ( Command Pattern ) (0) | 2015.11.03 |
---|---|
[๋์์ธํจํด] ์ปดํฌ์งํธ ํจํด ( Composite Pattern ) (0) | 2015.11.03 |
[๋์์ธํจํด] ๋ธ๋ฆฌ์ง ํจํด ( Bridge Pattern ) (0) | 2015.11.03 |
[๋์์ธํจํด] ํ๋ก์ ํจํด ( Proxy Pattern ) (0) | 2015.11.03 |
[๋์์ธํจํด] ๋ฐ์ฝ๋ ์ดํฐ ํจํด ( Decorator Pattern ) (0) | 2015.11.03 |