Head First 设计模式 Design Pattern 附录 Mediator Memeto Prototype Visitor

附录A: 余下的模式

6中介者 Mediator 集中相关对象之间复杂的沟通和控制方式

每个对象都会在自己的状态改变时告诉中介者; 每个对象都会对中介者发出的请求作出回应; 对象之间解耦;

>优点 对象的彼此解耦 增加对象的复用性; 将控制逻辑集中 简化系统维护; 让对象之间传递的信息变的简单轻量

>用途和缺点 用来协调相关的GUI组件; 如果设计不当 中介者对象本身会变得过于复杂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//***********Mediator***********                 
class Agent;                 
class Customer  //Colleague                 
{                 
public :                 
     Customer() : miCounter(0) {};                 
     void purchase(Agent* m, int num);                 
     void updateCounter(int n);                 
private :                 
     int miCounter;                 
};                 
                                                                                                                                                       
class Producer  //IColleague                 
{                 
public :                 
     Producer(int n)  : miInventory(n) {};                 
     void delivery(int n);                 
private :                 
     intmiInventory;                 
};                 
                                                                                                                                                               
classAgent  //Mediator                 
{                 
public :                 
     void setCustomer(Customer* c) { mCustomer = c;}                 
     Customer* getColleagueA() { returnmCustomer;}                 
     void setProducer(Producer* B) { mProducer = B;}                 
     Producer* getProducer() { returnmProducer;}                 
     void purchase(int num);                 
private :                 
     Customer* mCustomer;                 
     Producer* mProducer;                 
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//***********Mediator***********                 
void Customer::purchase(Agent* m, int num)                 
{                 
     m->purchase(num);                 
}                 
                                                                                                                                                      
void Customer::updateCounter(int n)                 
{                 
     miCounter += n;                 
     cout<< "Customer: " <<miCounter<<endl;                 
}                 
                                                                                                                                                      
void Producer::delivery(int n)                 
{                 
     miInventory -= n;                 
     cout<< "Producer: " <<miInventory<<endl;                 
}                 
                                                                                                                                                      
void Agent::purchase(int num)                 
{                 
     mProducer->delivery(num);                 
     mCustomer->updateCounter(num);                 
}                 
         //Mediator                 
         Agent* agent =  newAgent();                 
         Customer* customer =  newCustomer();                 
         Producer* producer = newProducer(100);                 
         agent->setCustomer(customer);                 
         agent->setProducer(producer);                 
         customer->purchase(agent, 7);

7备忘录 Memeto 需要让对象返回之前的状态(请求'撤销')

>存储系统关键对象的重要状态; 维护关键对象的封装;

1)Memento 将Originator对象的内部状态存储起来; 2)Originator 创建一个含有当前内部状态的备忘录对象, 使用备忘录对象存储其内部状态; 3)Caretaker 负责保存备忘录对象, 不保存备忘录对象的内容

>优点 将状态放在外部, 防止和关键对象混淆, 帮助维护内聚; 保持关键对象的数据封装; 提供了容易实现的恢复能力;

>用途和缺点 用于存储状态; 缺点-存储和恢复状态的过程比较耗时; Java系统中可以使用序列化Serialization机制存储系统的状态.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//***********Memento***********        
class  StateMem        
{        
public :        
     StateMem() : level(1), health(100) {};        
     int  level;        
     int  health;        
};        
                                                                                 
class  Memento        
{        
public :        
     void  setState( const  StateMem& state);        
     StateMem getState() {  return  mstate;}        
private :        
     StateMem mstate;        
};        
                                                                                 
class  Originator        
{        
public :        
     Originator( const  StateMem& state) { mstate = state;}        
     void  setLevel( int  lev) { mstate.level = lev;}        
     void  setHealth( int  h) { mstate.health = h;}        
     Memento* createMemento();        
     void  restoreMemento(Memento* mem);        
     void  StateOutput();        
private :        
     StateMem mstate;        
};        
                                                                                 
class  Caretaker        
{        
public :        
     void  saveMemento(Memento* mem) { mMemento = mem;}        
     Memento* retrieveMemento() {  return  mMemento;}        
private :        
     Memento* mMemento;        
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//***********Memento***********        
void  Memento::setState( const  StateMem& state)        
{        
     mstate = state;        
}        
                                                                                
Memento* Originator::createMemento()        
{        
     Memento* mem =  new  Memento();        
     mem->setState(mstate);        
     return  mem;        
}        
                                                                                
void  Originator::restoreMemento(Memento* mem)        
{        
     mstate = mem->getState();        
}        
                                                                                
void  Originator::StateOutput()        
{        
     cout<< "------State------" <<endl;        
     cout<< "Health: " <<mstate.health<<endl;        
     cout<< "Level: " <<mstate.level<<endl;        
}        
         //Memento        
         StateMem state;        
         Originator* originator =  new  Originator(state);        
         Memento* memento = originator->createMemento();        
         Caretaker* caretaker =  new  Caretaker();        
         caretaker->saveMemento(memento);        
         originator->setLevel(3);        
         originator->setHealth(150);        
         originator->StateOutput();        
         originator->restoreMemento(caretaker->retrieveMemento());        
         originator->StateOutput();

8原型 Prototype(拷贝) 当创建给定类的实例的过程很复杂很昂贵时使用

>Prototype 抽象原型角色, 抽象原型的定义, 包含一个Clone接口; ConcretePrototype 具体原型角色, 被原型复制的具体对象; Client 客户调用端.

>优点 对客户隐藏制造新实例的复杂性; 提供让客户能产生未知类型对象的选项; 某些情况复制对象比创建新对象更有效;

>用途和缺点 在复杂的类层次中, 当系统必须从其中的许多类型创建新对象时考虑原型; 实例化的类是在运行时刻决定的; 缺点-对象的复制有时很复杂;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//***********Prototype************        
class  Prototype     
{     
public :     
     typedef  enum
     {     
         NotDefined = 0,     
         Human = 1,     
         Alien= 2,     
     } Category;     
                                               
