装饰模式:
设计模式中的小经验: 类的频繁继承会导致类的数量膨胀带来维护上的困难,在面向对象的设计中,如果超过两层继承,就需要考虑是否出现了设计问题,得尝试改变思路。
定义:动态的给一个对象添加一些额外的职责。 这是一个基于代理模式,继承了其保护,封装的功能,又通过对代理类进行继承和扩展达到多态目的的一种模式,看上去类似于“给代理类化妆”。
用装饰模式补充继承的原因: 装饰模式的作用是“化妆”,继承的作用是“刻入DNA”,继承关系中子类会继承父类的所有代码,无论使用与否,造成极多无用的臃肿代码,装饰则通过继承代理类对功能进行扩展,相比直接继承功能类,避免了继承大片代码,保持了扩展类本身的“精简干练”。
通用类图,即可以通过继承功能类的代理类实现功能的多态,又可以通过多创几种代理类实现功能的多态,但前者的架构看上去会清晰一点。 优点: 装饰类和被装饰类(被代理的实际功能类)可独立发展,无耦合。 替代了对功能类的直接继承和扩展,被继承的最好是基类或代理类 动态扩展一个功能类的功能。
缺点: 功能类内核不变的情况下,多层装饰增加了系统的复杂度,增加了维护的工作量。
使用场景: 扩展一个功能类的功能或增加附加功能而不影响其子类。 动态的给一个对象增加功能,这些功能还能被动态撤销(删除)。 需要为一批的兄弟类进行改装或加装功能,首选装饰模式。
c++代码示例:
class worker
{
public:
worker(string name):mName(name)
{
}
worker(char * name) :mName(name)
{
}
virtual void work() = 0;
string getName()
{
return mName;
}
protected:
string mName;
};
class cooker :public worker
{
public:
cooker(string name):worker(name)
{
}
virtual void work()
{
cout << mName << "正在做它厨师的工作" << endl;
}
};
class ProxyOfCooker :public worker
{
public:
ProxyOfCooker(worker * Worker):worker(Worker->getName()),mWorker(Worker)
{
}
virtual void work()
{
}
protected:
worker* mWorker;
};
class StrongCooker :public ProxyOfCooker
{
public:
StrongCooker(worker* Worker) :ProxyOfCooker(Worker)
{
}
virtual void work()
{
BeStrong();
mWorker->work();
}
protected:
void BeStrong()
{
cout << mWorker->getName() << "通过健身变得更加强壮了" << endl;
}
};
class HighCooker :public ProxyOfCooker
{
public:
HighCooker(worker* Worker) :ProxyOfCooker(Worker)
{
}
virtual void work()
{
BeHign();
mWorker->work();
}
protected:
void BeHign()
{
cout << mWorker->getName() << "通过穿鞋变得更加高了" << endl;
}
};
class RichCooker :public ProxyOfCooker
{
public:
RichCooker(worker* Worker) :ProxyOfCooker(Worker)
{
}
virtual void work()
{
BeRich();
mWorker->work();
}
protected:
void BeRich()
{
cout << mWorker->getName() << "通过努力工作变得更加有钱了" << endl;
}
};
void func()
{
string name = "ZhangSan";
worker* ZhangSan = new cooker(name);
worker* StrongZhangSan = new StrongCooker(ZhangSan);
worker* HignZhangSan = new HighCooker(ZhangSan);
worker* RichZhangSan = new RichCooker(ZhangSan);
StrongZhangSan->work();
HignZhangSan->work();
RichZhangSan->work();
}
int main()
{
func();
return 0;
}
运行结果是:通过对代理类的继承和修改实现了对功能的额外装饰,但干活的功能类没有收到任何影响,而装饰类的使用非常随性,用的时候用,不用的时候删掉也不会有影响。
|