设计模式之-装饰者模式

定义:动态的给一个对象添加游戏欸额外的职责,就增加功能来说,装饰模式比生成子类更灵活。

注意他与建造者的区别:它的建造过程是不稳定的,二建造者的建造过程是稳定的。

 

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

基本代码:

    abstract class Component
    {
        public abstract void Operation();
    }

    class ConcreteComponent:Component
    {
        public override void Operation()
        {
            Console.WriteLine("具体对象的操作");
        }
    }

    abstract class Decorator:Component
    {
        protected Component component;
        public void SetComponent(Component component)
        {
            this.component = component;
        }
        public override void Operation()
        {
            if(component!=null)
            {
                component.Operation();
            }
        }
    }

    class ConcreteDecoratorA : Decorator
    {
        private string addedState;
        public override void Operation()
        {
            base.Operation();
            addedState = "new state";
            Console.WriteLine("具体修饰对象A的操作");
        }
    }

    class ConcreteDecoratorB : Decorator
    {
        
        public override void Operation()
        {
            base.Operation();
            AddBehavior();
            Console.WriteLine("具体修饰对象B的操作");
        }
        void AddBehavior()
        {

        }
    }
View Code

客户端代码的实现

static void Main(string[] args)
{
    ConcreteComponent c=new ConcreteComponent ();
    ConcreteDecoratorA d1=new ConcreteDecoratorA ();
    ConcreteDecoratorB d2=new ConcreteDecoratorB ();

    d1.SetComponent(c);
    d2.SetComponent(d1);
    d2.Operation();
}
View Code

上述代码的执行顺序就是先具体对象的操作,然后对象A ,最后对象B。


如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类。同样道理:如果只有一个ConcreteDecoretor类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator类和ConcreteDecorator类的职责合并。

优点:

把类中的装饰功能从类中搬移去除,这样可以简化原有的类。

何时使用:
当系统需要新功能时,是向旧的类中添加新的代码。这些新加的代码通常装饰了原有类的核心职责或主要行为,增加了主类的复杂度,而这些新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为的需要。

装饰模式提供了一种非常好的解决方案,他把每个要装饰的功能放在单独的类中,并让这个类包转它所需要装饰的对象。因此,当需要执行特殊行为时,客户端代码就可以在运行时根据需要有选择的,按顺序的使用装饰类包装对象了。
装饰模式总结:
装饰模式是为已有功能动态添加更多功能的一种方式。


 

 C++的实现

#include<iostream>
using namespace std;
#include<string>
//公共抽象类
class Phone
{
public:
    Phone() {}
    virtual ~Phone() {}
    virtual void ShowDecorate() {}
};
//具体的手机类
class iPhone : public Phone
{
private:
    string m_name; //手机名称
public:
    iPhone(string name) : m_name(name) {}
    ~iPhone() {}
    void ShowDecorate() { cout << m_name << "的装饰" << endl; }
};
//具体的手机类
class NokiaPhone : public Phone
{
private:
    string m_name;
public:
    NokiaPhone(string name) : m_name(name) {}
    ~NokiaPhone() {}
    void ShowDecorate() 
    { 
        cout << m_name << "的装饰" << endl; 
    }
};
//装饰类
class DecoratorPhone : public Phone
{
private:
    Phone* m_phone;  //要装饰的手机
public:
    DecoratorPhone(Phone* phone) : m_phone(phone) {}
    virtual void ShowDecorate()
    { 
        m_phone->ShowDecorate(); 
    }
};

//具体的装饰类
class DecoratorPhoneA : public DecoratorPhone
{
public:
    DecoratorPhoneA(Phone* phone) : DecoratorPhone(phone) {}
    void ShowDecorate()
    {
        DecoratorPhone::ShowDecorate(); 
        AddDecorate(); 
    }
private:
    void AddDecorate()
    { 
        cout << "增加挂件" << endl;
    } //增加的装饰
};
//具体的装饰类
class DecoratorPhoneB : public DecoratorPhone
{
public:
    DecoratorPhoneB(Phone* phone) : DecoratorPhone(phone) {}
    void ShowDecorate() 
    { 
        DecoratorPhone::ShowDecorate();
        AddDecorate(); 
    }
private:
    void AddDecorate() 
    { 
        cout << "屏幕贴膜" << endl; 
    } //增加的装饰
};
int main()
{
    Phone* iphone = new NokiaPhone("6300");
    Phone* dpa = new DecoratorPhoneA(iphone); //装饰,增加挂件
    Phone* dpb = new DecoratorPhoneB(dpa);    //装饰,屏幕贴膜
    dpb->ShowDecorate();
    delete dpa;
    delete dpb;
    delete iphone;
    return 0;
}
View Code

 转载博客:(1条消息) 设计模式C++实现(11)——装饰模式_wuzhekai的专栏-CSDN博客_c++装饰模式

posted @ 2021-09-02 23:09  HelloWorld庄先生  阅读(24)  评论(0编辑  收藏  举报