1.目的
当我们要增加一个类(Boy)的功能(如扩充某个接口(show)的功能)时,我们可以直接给这个类增加方法,可以给这个类的父类增加方法,但是这样会将这个类变得越来越大,装饰者模式是一种增加类的功能的思路。装饰者模式不增加类的方法,而是从父类(People)派生一个新的类(Tshirt),也就是装饰者,装饰者继承父类,并持有一个父类的指针(也就是被装饰者或已经被装饰过的被装饰者),当接口被调用的时候,装饰者先调用被装饰者的接口,再调用需要增加的额外功能的接口(装饰者可以派生出新的子类来提供额外的功能)
2.代码
Decorator.h
#ifndef DECORATOR_H_
#define DECORATOR_H_
class People
{
public:
virtual ~People();
virtual void show()=0;
};
class Boy:public People
{
public:
void show();
};
class Clothe:public People
{
public:
Clothe();
virtual ~Clothe();
void show();
void decorate(People&);
virtual void extraShow() =0;
protected:
People* people;
};
class Tshirt:public Clothe
{
public:
void extraShow();
};
class Pants:public Clothe
{
public:
void extraShow();
};
#endif /* DECORATOR_H_ */
Decorator.cpp
#include "Decorator.h"
#include <iostream>
using namespace std;
People::~People()
{}
void Boy::show()
{
cout<<"Boy wears ";
}
Clothe::Clothe():people(NULL)
{}
Clothe::~Clothe()
{}
void Clothe::decorate(People& arg)
{
people = &arg;
}
void Clothe::show()
{
if(people != NULL)
{
people->show();
}
extraShow();
}
void Tshirt::extraShow()
{
cout<<"T shirt ";
}
void Pants::extraShow()
{
cout<<"Pants ";
}
void decorator()
{
Boy boy;
Tshirt tshirt;
Pants pants;
tshirt.decorate(boy);
pants.decorate(tshirt);
pants.show();
}
执行结果: Boy wears T shirt Pants
3.讨论
装饰者模式是否违反了Liskov替换原则?继承一般逻辑上都有“is a”的关系,那么对于Clothe类,继承People类这个操作(也就是装饰者继承被装饰者的接口),就会破坏这种“is-a”的关系,从而违反了Liskov原则