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 需要让对象返回之前的状态(请求'撤销')

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

麦库截图20131818182353499.jpg

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(拷贝) 当创建给定类的实例的过程很复杂很昂贵时使用

麦库截图20130521055426097.jpg

>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 为一个对象的组合增加新的能力, 并且封装不重要时

麦库截图20130822080715691.jpg

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值