设计模式总结 (四)
桥接模式:
转自:http://blog.csdn.net/wuzhekai1985/article/details/6670473
[DP]书上定义:将抽象部分与它的实现部分分离,使它们都可以独立地变化。考虑装操作系统,有多种配置的计算机,同样也有多款操作系统。如何运用桥接模式呢?可以将操作系统和计算机分别抽象出来,让它们各自发展,减少它们的耦合度。当然了,两者之间有标准的接口。这样设计,不论是对于计算机,还是操作系统都是非常有利的。下面给出这种设计的UML图,其实就是桥接模式的UML图。
给出C++的一种实现:
- //操作系统
- class OS
- {
- public:
- virtual void InstallOS_Imp() {}
- };
- class WindowOS: public OS
- {
- public:
- void InstallOS_Imp() { cout<<"安装Window操作系统"<<endl; }
- };
- class LinuxOS: public OS
- {
- public:
- void InstallOS_Imp() { cout<<"安装Linux操作系统"<<endl; }
- };
- class UnixOS: public OS
- {
- public:
- void InstallOS_Imp() { cout<<"安装Unix操作系统"<<endl; }
- };
- //计算机
- class Computer
- {
- public:
- virtual void InstallOS(OS *os) {}
- };
- class DellComputer: public Computer
- {
- public:
- void InstallOS(OS *os) { os->InstallOS_Imp(); }
- };
- class AppleComputer: public Computer
- {
- public:
- void InstallOS(OS *os) { os->InstallOS_Imp(); }
- };
- class HPComputer: public Computer
- {
- public:
- void InstallOS(OS *os) { os->InstallOS_Imp(); }
- };
客户使用方式:
- int main()
- {
- OS *os1 = new WindowOS();
- OS *os2 = new LinuxOS();
- Computer *computer1 = new AppleComputer();
- computer1->InstallOS(os1);
- computer1->InstallOS(os2);
- }
装饰模式:
动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。有时我们希望给某个对象而不是整个类添加一些功能。比如有一个手机,允许你为手机添加特性,比如增加挂件、屏幕贴膜等。
例:
- //公共抽象类
- class Phone
- {
- public:
- Phone() {}
- virtual ~Phone() {}
- virtual void ShowDecorate() {}
- };
具体的手机类的定义:
- //具体的手机类
- class iPhone : public Phone
- {
- private:
- string m_name; //手机名称
- public:
- iPhone(string name): m_name(name){}
- ~iPhone() {}
- void ShowDecorate() { cout<<m_name<<"的装饰"<<endl;}
- };
- //具体的手机类
- class NokiaPhone : public Phone
- {
- private:
- string m_name;
- public:
- NokiaPhone(string name): m_name(name){}
- ~NokiaPhone() {}
- void ShowDecorate() { cout<<m_name<<"的装饰"<<endl;}
- };
装饰类的实现:
- //装饰类
- class DecoratorPhone : public Phone
- {
- private:
- Phone *m_phone; //要装饰的手机
- public:
- DecoratorPhone(Phone *phone): m_phone(phone) {}
- virtual void ShowDecorate() { m_phone->ShowDecorate(); }
- };
- //具体的装饰类
- class DecoratorPhoneA : public DecoratorPhone
- {
- public:
- DecoratorPhoneA(Phone *phone) : DecoratorPhone(phone) {}
- void ShowDecorate() { DecoratorPhone::ShowDecorate(); AddDecorate(); }
- private:
- void AddDecorate() { cout<<"增加挂件"<<endl; } //增加的装饰
- };
- //具体的装饰类
- class DecoratorPhoneB : public DecoratorPhone
- {
- public:
- DecoratorPhoneB(Phone *phone) : DecoratorPhone(phone) {}
- void ShowDecorate() { DecoratorPhone::ShowDecorate(); AddDecorate(); }
- private:
- void AddDecorate() { cout<<"屏幕贴膜"<<endl; } //增加的装饰
- };
客户使用方式:
- int main()
- {
- Phone *iphone = new NokiaPhone("6300");
- Phone *dpa = new DecoratorPhoneA(iphone); //装饰,增加挂件
- Phone *dpb = new DecoratorPhoneB(dpa); //装饰,屏幕贴膜
- dpb->ShowDecorate();
- delete dpa;
- delete dpb;
- delete iphone;
- return 0;
- }
备忘录模式:
以保存游戏的进度为例。
Memento类定义了内部的状态,而Caretake类是一个保存进度的管理者,GameRole类是游戏角色类。可以看到GameRole的对象依赖于Memento对象,而与Caretake对象无关。下面给出一个简单的是实现。
- //需保存的信息
- class Memento
- {
- public:
- int m_vitality; //生命值
- int m_attack; //进攻值
- int m_defense; //防守值
- public:
- Memento(int vitality, int attack, int defense):
- m_vitality(vitality),m_attack(attack),m_defense(defense){}
- Memento& operator=(const Memento &memento)
- {
- m_vitality = memento.m_vitality;
- m_attack = memento.m_attack;
- m_defense = memento.m_defense;
- return *this;
- }
- };
- //游戏角色
- class GameRole
- {
- private:
- int m_vitality;
- int m_attack;
- int m_defense;
- public:
- GameRole(): m_vitality(100),m_attack(100),m_defense(100) {}
- Memento Save() //保存进度,只与Memento对象交互,并不牵涉到Caretake
- {
- Memento memento(m_vitality, m_attack, m_defense);
- return memento;
- }
- void Load(Memento memento) //载入进度,只与Memento对象交互,并不牵涉到Caretake
- {
- m_vitality = memento.m_vitality;
- m_attack = memento.m_attack;
- m_defense = memento.m_defense;
- }
- void Show() { cout<<"vitality : "<< m_vitality<<", attack : "<< m_attack<<", defense : "<< m_defense<<endl; }
- void Attack() { m_vitality -= 10; m_attack -= 10; m_defense -= 10; }
- };
- //保存的进度库
- class Caretake
- {
- public:
- Caretake() {}
- void Save(Memento menento) { m_vecMemento.push_back(menento); }
- Memento Load(int state) { return m_vecMemento[state]; }
- private:
- vector<Memento> m_vecMemento;
- };
客户使用方式:
- //测试案例
- int main()
- {
- Caretake caretake;
- GameRole role;
- role.Show(); //初始值
- caretake.Save(role.Save()); //保存状态
- role.Attack();
- role.Show(); //进攻后
- role.Load(caretake.Load(0)); //载入状态
- role.Show(); //恢复到状态0
- return 0;
- }
1、有时一些发起人对象的内部信息必须保存在发起人对象以外的地方,但是必须要由发起人对象自己读取,这时,
使用备忘录模式可以把复杂的发起人内部信息对其他的对象屏蔽起来,从而可以恰当地保持封装的边界。
|
2、本模式简化了发起人类。发起人不再需要管理和保存其内部状态的一个个版本,客户端可以自行管理他们所需
要的这些状态的版本。
|
3、当发起人角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原。 |
1、如果发起人角色的状态需要完整地存储到备忘录对象中,那么在资源消耗上面备忘录对象会很昂贵。 |
2、当负责人角色将一个备忘录 存储起来的时候,负责人可能并不知道这个状态会占用多大的存储空间,从而无法提醒用户一个操作是否很昂贵。 |
3、当发起人角色的状态改变的时候,有可能这个协议无效。如果状态改变的成功率不高的话,不如采取“假如”协议模式。 |
中介者模式:
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式的例子很多,大到联合国安理会,小到房屋中介,都扮演了中间者的角色,协调各方利益。
职责链模式:
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
观察者模式:
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。它还有两个别名,依赖(Dependents),发布-订阅(Publish-Subsrcibe)。
状态模式:
允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。它有两种使用情况:(1)一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为。(2)一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。