目录
简介
装饰者模式是指 在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它通过创建一个包装对象,也就是 装饰 来包裹真实的对象。
设计原则
多用组合,少用继承:
利用继承设计子类行为,是在编译时静态决定的,而且所有的子类都会集成到相同的行为。然而,如果能够利用组合的做法扩展对象的行为,就可以在运行时动态的进行扩展。
类应设计的对外扩展,对修改关闭。
定义
23种设计模式之一,装饰模式(DecoratorPattern),又叫装饰者模式。动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活[DP]。
特点
装饰对象和真实对象由相同的接口。这样客户端对象就能以和 真实对象相同的方式和装饰对象交互。
装饰对象必须包含一个真实对象的引用
装饰对象接受所有来自客户端的请求。它把这些请求转发给真实的对象。
装饰对象可以在转发这些请求之前或之后增加一些附加功能。确保在运行时,不用修改给定对象的结构就可以在外部增加附加功能。在面向对象的设计中,通常时通过继承来实现对给定类的功能扩展。
适用性
需要扩展一个类的功能,或给一个类添加附加职责。
需要动态的给一个对象添加功能,这些功能可以再动态的撤销。
需要增加由一些基本功能排列组合而产生的非常强大的功能,从而使继承关系变的不现实。
装饰模式(Decorator)结构图
Component ([kəmˈpəʊnənt] 组成部分,零件):定义一个对象接口,可以给这些对象动态地添加职责。
concreteComponent:具体的对象,也可以给这个对象添加一些职责。
Decorator:装饰抽象类,继承自Component,从外类来扩展Component类的功能,但是对于Component来说,是无需知道Decorator的存在。
concreteDecorator:具体的装饰对象, 起到给Component添加职责的功能[DPE]。
模式简化
如果只有一个concreteComponent类而没有抽象的Component接口时,可以让Decorator继承ConcreteComponent。
如果只有一个concreteDecorator类时,可以将Decorator和concreteDecorator合并。
优缺点
优点
Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。
通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多找那个不同行为的组合。
缺点
这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。
装饰模式会导致设计中出现许多小类,如果过多使用,会使程序变得很复杂。
实例
装饰类文件Person.h
#pragma once
#include<iostream>
#include<string>
using namespace std;
/// <summary>
/// 装饰者模式
/// ConcreteComponent :具体的组成部件
/// </summary>
class Person
{
public:
Person() {
}
Person(string name) {
this->name = name;
}
virtual void Show() {
cout << "装扮的" << name << endl;
}
private:
string name;
};
/// <summary>
/// 服饰类 Decorator 装饰抽象类
/// </summary>
class Finery :public Person {
public:
void Decorate(Person* component)//打扮
{
this->component = component;
}
void Show() override {
if (component != nullptr) {
component->Show();
}
}
protected:
Person *component;//组成部件 零件 实际上就是包装的对象
};
/// <summary>
/// Decorator 具体装饰类
/// </summary>
class Tshirts :public Finery {
public:
void Show() override {
cout << "大T恤";
Finery::Show();
}
};
class BigTrouser :public Finery {
public:
void Show() override {
cout << "垮裤";
Finery::Show();
}
};
class Sneakers :public Finery {
public:
void Show() override {
cout << "破球鞋";
Finery::Show();
}
};
class Suit :public Finery {
public:
void Show() override {
cout << "西装";
Finery::Show();
}
};
class Tie :public Finery {
public:
void Show() override {
cout << "领带";
Finery::Show();
}
};
class LeatherShoes :public Finery {
public:
void Show() override {
cout << "皮鞋";
Finery::Show();
}
};
客户端文件
#include<iostream>
using namespace std;
#include"Person.h"
int main(int argc, char* argv[]) {
Person *xc = new Person("小菜");
cout << "\n第一种装扮:\n";
Sneakers* pqx = new Sneakers();
BigTrouser* kk = new BigTrouser();
Tshirts* dtx = new Tshirts();
//装饰过程
pqx->Decorate(xc);
kk->Decorate(pqx);
dtx->Decorate(kk);
dtx->Show();
cout << "\n第二种装扮:\n";
LeatherShoes* px = new LeatherShoes;
Tie* ld = new Tie;
Suit* xz = new Suit;
//装饰过程
px->Decorate(xc);
ld->Decorate(px);
xz->Decorate(ld);
xz->Show();
system("pause");
return 0;
}