• C++之模板模式


    模板模式

    作用:定义一个操作中的算法的骨架。而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。其关键是将通用算法(逻辑)封装在抽象基类中,并将不同的算法细节放到子类中实现。

    在我看来,模板模式的好处在于能减少代码段的复用,把公共行为封装到基类中,把行为流程的实现函数写在基类中,这样在对于不同情况的不同子类,在子类中修改或重写函数即可,而且子类不必担心具体流程。

    优点:1、封装不变部分,扩展可变部分。

    2、提取公共代码,便于维护。

    3、行为由父类控制,子类实现。

    缺点:每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。

    假如一个开发商要建造三所房子,每个房子建造的过程中有些步骤是固定的,如先建造地基,然后砌墙,再然后进行墙面装饰,然后进行内部装修。但虽然步骤一样,但不同的房子可能会采用不同的建筑风格,下面写程序来实现这个过程

    假如不采用模板模式,每个房子是一个类,每个类中建房子步骤的具体细节可能会有差异,所以相同的函数中要写不同的实现,代码如下:

     

    #include <iostream>
    using namespace std;
    class House1
    {
    public:
        void foundation()
        {
            cout<<"1.打地基"<<endl;;
        }
        void wall()
        {
            cout<<"2.按图纸1给房子1砌墙"<<endl;;
        }
        void color()
        {
            cout<<"3.粉刷白颜色的墙"<<endl;;
        }
        void decorte()
        {
            cout<<"4.进行欧美风内部装修"<<endl;;
        }
    };
    
    class House2
    {
    public:
        void foundation()
        {
            cout<<"1.打地基";
        }
        void  wall()
        {
            cout<<"2.按图纸2给房子2砌墙"<<endl;;
        }
        void color()
        {
            cout<<"3.粉刷绿颜色的墙"<<endl;;
        }
       void decorte()
        {
            cout<<"4.进行古风内部装修"<<endl;
        }
    };
    
    class House3
    {
    public:
        void foundation()
        {
            cout<<"1.打地基"<<endl;;
        }
        void wall()
        {
            cout<<"2.按图纸3给房子3砌墙"<<endl;;
        }
        void color()
        {
            cout<<"3.粉刷粉颜色的墙"<<endl;;
        }
        void decorte()
        {
            cout<<"4.进行哥特风内部装修"<<endl;;
        }
    };
    int main()
    
    {
        House1 a1;
        a1.foundation();
        a1. wall();
        a1.color();
        a1.decorte();
        cout<<"================================================="<<endl;
        House2 a2;
        a2.foundation();
        a2. wall();
        a2.color();
        a2.decorte();
        House3 a3;
        cout<<"================================================="<<endl;
        a3.foundation();
        a3. wall();
        a1.color();
        a3.decorte();
    
    }
    

     

      

     

    此种写法不仅代码量大,在建造对象时,每个不同的对象自己在主函数都要调用一遍步骤流程,而且假如现在要求在粉刷墙漆前要先粉刷一遍防火漆,修改时要对每个类进行添加函数,很是麻烦,如果采用模板模式来编写,这些问题都可以得到很好的解决,把公共的函数以及部分实现定义在基类中,再把流程封装在一个函数中,不同的子类继基类后直接重写不同的函数即可,而且对于防火漆这一需求,只需要在基类中定义并加入流程函数就可以了,子类在调用流程函数时会自动执行。具体代码如下:

    #include <iostream>
    
    using namespace std;
    
    class Base
    {
    protected:
        void foundation()
        {
            cout<<"1.打地基"<<endl;
        }
        void ex()
        {
            cout<<"刷防火漆"<<endl;
        }
    public:
        virtual void wall()=0;
        virtual void color()=0;
        virtual void decorte()=0;
        void run()
        {
            foundation();
    
            wall();
    
            ex();
    
            color();
    
            decorte();
        }
    };
    
    class House1:public Base
    {
    public:
       void wall()
        {
            cout<<"2.按图纸1给房子1砌墙"<<endl;;
        }
        void color()
        {
            cout<<"3.粉刷白颜色的墙"<<endl;;
        }
        void decorte()
        {
            cout<<"4.进行欧美风内部装修"<<endl;;
        }
    };
    
    class House2:public Base
    {
    public:
       void  wall()
        {
            cout<<"2.按图纸2给房子2砌墙"<<endl;;
        }
        void color()
        {
            cout<<"3.粉刷绿颜色的墙"<<endl;;
        }
        void decorte()
    
        {
            cout<<"4.进行古风内部装修"<<endl;
        }
    
    };
    
    class House3:public Base
    {
    public:
        void wall()
    
        {
            cout<<"2.按图纸3给房子3砌墙"<<endl;;
        }
        void color()
        {
           cout<<"3.粉刷粉颜色的墙"<<endl;;
        }
        void decorte()
        {
            cout<<"4.进行哥特风内部装修"<<endl;;
        }
    };
    
    int main()
    {
        Base *a=new House1;
        a->run();
        cout<<"================================================="<<endl;
        a=new House2;
        a->run();
        cout<<"================================================="<<endl;
        a=new House3;
        a->run();
    }
    

      

     

     

     

  • 相关阅读:
    Charles抓包工具的使用
    C++中引用(&)的用法和应用实例
    机器学习-斯坦福:学习笔记7-最优间隔分类器问题
    机器学习-斯坦福:学习笔记6-朴素贝叶斯
    机器学习-斯坦福:学习笔记5-生成学习算法
    机器学习-斯坦福:学习笔记4-牛顿方法
    机器学习-斯坦福:学习笔记3-欠拟合与过拟合概念
    机器学习-斯坦福:学习笔记2-监督学习应用与梯度下降
    机器学习-斯坦福:学习笔记1-机器学习的动机与应用
    相似性计算方法
  • 原文地址:https://www.cnblogs.com/xiaxiaopi/p/12482390.html
Copyright © 2020-2023  润新知