[TOC]
最近工作上遇到一个问题,最后用设计模式——装饰模式(Decorator)解决了,加深了对这个模式的印象,记录一下,同时当作对看书的复习吧,如果对其他朋友有抛砖引玉的作用就最好了^_^。
我们的UI操作是一种已经定下来的模式,后来被要求修改为另外一种操作模式。简单来说,就是要改变一种控件的功能,我们后面就把这种控件叫做WidgetBox吧。而且,这个WidgetBox类本身有别的用途,暂时不考虑直接在原来的基础上修改。
从这个角度来说,解决这个问题首先想到的方法是: 继承! 以WidgetBox作为父类重新写一个子类,重载关键函数,满足新操作模式的需求。
但是,恰恰遇到问题了:
所以, 继承 这个方法行不通,会因为改动底层给系统带来很大的不稳定性,而且代码量和结构上的修改并没有什么可取之处,如果需求变了,需要新的操作模式呢?
在以上的背景之下,自己想到了如此拙见:用到了装饰(Decorator)这个设计模式。虽然不能完美解决问题,还存在缺点,但是总的来说比上面的这个方法好。如果以后再碰到更好的解决办法,说明我又进步了。^_^
引用书上的一句话:
动态地给一个对象添加一些额外的职责。
依然引用书上的说法:
有时我们希望给某个对象而不是整个类添加一些功能。一种较为灵活的方式是将组件嵌入另一个对象中。
对接上自己需要的:
很简单!能在不改变现有系统结构的情况下,增加一种新的操作方式。那么我就实现一个装饰类,在其中嵌入已经存在的控件类WidgetBox,然后我在装饰类中实现自己的各种操作方式,而且用到大部分的WidgetBox类本身已经实现的功能。
完整的装饰模式的结构如下图所示:
但是,因为个中原因,自己的实现有些许不同:
### C++ class WidgetBox{ void subscribe(event); void unsubscribe(event); void HoldObject(); bool OnMousePress(); bool OnMouseUp(); }
class Decorator{
virtual void subscribe(event);
virtual void unsubscribe(event);
virtual void HoldObject();
virtual bool OnMousePress();
virtual bool OnMouseUp();
private:
WidgetBox* pItem;
}
class WidgetBoxDecorator{
void subscribe(event);
void unsubscribe(event);
void HoldObject();
bool OnMousePress();
bool OnMouseUp();
}
int main()
{
// 老的控件操作模式
WidgetBox *pItem = new WidgetBox("name");
pItem->HoldObject();
// 新的控件操作模式
WidgetBoxDecorator *pItem(new WidgetBox("name"));
pItem->HoldObject();
} ### 小结
自己也把《设计模式-可服用面向对象软件的基础》这本书看了一遍,印象其实不是很深刻,除了个别非常形象的模式之外,例如:享元模式-FlyWeight。剩下的就是自己去写过或者常用的模式了,比如:单例模式、工厂模式、观察者模式。所以,对于自己来说,碰到一个问题,特别是设计上的问题,然后用一个设计模式去解决这个问题,才能深刻理解这个模式的优缺点,以及用途。
[1]《设计模式:可复用面向对象软件的基础》
var WidgetBox = {
createNew: function(){
var widget = {};
widget.OnMouseUp = function()
{
console.log("WidgetBox OnMouseUp();");
}
return widget;
}
}
var Decorator = {
createNew: function(){
var widget = {};
widget.item = WidgetBox.createNew();
widget.OnMouseUp = function()
{
item.OnMouseUp();
console.log("Decorator OnMouseUp();");
}
return widget;
}
}
var WidgetBoxDecorator = {
createNew: function(){
// 继承
var widget = Decorator.createNew();
widget.item = WidgetBox.createNew();
widget.OnMouseUp = function()
{
console.log("WidgetBoxDecorator OnMouseUp();");
}
return widget;
}
}
// old operation
console.log("Old operation:");
var item = WidgetBox.createNew();
item.OnMouseUp();
// new operation
console.log("New operation:");
var item1 = WidgetBoxDecorator.createNew();
item1.OnMouseUp();
结果:
Old operation: WidgetBox OnMouseUp(); New operation: WidgetBoxDecorator OnMouseUp();