C++设计模式:Template Method 模式

来源:互联网 发布:口袋妖怪go手环淘宝 编辑:程序博客网 时间:2024/06/15 02:52
 
    基类用一个public nonvirtual 成员函数访问protected virtual成员函数,子类在需要的时候可以选择Overriding那个protected virtual成员函数,如果是个pure protected virtual成员函数,那就必须Overriding它。
 
 
    1.AbstractClass(抽象类):定义一到多个抽象方法,至少应该是virtual方法。如果AbstractClass负责实现一个通用版本的算法,各子类对该方法进行进一步细化,则只需定义成virtual方法,具体的子类将重定义它们以实现一个算法;而且还实现一个模板方法,来定义一个算法的骨架。
    该模板方法不仅调用前面的抽象方法,也可以调用其他的操作。
    各抽象方法往往被定义成protected(保护)成员,以保证它们只被模板方法调用,而TemplateMethod往往被定义成public非虚成员函数。
 
    2.ConcreteClass(具体类):实现父类中的抽象方法以完成算法中与特定子类相关的步骤。这里的关键是基类中的TemplateMethod方法,因为正是它定义了对各子类对象适用的通用的处理逻辑。
 
    空泛的理论总是令人乏味,给个例子:
///////////////////////////////////////////////////////////
   
class Mountie
    {
     public:
      void read( std::istream & );
      void write( std::ostream & ) const;
      virtual ~Mountie();
 
    protected:
      virtual void do_read( std::istream & );
      virtual void do_write( std::ostream & ) const;
    //派生类对象需要调用这两个函数的实现来读写其中的基类对象
    
     private:
      virtual std::string classID() const = 0; 
         
//在该程序中,classID()是一个实现细节,用来在保存对象时指示具象类的类型,派生类必须覆盖它,所以必须是纯虚的。但是既然是实现细节,就应该设为private的。
    }
 
    void Mountie::write(std::ostream &Dudley) const
    {
     Dudley << classID() << std::endl;
     do_write(Dudley);
    }
   
///////////////////////////////////////////////////////////  
   似乎有些难以理解,换一个:

///////////////////////////////////////////////////////////   
 class Sort
  
   ////// Shell sort //////
   public:
    void doIt( int v[], int n )
      
//基本的排序逻辑在基类Sort中实现
   
    
       for (int g = n/2; g > 0; g /= 2)
         for (int i = g; i < n; i++)
           for (int j = i-g; j >= 0; j -= g)
             if (needSwap(v[j], v[j+g]))
               doSwap(v[j], v[j+g]);        
    }
 
   private:
      virtual int needSwap(int,int) = 0;
      void doSwap(int& a,int& b)
      {
        int t = a; a = b; b = t;
      }
    };
 
 class SortUp : public Sort //但具体的排序方法(升序还是降序)由子类决定
 
{
    int needSwap(int a, int b)
    {
        return (a > b);
    }
  };
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
   最后给一个例子:Template Method使得基类控制了函数的调用顺序(执行流程),子类只负责某个步骤的实现(具体要看是虚还是纯虚)。
  
 class App
    {
    public:
       virtual ~App();
       void startup()
       { // Template Method
        initialize();
        if( !validate() )
            altInit();
      }
 
     protected:
        virtual bool validate() const = 0;
        virtual void altInit();
 
     private:
        void initialize();
   };
 
   class MyApp : public App
    {
     public:
      //...
     private:
        bool validate() const;
        void altInit();
   };
///////////////////////////////////////////////////////////
原创粉丝点击