o d for agile software development - hhko.tistory.comhhko.tistory.com/attachment/ek010000000000.pdf1...
Post on 13-Mar-2018
242 Views
Preview:
TRANSCRIPT
1
OObjectbject--OOrientedriented DDesignesign
for for AgileAgile Software DevelopmentSoftware Development
Story 11.Story 11.
작 성 자 : 고형호
메 일 : hyungho.ko@gmail.com
홈 페 이 지 : http://www.innosigma.com
최초 작성일 : 2007.11.13
최종 작성일 : 2007.11.30
2
http
://w
ww
.inn
osig
ma.
com
Goal
Create objects without knowing exactlywhat that type is.
3
http
://w
ww
.inn
osig
ma.
com
Contents
3. Clone
5. Design Pattern
6. Class Diagram in Practice
7. Design Pattern in Practice
8. Summary
2. Concrete Factory Integration
1. Customer Requirement
4. Prototype Manager
4
1. Customer Requirement
5
http
://w
ww
.inn
osig
ma.
com
Customer Requirement
요구사항 : Line 도형을 그린다.
HOW(세부 구현, 변화하는 것)
WHAT(외부와의 계약, 변화하지 않는 것)
철저히 은닉되어야 한다.
HOW(세부 구현, 변화하는 것)
WHAT(외부와의 계약, 변화하지 않는 것)
철저히 은닉되어야 한다.
추가 요구사항 : Line 도형을 생성한다.
6
http
://w
ww
.inn
osig
ma.
com
요구사항WHAT
HOW : Line 도형
: 그리기 WHAT
HOW : Line 도형
: 생성
Abstract Factory Pattern구현
Abstract Factory
Abstract Factory
Concrete Factory Concrete Product
Abstract Product
그리기WHAT
생성WHAT
LineHOW
LineHOW
LineFactory
+Create() : IShape*
RectangleFactory
+Create() : IShape*
<<interface>>IShapeFactory
+Create() : IShape*
LineShape
+Draw(const Graphics&)
RectangleShape
+Draw(const Graphics&)
<<interface>>IShape
+Draw(const Graphics&)
<<create>>
Customer Requirement
7
http
://w
ww
.inn
osig
ma.
com
LineFactory
+Create() : IShape*
RectangleFactory
+Create() : IShape*
<<interface>>IShapeFactory
+Create() : IShape*
LineShape
+Draw(const Graphics&)
RectangleShape
+Draw(const Graphics&)
<<interface>>IShape
+Draw(const Graphics&)
<<create>>
-. 원인: “Concrete Factory : Concrete Product = 1 : 1” 관계이다.
Concrete Factory Concrete Product
-. 해결책: “Concrete Factory : Concrete Product = 1 : N” 관계를 구성한다.
-. 문제점: 새로운 Concrete Product가 추가되면 이를 생성하기 위한 Concrete Factory 또한 추가되어야 한다.
(LineShape) (LineFactory)
그러므로, 런타임 시점에 System 수정 없이 새로운 Concrete Project을 추가 생성할 수 없다.(Ex. Composite Pattern을 통해 조합된 새로운 Shape)
Customer Requirement
즉, Concrete Factory를 하나로 통합 시킨다.
8
2. Concrete Factory Integration
9
http
://w
ww
.inn
osig
ma.
com
LineFactory
+Create() : IShape*
RectangleFactory
+Create() : IShape*
<<interface>>IShapeFactory
+Create() : IShape*
LineShape
+Draw(const Graphics&)
RectangleShape
+Draw(const Graphics&)
<<interface>>IShape
+Draw(const Graphics&)
Concrete Factory통합
<<create>>
ShapeFactory
+Create(Shape_식별자_타입) : IShape*
<<interface>>IShapeFactory
+Create() : IShape*
LineShape
+Draw(const Graphics&)
RectangleShape
+Draw(const Graphics&)
<<interface>>IShape
+Draw(const Graphics&)
<<create>>
Concrete Factory Integration
10
http
://w
ww
.inn
osig
ma.
com
Class 계층구조단순화
ShapeFactory
+Create(Shape_식별자_타입) : IShape*
<<interface>>IShapeFactory
+Create() : IShape*
LineShape
+Draw(const Graphics&)
RectangleShape
+Draw(const Graphics&)
<<interface>>IShape
+Draw(const Graphics&)
<<create>>
ShapeFactory
+Create(Shape_식별자_타입) : IShape*
LineShape
+Draw(const Graphics&)
RectangleShape
+Draw(const Graphics&)
<<interface>>IShape
+Draw(const Graphics&)
<<create>>
Concrete Factory Integration
Concrete Factory가 더 이상 추가되지 않으므로 IShapeFactory 인터페이스 역할이 약화된다.(Concrete Factory가 하나로 통합되므로 인해)
Concrete Factory
11
http
://w
ww
.inn
osig
ma.
com
ShapeFactory 세부 구현
ShapeFactory
+Create(Shape_식별자_타입) : IShape*
LineShape
+Draw(const Graphics&)
RectangleShape
+Draw(const Graphics&)
<<interface>>IShape
+Draw(const Graphics&)
<<create>>
class ShapeFactory {public:
IShape* Create(Shape_식별자_타입 식별자){
switch(식별자) {
case Rectangle : return new RectangleShape;
case Line :return new LineShape;
...}return NULL;
}};
Concrete Factory Integration
12
http
://w
ww
.inn
osig
ma.
com
class ShapeFactory {public:
IShape* Create(Shape_식별자_타입 식별자){
switch(식별자) {
case Rectangle : return new RectangleShape;
case Line :return new LineShape;
...}return NULL;
}};
-. 문제점: 새로운 Shape이 추가되면 Switch 구문 수정은 불가피 하다.
-. 원인: 객체를 생성할 시점에서 생성할 객체의 자료형을 판별한다.
-. 해결책: 생성할 객체의 자료형을 이전에 결정한다.
기존 객체를 복제하여 새로운 객체를 생성한다.
Why ? 복제된 객체는 기존 객체와 동일한 자료형을 가질 것이기 때문이다.
Concrete Factory Integration
결론
13
3. Clone
14
http
://w
ww
.inn
osig
ma.
com
ShapeFactory
+Create(Shape_식별자_타입) : IShape*
LineShape
+Draw(const Graphics&)
RectangleShape
+Draw(const Graphics&)
<<interface>>IShape
+Draw(const Graphics&)
<<create>>
ShapeFactory
+Create(IShape*) : IShape*
LineShape
+Draw(const Graphics&)+Clone() : IShape*
RectangleShape
+Draw(const Graphics&)+Clone() : IShape*
<<interface>>IShape
+Draw(const Graphics&)+Clone() : IShape*
<<create>>
복제구현
Clone
15
http
://w
ww
.inn
osig
ma.
com
ShapeFactory
+Create(IShape*) : IShape*
<<create>>
class ShapeFactory {public:
IShape* Create(IShape* pShape){
return pShape->Clone();}
};
미리 생성된 객체
복제하여 생성한다.
추가 요구사항 : 미리 생성된 객체를 관리한다.
Clone
LineShape
+Draw(const Graphics&)+Clone() : IShape*
RectangleShape
+Draw(const Graphics&)+Clone() : IShape*
<<interface>>IShape
+Draw(const Graphics&)+Clone() : IShape*
16
4. Prototype Manager
17
http
://w
ww
.inn
osig
ma.
com
요구사항 : 미리 생성된 객체를 관리한다.
HOW(세부 구현, 변화하는 것)
WHAT(외부와의 계약, 변화하지 않는 것)
철저히 은닉되어야 한다.
Prototype Manager
18
http
://w
ww
.inn
osig
ma.
com
요구사항WHAT
HOW : 미리 생성된 객체
: 관리
OOD 원칙구현
미리 생성된 객체HOW
(세부 구현, 변화하는 것)
관리WHAT
(외부와의 계약, 변화하지 않는 것)
Prototype Manager
<<interface>>IPrototypeManager
+Add(IShape) : int+Remove(int)+GetPrototype(int) : IShape*
PrototypeManager
+Add(IShape) : int+Remove(int)+GetPrototype(int) : IShape*
-m_mapFactory : map<int, IShape*>-m_nMagicID : int
SRP
OCP(LSP)LineShape
+Draw(const Graphics&)+Clone() : IShape*
RectangleShape
+Draw(const Graphics&)+Clone() : IShape*
<<interface>>IShape
+Draw(const Graphics&)+Clone() : IShape*
19
http
://w
ww
.inn
osig
ma.
com
Class 계층구조단순화
Concrete Factory가 하나로 통합되어 있으므로 IPrototypeManager 인터페이스 역할 또한 약화된다.
Prototype Manager
<<interface>>IPrototypeManager
+Add(IShape) : int+Remove(int)+GetPrototype(int) : IShape*
PrototypeManager
+Add(IShape) : int+Remove(int)+GetPrototype(int) : IShape*
-m_mapFactory : map<int, IShape*>-m_nMagicID : int
LineShape
+Draw(const Graphics&)+Clone() : IShape*
RectangleShape
+Draw(const Graphics&)+Clone() : IShape*
<<interface>>IShape
+Draw(const Graphics&)+Clone() : IShape*
PrototypeManager
+Add(IShape) : int+Remove(int)+GetPrototype(int) : IShape*
-m_mapFactory : map<int, IShape*>-m_nMagicID : int
LineShape
+Draw(const Graphics&)+Clone() : IShape*
RectangleShape
+Draw(const Graphics&)+Clone() : IShape*
<<interface>>IShape
+Draw(const Graphics&)+Clone() : IShape*
ShapeFactory
+Create(IShape*) : IShape*
<<create>>
Concrete Factory
20
http
://w
ww
.inn
osig
ma.
com
class PrototypeManager{private:
map<int, IShape*> m_mapFactory;int m_nMagicID;
public:PrototypeManager() : m_nMagicID(0){
m_mapFactory[m_nMagicID++] = new RectangleShape;m_mapFactory[m_nMagicID++] = new LineShape;
}int Add(IShape* pShape){
m_mapFactory[m_nMagicID] = pShape;return m_nMagicID++
}void Remove(int nMagicID) { ... }IShape* GetPrototype(int nMagicID){
return m_mapFactory[nMagicID];}
};
미리 객체를 생성한다.
런타임 시점에
복제할 객체를 추가/삭제할 수 있다.(Ex. Composite Pattern을 통해 조합된 새로운 Shape, ...)
Prototype Manager
PrototypeManager
+Add(IShape) : int+Remove(int)+GetPrototype(int) : IShape*
-m_mapFactory : map<int, IShape*>-m_nMagicID : int
LineShape
+Draw(const Graphics&)+Clone() : IShape*
RectangleShape
+Draw(const Graphics&)+Clone() : IShape*
<<interface>>IShape
+Draw(const Graphics&)+Clone() : IShape*
21
5. Design Pattern
22
http
://w
ww
.inn
osig
ma.
com
Prototype Manager
<<create>>
LineShape
+Draw(const Graphics&)+Clone() : IShape*
RectangleShape
+Draw(const Graphics&)+Clone() : IShape*
<<interface>>IShape
+Draw(const Graphics&)+Clone() : IShape*
ShapeFactory
+Create(IShape*) : IShape*
Clone
LineShape
+Draw(const Graphics&)
RectangleShape
+Draw(const Graphics&)
<<interface>>IShape
+Draw(const Graphics&)
ShapeFactory
+Create(Shape*) : IShape*
LineFactory
+Create() : IShape
RectangleFactory
+Create() : IShape*
Abstract Factory Pattern
요구사항
WHAT : 생성
HOW : Rectangle, Line
요구사항
WHAT : 관리
HOW : 미리 생성된 객체
<<create>>
Design Pattern
LineShape
+Draw(const Graphics&)+Clone() : IShape*
RectangleShape
+Draw(const Graphics&)+Clone() : IShape*
<<interface>>IShape
+Draw(const Graphics&)+Clone() : IShape*
PrototypeManager
+Add(IShape) : int+Remove(int)+GetPrototype(int) : IShape*
-m_mapFactory : map<int, IShape*>-m_nMagicID : int
ShapeFactory
+Create(IShape*) : IShape*
23
http
://w
ww
.inn
osig
ma.
com
<<create>>
+Draw(const Graphics&)+Clone() : IShape*
+Draw(const Graphics&)+Clone() : IShape*
<<interface>>IShape
+Draw(const Graphics&)+Clone() : IShape*
PrototypeManager
+Add(IShape) : int+Remove(int)+GetPrototype(int) : IShape*
-m_mapFactory : map<int, IShape*>-m_nMagicID : int
ShapeFactory
+Create(IShape*) : IShape*
Prototype
Prototype
Prototype : 복사할 객체의 인터페이스. 자신을 복사하는 메커니즘을 정의하고 있어야 한다.
Concrete Prototype Concrete Prototype
Concrete Prototype : 복사되는 객체. 복사 메커니즘을 구현한다.
Client
Client : Prototype에 복사를 요청함으로써 새로운 객체를 생성한다.
Prototype Manager
Prototype Manager : Prototype이 등록된 레지스트리를 관리한다.
원형이 되는 객체를 복사하여 객체를 생성한다.
보통 Prototype은 외부 엔터티 혹은 Factory가 제공하며 Prototype의 실제 타입은 알 필요가 없다.
출처 : 실전 코드로 배우는 실용주의 디자인 패턴(사이텍미디어, 송치형)
Design Pattern
LineShapeRectangleShape
24
6. Class Diagram in Practice
25
http
://w
ww
.inn
osig
ma.
com
C++ Program Code로 표현해 보자!
Class Diagram in Practice
<<create>>
+Draw(const Graphics&)+Clone() : IShape*
+Draw(const Graphics&)+Clone() : IShape*
<<interface>>IShape
+Draw(const Graphics&)+Clone() : IShape*
PrototypeManager
+Add(IShape) : int+Remove(int)+GetPrototype(int) : IShape*
-m_mapFactory : map<int, IShape*>-m_nMagicID : int
ShapeFactory
+Create(IShape*) : IShape*
LineShapeRectangleShape
26
http
://w
ww
.inn
osig
ma.
com
Class Diagram in Practice
<<create>>
+Draw(const Graphics&)+Clone() : IShape*
+Draw(const Graphics&)+Clone() : IShape*
<<interface>>IShape
+Draw(const Graphics&)+Clone() : IShape*
ShapeFactory
+Create(IShape*) : IShape*
LineShapeRectangleShape
class ShapeFactory{public:
IShape* Create(IShape* pShape){
return pShape->Clone();}
};
class IShape{public:
virtual void Draw(const Graphics& g) = 0;virtual IShape* Clone() = 0;
};
public RectangleShape : public IShape{public:
RectangleShape(const RectangleShape& ref);public:
virtual void Draw(const Graphics& g);virtual IShape* Clone(){
return new RectangleShpae(*this);}
};
27
http
://w
ww
.inn
osig
ma.
com
Class Diagram in Practice
+Draw(const Graphics&)+Clone() : IShape*
+Draw(const Graphics&)+Clone() : IShape*
<<interface>>IShape
+Draw(const Graphics&)+Clone() : IShape*
PrototypeManager
+Add(IShape) : int+Remove(int)+GetPrototype(int) : IShape*
-m_mapFactory : map<int, IShape*>-m_nMagicID : int
LineShapeRectangleShape
class PrototypeManager{private:
map<int, IShape*> m_mapFactory;int m_nMagicID;
public:PrototypeManager() : m_nMagicID(0){
m_mapFactory[m_nMagicID++] = new RectangleShape;m_mapFactory[m_nMagicID++] = new LineShape;
}int Add(IShape* pShape){
m_mapFactory[m_nMagicID] = pShape;return m_nMagicID++;
}void Remove(int nMagicID) { ... }IShape* GetPrototype(int nMagicID){
return m_mapFactory[nMagicID];}
};
28
7. Design Pattern in Practice
29
http
://w
ww
.inn
osig
ma.
com
요구사항 : Log 데이터를 Database에 출력(저장)한다.
HOW(세부 구현, 변화하는 것)
WHAT(외부와의 계약, 변화하지 않는 것)
철저히 은닉되어야 한다.
HOW(세부 구현, 변화하는 것)
WHAT(외부와의 계약, 변화하지 않는 것)
철저히 은닉되어야 한다.
추가 요구사항 : Database Stream을 생성한다.
Design Pattern in Practice
30
http
://w
ww
.inn
osig
ma.
com
요구사항WHAT
HOW : Database
: 출력(저장) WHAT
HOW : Database Stream
: 생성
Abstract Factory Pattern구현
Design Pattern in Practice
DatabaseHOW
DatabaseHOW
생성WHAT
출력(저장)WHAT
DBOutputStreamFactory
+Create() : OutputStream*
FileOutputStreamFactory
+Create() : OutputStream*
<<interface>>IOutputStreamFactory
+Create() : OutputStream*
DBOutputStream
+Write(const void*, UINT)
FileOutputStream
+Write(const void*, UINT)
<<interface>>OutputStream
+Write(const void*, UINT)
<<create>>
Abstract Factory
Concrete Factory Concrete Product
Abstract Product
Abstract Factory
31
http
://w
ww
.inn
osig
ma.
com
DBOutputStreamFactory
+Create() : OutputStream*
FileOutputStreamFactory
+Create() : OutputStream*
<<interface>>IOutputStreamFactory
+Create() : OutputStream*
DBOutputStream
+Write(const void*, UINT)
FileOutputStream
+Write(const void*, UINT)
OutputStream
+Write(const void*, UINT)...
<<create>>
-. 원인: “Concrete Factory : Concrete Product = 1 : 1” 관계이다.
Concrete Factory Concrete Product
-. 해결책: “Concrete Factory : Concrete Product = 1 : N” 관계를 구성한다.
-. 문제점: 새로운 Concrete Product가 추가되면 이를 생성하기 위한 Concrete Factory 또한 추가되어야 한다.
(DBOutputStream) (DBOutputStreamFactory)
그러므로, 런타임 시점에 System 수정 없이 새로운 Concrete Project을 추가 생성할 수 없다.(Ex. Composite Pattern을 통해 조합된 새로운 Stream)
즉, Prototype Pattern 적용.
Design Pattern in Practice
32
http
://w
ww
.inn
osig
ma.
com
DBOutputStreamFactory
+Create() : OutputStream*
FileOutputStreamFactory
+Create() : OutputStream*
<<interface>>IOutputStreamFactory
+Create() : OutputStream*
DBOutputStream
+Write(const void*, UINT)
FileOutputStream
+Write(const void*, UINT)
OutputStream
+Write(const void*, UINT)...
<<create>>
Prototype Pattern구현
<<create>>
DBOutputStream
+Write(const void*, UINT)+Clone() : OutputStream*
...
FileOutputStream
+Write(const void*, UINT)+Clone() : OutputStream*
...
OutputStream
+Write(const void*, UINT) +Clone() : OutputStream*
...
PrototypeManager
+Add(OutputStream) : int+Remove(int)+GetPrototype(int) : OutputStream*
-m_mapFactory : map<int, OutputStream*>-m_nMagicID : int
OutputStreamFactory
+Create(OutputStream*) : OutputStream*
Design Pattern in Practice
33
http
://w
ww
.inn
osig
ma.
com
class OutputStream{public:
virtual Write(const void*, UINT) = 0;virtual OutputStream* Clone() = 0;...
};
Class DBOutputStream : public OutputStream{public:
DBOutputStream(const DBOutputStream& ref);public:
virtual Write(const void*, UINT);virtual OutputStream* Clone(){
return new DBOutputStream(*this);}...
};
class OutputStreamFactory{public:
OutputStream* Create(OutputStream* pStream){
return pStream->Clone();}
};
Design Pattern in Practice
<<create>>
DBOutputStream
+Write(const void*, UINT)+Clone() : OutputStream*
...
FileOutputStream
+Write(const void*, UINT)+Clone() : OutputStream*
...
OutputStream
+Write(const void*, UINT) +Clone() : OutputStream*
...
PrototypeManager
+Add(OutputStream) : int+Remove(int)+GetPrototype(int) : OutputStream*
-m_mapFactory : map<int, OutputStream*>-m_nMagicID : int
OutputStreamFactory
+Create(OutputStream*) : OutputStream*
34
http
://w
ww
.inn
osig
ma.
com
Design Pattern in Practice<<create>>
DBOutputStream
+Write(const void*, UINT)+Clone() : OutputStream*
...
FileOutputStream
+Write(const void*, UINT)+Clone() : OutputStream*
...
OutputStream
+Write(const void*, UINT) +Clone() : OutputStream*
...
PrototypeManager
+Add(OutputStream) : int+Remove(int)+GetPrototype(int) : OutputStream*
-m_mapFactory : map<int, OutputStream*>-m_nMagicID : int
OutputStreamFactory
+Create(OutputStream*) : OutputStream*
class PrototypeManager{private:
map<int, OutputStream*> m_mapFactory;int m_nMagicID;
public:PrototypeManager() : m_nMagicID(0){
m_mapFactory[m_nMagicID++] = new FileOutputStream;m_mapFactory[m_nMagicID++] = new DBOutputStream;
}int Add(IShape* pOutputStream){
m_mapFactory[m_nMagicID] = pOutputStream;return m_nMagicID++;
}void Remove(int nMagicID) { ... }OutputStream* GetPrototype(int nMagicID){
return m_mapFactory[nMagicID];}
};
미리 객체를 생성한다.
런타임 시점에
복제할 객체를 추가/삭제할 수 있다.(Ex. Composite Pattern을 통해 조합된 새로운 Stream, ...)
35
http
://w
ww
.inn
osig
ma.
com
OutputStreamFactory
FileOutputStream
<<abstract>>OutputStream
WinOutputStream CompositeOutputStream
SyncOutputStream
delegationLog
delegation
Client
Pattern Summary
Context Strategy
Concrete Strategy Concrete StrategyConcrete Strategy
Strategy
Component
Leaf CompositeLeaf
Composite
Component
Concrete Component
Concrete Decorator
DecoratorConcrete Component
Concrete Decorator
Design Pattern in Practice
Decorator
Singleton
Singleton
BufferedOutputStream
PrototypeManager
Prototype Manager Client
Prototype
Concrete Prototype Concrete Prototype Concrete Prototype
Concrete Prototype Concrete Prototype
Prototype
36
8. Summary
37
http
://w
ww
.inn
osig
ma.
com
정적 자료형(Static Typing)을 기반으로 하는언어(Ex. C++, …)의단점을보완할 수 있다.
Prototype Pattern은
단점 : 객체를 생성할 시점에 생성할 객체의 자료형을 결정해야 한다.
Ex. Static TypingShape* pShape = new Rectangle; // 생성할 시점에 생성할 객체의 자료형 결정
Summary
Ex. Prototype PatternShape* pShape = pSelected->Clone(); // 이전에 생성할 객체의 자료형 결정
top related