     Prototype() {};     
     virtual  ~Prototype() {};     
     virtual  Prototype* clone() = 0;     
};     
                                           
class  Human :  public  Prototype     
{     
public :       
     typedef  enum
     {     
         NotDefined = 0,     
         Male = 1,     
         Female = 2,     
     } Gender;     
     Human( const  char * name,  int  height);     
     Human( const  Human& h);     
     virtual  ~Human();     
     void  setGender(Gender g) { mGender = g;}     
     virtual  Human* clone();     
     void  Display();       
private :     
     char * mName;     
     int  mHeight;     
     Gender mGender;     
     static  int  miObject;     
     static  int  ObjectNum();     
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//***********Prototype***********     
int  Human::miObject = 0;     
Human::Human( const  char * name,  int  height)     
{     
     if  (name == NULL)     
     {     
         mName =  new  char [1];     
         mName =  '\0' ;     
     }     
     else
     {     
         mName =  new  char [ strlen (name) + 1];     
         strcpy (mName, name);     
     }     
     mHeight = height;     
     mGender = NotDefined;     
     miObject++;     
}     
                                          
Human::Human( const  Human& h)     
{     
     mHeight = h.mHeight;     
     mGender = h.mGender;     
     mName =  new  char [ strlen (h.mName) + 1];     
     strcpy (mName, h.mName);     
     miObject++;     
}     
                                          
Human::~Human()     
{     
     delete  []mName;     
     miObject--;     
}     
                                          
Human* Human::clone()     
{     
     Human* human =  new  Human(* this );  //copy construct     
     return  human;     
}     
                                          
void  Human::Display()     
{     
     cout<< "Object number: " <<ObjectNum()<<endl;     
     cout<< "Name-" <<mName<< "& Height-" <<mHeight<<endl;         
}     
                                          
int  Human::ObjectNum()     
{     
     return  miObject;     
}     
         //Prototype     
         Human* humanA =  new  Human( "Peter" , 180);     
         humanA->setGender(Human::Male);     
         Human* humanB = humanA->clone();     
         humanB->Display();     
         delete  humanA;     
         humanB->Display();

9访问者 Visitor 为一个对象的组合增加新的能力, 并且封装不重要时

>优点 允许对组合结构加入新的操作, 无需修改结构本身; 相对易于加入新操作; 访问者进行的操作代码比较集中;

>用途和缺点 访问者模式打破组合类的封装; 由于游走的功能, 组合结构更加难以改变;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//***********Vistor************      
class  IVistor;   
class  IOperatingSystem   
{   
public :   
     virtual  void  accept(IVistor* v) = 0;   
     virtual  void  setName(string n) { mName = n;}   
     virtual  string getName()  const  return  mName;}   
private :   
     string mName;   
};   
             
class  Windows :  public  IOperatingSystem   
{   
public :   
     Windows(string name);      
     virtual  void  accept(IVistor* v);   
};   
             
class  Linux :  public  IOperatingSystem   
{   
public :   
     Linux(string name, string version);   
     virtual  void  accept(IVistor* v);   
     string getVersion()  const  return  mVersion;}   
private :   
     string mVersion;   
};   
             
class  IVistor   
{   
public :   
     virtual  void  visit( const  Windows& win) = 0;   
     virtual  void  visit( const  Linux& lin) = 0;   
};   
             
class  Display :  public  IVistor   
{   
public :   
     virtual  void  visit( const  Windows& win);   
     virtual  void  visit( const  Linux& lin);   
};   
             
class  Collection   
{   
public :   
     ~Collection();   
     void  Add(IOperatingSystem* opSys);   
     void  Print(IVistor* v);   
private :   
     typedef  list<IOperatingSystem*> OperationSysList;   
     OperationSysList sysList;   
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//***********Vistor***********  
Windows::Windows(string name)  
{  
     setName(name);  
}  
         
void  Windows::accept(IVistor* v)  
{  
     v->visit(* this );  
}  
         
Linux::Linux(string name, string version) : mVersion(version)  
{  
     setName(name);  
}  
         
void  Linux::accept(IVistor* v)  
{  
     v->visit(* this );  
}  
         
void  Display::visit( const  Windows& win)  
{  
     cout<< "---Windows---" <<endl;  
     cout<< "Name: " <<win.getName()<<endl;  
}  
         
void  Display::visit( const  Linux& lin)  
{  
     cout<< "---Linux---" <<endl;  
     cout<< "Name: " <<lin.getName()<<endl;  
     cout<< "Version: " <<lin.getVersion()<<endl;  
}  
         
Collection::~Collection()  
{  
     OperationSysList::const_iterator iter = sysList.begin();  
     for  (; iter != sysList.end(); iter++)  
         delete  *iter;  
}  
         
void  Collection::Add(IOperatingSystem* opSys)  
{  
     sysList.push_back(opSys);  
}  
         
void  Collection::Print(IVistor* v)  
{  
     OperationSysList::const_iterator iter = sysList.begin();  
     for  (; iter != sysList.end(); iter++)  
     {  
         (*iter)->accept(v);  
     }  
}  
         //Vistor  
         Collection collection;  
         collection.Add( new  Windows( "Windows 7" ));  
         Linux* lin =  new  Linux( "Red Hat" "6.0" );  
         collection.Add(lin);  
         collection.Print( new  Display());

End

你可能感兴趣的:(Head First 设计模式 Design Pattern 附录 Mediator Memeto Prototype Visitor)