zoukankan      html  css  js  c++  java
  • 第六章-装饰模式

    装饰模式(Decorator): 动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。

    当你向旧的类中添加新代码时,一般是为了添加核心职责或主要行为。而当需要加入的仅仅是一些特定情况下才会执行的特定的功能时(简单点就是不是核心应用的功能),就会增加类的复杂度。装饰模式就是把要添加的附加功能分别放在单独的类中,并让这个类包含它要装饰的对象,当需要执行时,客户端就可以有选择地、按顺序地使用装饰功能包装对象。

    图片

    Component是定义一个对象借口,可以给这些对象动态的添加职责。ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责。Decorator,装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator的存在的。至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能。

    基本代码实现

    #include<iostream>
    #include<string>
    
    using namespace std;
    
    //Component类
    class Component
    {
    public:
    	virtual void Operation() = 0;
    };
    
    //ConcreteComponent类
    class ConcreteComponent : public Component
    {
    public:
    	void Operation()
    	{
    		cout << "具体对象的操作" << endl;
    	}
    };
    
    //Decorator类
    class Decorator : public Component
    {
    protected:
    	Component* component;
    public:
    	Decorator() : component(nullptr) {}
    	void SetComponent(Component* component_t) //设置Component
    	{
    		component = component_t;
    	}
    	void Operation()    //重写Operation(), 实际执行的是Component的Operation()
    	{
    		if (component != nullptr)
    		{
    			component->Operation();
    		}
    	}
    
    };
    
    //ConcreteDecoratorA类
    class ConcreteDecoratorA : public Decorator
    {
    private:
    	string addedState; //本类独有功能,以区别于ConcreteDecoratorB
    public:
        /*首先运行原Component的Operation(),再执行本类的功能,如addedState,相当于对原Component进行了装饰*/
    	void Operation()
    	{
    		Decorator::Operation();
    		addedState = "New State";
    		cout << "具体装饰对象A的操作" << endl;
    	}
    
    };
    
    class ConcreteDecoratorB : public Decorator
    {
    public:
        /*首先运行原Component的Operation(),再执行本类的功能,如AddedBehavior(),相当于对原Component进行了装饰*/
    	void Operation()
    	{
    		Decorator::Operation();
    		AddedBehavior();
    		cout << "具体装饰对象B的操作" << endl;
    	}
    	void AddedBehavior() {}   //本类独有功能,以区别于ConcreteDecoratorA
    
    };
    
    
    
    
    int main()
    {
        /*装饰的方式是:首先用ConcreteComponent实例化对象c,然后用ConcreteDecoratorA的实例化对象d1来包装c,再用ConcreteDecoratorB的对象d2包装d1,最终执行d2的Operation()*/
    	ConcreteComponent *c = new ConcreteComponent;
    	ConcreteDecoratorA *d1 = new ConcreteDecoratorA;
    	ConcreteDecoratorB *d2 = new ConcreteDecoratorB;
    
    	d1->SetComponent(c);
    	d2->SetComponent(d1);
    	d2->Operation();
    	
    
    	system("pause");
    	return 0;
    }
    
    

    装饰模式使用SetComponent来对对象进行包装的。这样每个装饰对象的实现就和如何使用这个对象分离开了,每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链中。

    在下面的穿衣装扮代码中Person类就是Component和ConcreteComponent的结合。
    如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以使ConcreteComponent的一个子类。同样道理,如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类。

    穿衣装扮代码

    图片

    #include<iostream>
    #include<string>
    
    using namespace std;
    
    //Person类(ConcreteComponent)
    class Person
    {
    private:
    	string name;
    
    public:
    	Person() {}
    	Person(string name_t)
    	{
    		name = name_t;
    	}
    	virtual void Show()
    	{
    		cout << "装扮的" << name << endl;
    	}
    
    };
    
    //服饰类(Decorator)
    class Finery :public Person
    {
    protected:
    	Person *component;
    	
    public:
    	Finery() :component(nullptr) {}
    
        //打扮
    	void Decorate(Person *component_t)
    	{
    		component = component_t;
    	}
    
    	void Show()
    	{
    		if (component != nullptr)
    		{
    			component->Show();
    		}
    	}
    };
    
    //具体服饰类(ConcreteDecorator)
    class TShirts :public Finery
    {
    public:
    	void Show()
    	{
    		cout << "大T恤 ";
    		Finery::Show();
    	}
    };
    
    class BigTrouser :public Finery
    {
    public:
    	void Show()
    	{
    		cout << "垮裤 ";
    		Finery::Show();
    	}
    };
    /*其余类类似,省略
    ...................*/
    
    
    int main()
    {
    	
    	Person *xc = new Person("小菜");
    	cout << "开始装扮:" << endl;
    	TShirts * ts = new TShirts;
    	BigTrouser * bt = new BigTrouser;
    
        //装饰过程
    	ts->Decorate(xc);
    	bt->Decorate(ts);
    
    	bt->Show();
    
    	system("pause");
    	return 0;
    }
    
    

    装饰模式是为已有功能动态的添加更多功能的一种方式。它把每个要装饰的功能放在单独的类中,并让这些类包装它所要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。
    装饰模式的优点是把类中的装饰功能从类中搬移去除,这样可以简化原有的类,有效的把类的核心职责和装饰功能区分开了,而且可以去除相关类中重复的装饰逻辑。

  • 相关阅读:
    (收藏)基于.net开发平台项目案例集锦
    记录:在ASP.NET中使用ActiveX插件时遇到的问题
    [转]三种邮件服务器的比较
    (收藏)30岁,开始实现我的程序员梦
    [转]加密狗原理介绍
    从临时表返回数据时遇到的问题(ORA08103: object no longer exists)
    Response.Flush的使用心得
    C#编程向VFP数据库中插入Numeric型的值(foxpro,dbf)
    [转]Web部件错误:此网页存在致命错误
    Win2003Server出现了很多的“桌面”
  • 原文地址:https://www.cnblogs.com/wfcg165/p/11989985.html
Copyright © 2011-2022 走看看