【设计模式】装饰模式
来源:互联网 发布:13家合法网络筹款平台 编辑:程序博客网 时间:2024/06/05 03:56
修饰模式是一种动态地往一个对象中添加新的行为的设计模式。继承是对现有类进行扩充,用来增加基类功能,该扩充动作是在编译期完成;而修饰模式是对一个对象进行扩充,从而达到修饰的目的,该修饰动作是在运行期完成。装饰模式的UML图如下:
下面是一个用C++编写的关于描述一个人的示例程序,并使用了装饰模式。
#include <iostream>#include <string> using namespace std; // Componentclass Person {public: virtual void Describe() = 0; virtual ~Person() // 存在继承关系,需要使用虚析构函数 {}}; // ConcreteComponentclass Student : public Person {public: Student(const string &n) : name(n) {} // 重写虚函数 void Describe() { cout << "Name : " << name << endl; }private: string name;}; // Decoratorclass Decorator : public Person {public: Decorator(Person *p) { person = p; } void Describe() { person->Describe(); // 调用被修饰对象自身的方法 } private: Person *person; // 保存需要被修饰的对象}; // ConcreteDecoratorclass DecoratorAge : public Decorator {public: DecoratorAge(Person *p, int a) : Decorator(p), age(a) {} void Describe() { Decorator::Describe(); cout << "Age : " << age << endl; // 修饰 }private: int age;}; // ConcreteDecoratorclass DecoratorSex : public Decorator {public: DecoratorSex(Person *p, const string &s) : Decorator(p), sex(s) {} void Describe() { Decorator::Describe(); cout << "Sex : " << sex << endl; // 修饰 }private: string sex;}; int main(){ Student s("Nestle"); cout << "无修饰:" << endl; s.Describe(); cout << endl; cout << "修饰年龄:" << endl; DecoratorAge decoratorAge(&s, 24); // 修饰器 decoratorAge.Describe(); cout << endl; cout << "修饰性别:" << endl; DecoratorSex decoratorSex(&s, "man"); // 修饰器 decoratorSex.Describe(); cout << endl; cout << "同时修饰年龄和性别:" << endl; DecoratorSex decoratorAll(&decoratorAge, "man"); // 修饰器 decoratorAll.Describe(); cout << endl; system("pause"); return 0;}
运行结果:
在这个例子中,我把人作为修饰对象,并从Person抽象类(在装饰模式中被称为Component)派生出一个Student非抽象类(在装饰模式中被称为ConcreteComponent)。该类中有一个描述自己的成员函数Describe,但描述的内容十分简单,所以需要使用装饰模式对描述内容进行修饰扩充。接下来在从Person类派生出一个Decorator类,这个类是其它修饰器类的基类,也就是说,真正对Student对象进行修饰的类必须继承自Decorator类。在Decorator类中保存有被修饰对象的指针,我们需要用这个指针完成被修饰对象自身的操作。我在这个例子中构建了两个具体的修饰类(在装饰模式中被称为ConcreteDecorator),一个是修饰Student年龄的DecoratorAge类,另一个是修饰Student性别的DecoratorSex类。它们执行完被修饰对象原有的操作后,就执行自己的修饰行为,分别输出年龄和性别,从而达到修饰目的。在用户代码中,实例化了一个Student对象和三个修饰器,修饰器可随意的对Student对象进行修饰。
装饰模式的好处在于,对一个对象功能的扩充不需要在该对象所属类中添加代码,只需要单独建立一个或几个类,用这些类来修饰对象。这样便有效地把类的核心职责和装饰功能分离开来。并且修饰方法非常灵活,在上面的例子中,我们可以只修饰年龄或对象或同时修饰,形成一个修饰链。
参考:
《大话设计模式》第6章
维基百科
- 设计模式---装饰模式
- 设计模式:装饰模式
- 设计模式------装饰模式
- 设计模式--装饰模式
- 设计模式--装饰模式
- 设计模式--装饰模式
- 设计模式 装饰模式
- 设计模式----装饰模式
- 设计模式-【装饰模式】
- 设计模式--装饰模式
- 设计模式装饰模式
- 设计模式 - 装饰模式
- 设计模式-----装饰模式.
- 设计模式-----装饰模式.
- [ 设计模式 ] 装饰模式!
- 设计模式:装饰模式
- 设计模式 - 装饰模式
- 设计模式 - 装饰模式
- LeetCode :: Candy
- 下一步计划及问题
- 常量指针与指针常量的区别
- LAMP环境配置(XP.X86)
- 热水袋
- 【设计模式】装饰模式
- 佳能数码相机出现故障如何恢复里面的照片数据【天盾数据恢复中心】
- 菜鸟对互换两个数经典swap函数的理解
- 最长回文子串_POJ3974_O(n)完美求解--------入门级理解
- OC语言之学习篇——03——代理模式
- 使用fflush函数导致HDU1880WA
- HDU 2087 剪花布条 KMP入门
- HttpWatch工具简介及使用技巧(转载)
- HDU 2955 Robberies (01背包)