设计模式:装饰类
试想这样一个场景:小菜每天都要打扮自己,第一天小菜穿T恤,穿破洞裤,第二天穿西服西裤。同一个人在不同的场合需要对自己进行不同的打扮,需要动态的给对象(小菜)添加一些不同的功能(穿不同服装)的时候就需要使用到装饰的设计模式
文章目录
结构图
首先可以通过左右对比,首先通过一个人类的对象接口。通过小菜一个具体的人和装饰类来继承人类。然后将不同的穿衣类型的对象来对小菜进行装饰。在Decorator类当中有一个component指针,这个指针是指向concreteComponent对象的。
一些思考
这里的装饰模式其实是为了避免对象的继承的方过多而导致代码的膨胀,所以选择通过装饰来使得对象动态的获得一些功能,可以预见的是装饰的顺序对于结果可能是会影响的。
代码
人类 (component)
//人类对象接口
class Person {
public:
~Person() {}
virtual std::string Operation() const = 0;
};
小菜 (concreteComponent)
// 小菜 需要被装饰的人
class Xiaocai :public Person {
public:
~Xiaocai() {}
std::string Operation() const override {
return "小菜本菜";
}
};
装饰基类 (Decorator)
//基础部分(可能包含额外部分)
class Dress : public Person {
protected:
// 装饰对象,装饰的时候需要一个人吧,所以这里显然需要一个人类
Person* m_Person;
public:
~Dress() {}
Dress(Person* person) :m_Person(person) {};
std::string Operation() const override {
//显然我这个Dress只是提供了一个基类,要如何装饰还得看之后的子类如何装饰
return m_Person->Operation(); //核心代码 ,这里并不会一直循环
}
};
具体的装饰(concreteDecorator)
//额外部分(需要委托基类,完成基础部分)
class Tshirt : public Dress {
public:
~Tshirt() {}
Tshirt(Person* person) :Dress(person) {}
std::string Operation() const override {
//在基类的操作之前,加上额外的Tshirt的操作
return "大T恤" + Dress::Operation();
}
};
class RippedPants : public Dress {
public:
~RippedPants() {}
RippedPants(Person* person) :Dress(person) {}
std::string Operation() const override {
//在基类的操作之前,加上额外的Tshirt的操作
return "破洞裤" + Dress::Operation();
}
};
主函数
void ClientCode(Person* person) {
std::cout << "结果:" + person->Operation()<<std::endl;
}
int main()
{
Person* xiaocai = new Xiaocai();
// 小菜
ClientCode(xiaocai);
Person* xiaocaiDress1 =new Tshirt(xiaocai);
Person* xiaocaiDress2 =new RippedPants(xiaocaiDress1);
ClientCode(xiaocaiDress2);
Person* test = new Dress(xiaocai);
test->Operation();
ClientCode(test);
}
结果
总结
今天解决了小菜穿衣服的问题,真是开心的一天啊。现在本菜要穿上球鞋去打篮球了。