设计模式(3)--装饰模式
2016-11-02 01:07 sylar_liang 阅读(211) 评论(0) 编辑 收藏 举报//单一原则: 一个类而言,应该仅有一个引起它变化的原因。 //开放-封闭原则: 类/模块/函数等等,应该可以扩展,但是不可修改。 //依赖倒装原则: 抽象不应该依赖细节,洗劫应该依赖于抽象。换句话说是,要针对接口编程,不要对实现编程。 //A.高层模块不应该依赖低层模块。两个都应该依赖抽象。 //B.抽象不应该依赖细节。细节应该依赖抽象。 //里氏代换原则: 子类型必须能够替换掉它们的父类型。
//3.装饰模式 //ver1 class Person { private: string _name; public: Person(string name) { _name = name; } void Show() { //... } }; //服饰抽象类 class Finery { public: virtual void Show() = 0; }; //T恤类 class TShirts : public Finery { public: virtual void Show() { //.. } }; //垮裤类 class BigTrouser : public Finery { public: virtual void Show() { //.. } }; //领带类 class Tie : public Finery { public: virtual void Show() { //.. } }; void main11() { Person *ppc = new Person("fun"); TShirts *pd1 = new TShirts(); BigTrouser *pd2 = new BigTrouser(); Tie *pd3 = new Tie(); //装扮1 pd1->Show(); pd2->Show(); ppc->Show(); //装扮2 pd1->Show(); pd3->Show(); ppc->Show(); //缺点: 一个一个显示出来; 组装应该在内部进行; }
//装饰模式: 动态地给一个对象添加一些额外的职责,就增加功能类说,装饰模式比生成子类更为灵活;
//3.装饰模式 //ver2 //Component是定义一个对象接口,可以给这些对象动态地添加职责。 //ConcreteComponent是定义一个具体的对象,也可以给这个对象添加一些职责。 //Decorator抽象装饰类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,无需知道Decorator的存在; //ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能。 class Component { public: virtual void Operation() = 0; //接口 }; class ConcreteComponent : public Component { virtual void Operation() { //... } }; class Decorator : public Component { protected: Component *pcomponent; public: void SetComponent(Component *pcom) { pcomponent = pcom; } virtual void Operation() { if (pcomponent != NULL) { pcomponent->Operation(); } } }; class ConcreteDecoratorA : public Decorator { private: string addState; public: virtual void Operation() { Decorator::Operation(); //先运行Component的Operation,再执行本类的操作。 addState = "New State"; //... } }; class ConcreteDecoratorB : public Decorator { private: void AddBehavior() //本类独有的操作; { //... } public: virtual void Operation() { Decorator::Operation(); AddBehavior(); } }; void main12() { ConcreteComponent * pc = new ConcreteComponent(); ConcreteDecoratorA * d1 = new ConcreteDecoratorA(); ConcreteDecoratorB * d2 = new ConcreteDecoratorB(); d1->SetComponent(pc); //先用 ConcreteDecoratorA 来包装 ConcreteComponent; 会执行 ConcreteComponent::Operation() d2->SetComponent(d1); //再用 ConcreteDecoratorB 来包装 ConcreteDecoratorA d2->Operation(); //最终执行 d2->Operation() //装饰模式是利用SetComponent来对对象进行包装的。这样每个装饰对象的实现就和如何使用这个对象分离开了。 //每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中。 }
//如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类。
//如果只有一个ConcreteDecorator类,那么久没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合成一个类.
//3.装饰模式 //ver3 class Person { private: string _name; public: Person(){} //用于 TShirts 等派生类构造默认的构造函数; Person(string name) { _name = name; } virtual void Show() { } }; //服饰类 class Finery : public Person { protected: Person component; public: void Decorate(Person comp) { component = comp; } virtual void Show() { component.Show(); } }; //具体服饰类 class TShirts : public Finery { public: virtual void Show() { //do something Finery::Show(); } }; class BigTrouser : public Finery { public: virtual void Show() { //do something. Finery::Show(); } }; void main31() { Person * ppc = new Person("fun"); TShirts * pd1 = new TShirts(); BigTrouser * pd2 = new BigTrouser(); pd1->Decorate(*ppc); pd2->Decorate(*pd1); pd2->Show(); }
//装饰模式是为已有功能动态地添加更多功能的一种方式。
//装饰模式把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象。
//优点: 把类中的装饰功能从类中搬移去除,这样可以简化原有的类。
// 有效地把类的核心职能和装饰功能区分开了,而且可以去除相关类中重复的装饰逻辑。