zoukankan      html  css  js  c++  java
  • 设计模式 --> (12)装饰模式

    装饰模式

      时常会遇到这样一种情况,我已经设计好了一个接口,并且也有几个实现类,但是这时我发现我设计的时候疏忽了,忘记了一些功能,或者后来需求变动要求加入一 些功能,最简单的做法就是修改接口,添加函数,然后继承类中都相应的添加实现,这样做倒也没什么问题,但是如果这种变化来个好几次或者继承类非常多,那工 作量可就大了。

      装饰者模式,在不修改现在有接口和实现类的基础上实现功能或者状态的添加。

    适用性:

      如果需要添加新功能,但又不想修改定义好的接口或者抽象类,那么这时候就比较适合装饰模式,例如很多图形系统中的组件,就可以使用装饰模式,来让新的组件在继承现在功能的基础上添加新的功能。

      装饰模式一般是针对接口或者抽象类的变化,如果是具体实现类的变化,则要考虑适用哪种模式。

    优点

      1.可以不用修改原有的接口,就可以实现新功能的添加。

      2.装饰者可以很方便的转换原有接口中的实现,可以给装饰者指定不同的ConcreteComponent实现不同的功能。

    缺点

      1.复杂性增加,装饰者模式会导致许多小类的产生。

    示例

      比如有一个手机,允许你为手机添加特性,比如增加挂件、屏幕贴膜等。一种灵活的设计方式是,将手机嵌入到另 一对象中,由这个对象完成特性的添加,我们称这个嵌入的对象为装饰。

    #include <iostream>
    using namespace std;
    
    //公共抽象类  
    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;  
    }  

    参考: http://blog.csdn.net/wuzhekai1985

  • 相关阅读:
    了解mysql之约束篇
    快速了解MySQL中的字符串数据类型
    解决tomcat命令行输出的中文乱码问题
    浅谈了解JDBC
    .NET Core项目部署到Linux(Centos7)(八)为.NET Core项目创建Supervisor进程守护监控
    .NET Core项目部署到Linux(Centos7)(七)启动和停止.NET Core项目
    .NET Core项目部署到Linux(Centos7)(六)发布.NET Core 项目到Linux
    .NET Core项目部署到Linux(Centos7)(五)Centos 7安装.NET Core环境
    .NET Core项目部署到Linux(Centos7)(四)VMware Workstation虚拟机Centos 7安装
    .NET Core项目部署到Linux(Centos7)(三)创建.NET Core API项目
  • 原文地址:https://www.cnblogs.com/jeakeven/p/4967080.html
Copyright © 2011-2022 走看看