梁越

c++设计模式-模板模式

0 人看过

模板模式

模板模式

适用情况

假如你正在开发一款分析公司文档的数据挖掘程序。 用户需要向程序输入各种格式 (PDF、 DOC 或 CSV) 的文档, 程序则会试图从这些文件中抽取有意义的数据, 并以统一的格式将其返回给用户。

该程序的首个版本仅支持 DOC 文件。 在接下来的一个版本中, 程序能够支持 CSV 文件。 一个月后, 你 “教会” 了程序从 PDF 文件中抽取数据。一段时间后, 你发现这三个类中包含许多相似代码。

尽管这些类处理不同数据格式的代码完全不同, 但数据处理和分析的代码却几乎完全一样,将相同部分代码提取成接口,使用多态性实现个性化,是模板模式的精髓

优缺点

优点:可以重写某个算法的特定部分,分离相同部分
缺点:违反里氏替换原则,子类不能完全替换基类;当算法步骤需要修改时,需要修改所有的类

与其他模式关系

这个等学完在对比

实例代码

实例1

class Library
{
protected:
    step1(){};
    step2(){};
    step3(){};
    virtual step4()=0;
    virtual step5()=0;
public:
    virtual ~Library();

    voud run()
    {
        step1();
        step2();
        step3();
        step4(); //后绑定
        step5(); //后绑定
    }
}

class Application1:public Library
{
protected:
    step4() override {cout<<"Application1::step4"};
    step5() override {cout<<"Application1::step5"};
}

class Application2:public Library
{
protected:
    step4() override {cout<<"Application2::step4"};
    step5() override {cout<<"Application2::step5"};
}

int main()
{
    Library  *a=new Application1;
    a->run();
    Library  *b=new Application2;
    b->run();
}

实例2

class AbstractClass {
 public:
  void TemplateMethod() const {
    this->BaseOperation1();
    this->RequiredOperations1();
    this->BaseOperation2();
    this->Hook1();
    this->RequiredOperation2();
    this->BaseOperation3();
    this->Hook2();
  }

 protected:
  void BaseOperation1() const {
    std::cout << "AbstractClass says: I am doing the bulk of the work\n";
  }
  void BaseOperation2() const {
    std::cout << "AbstractClass says: But I let subclasses override some operations\n";
  }
  void BaseOperation3() const {
    std::cout << "AbstractClass says: But I am doing the bulk of the work anyway\n";
  }

  virtual void RequiredOperations1() const = 0;
  virtual void RequiredOperation2() const = 0;

  virtual void Hook1() const {}
  virtual void Hook2() const {}
};

class ConcreteClass1 : public AbstractClass {
 protected:
  void RequiredOperations1() const override {
    std::cout << "ConcreteClass1 says: Implemented Operation1\n";
  }
  void RequiredOperation2() const override {
    std::cout << "ConcreteClass1 says: Implemented Operation2\n";
  }
};

class ConcreteClass2 : public AbstractClass {
 protected:
  void RequiredOperations1() const override {
    std::cout << "ConcreteClass2 says: Implemented Operation1\n";
  }
  void RequiredOperation2() const override {
    std::cout << "ConcreteClass2 says: Implemented Operation2\n";
  }
  void Hook1() const override {
    std::cout << "ConcreteClass2 says: Overridden Hook1\n";
  }
};

void ClientCode(AbstractClass *class_) {
  // ...
  class_->TemplateMethod();
  // ...
}

int main() {
  std::cout << "Same client code can work with different subclasses:\n";
  ConcreteClass1 *concreteClass1 = new ConcreteClass1;
  ClientCode(concreteClass1);
  std::cout << "\n";
  std::cout << "Same client code can work with different subclasses:\n";
  ConcreteClass2 *concreteClass2 = new ConcreteClass2;
  ClientCode(concreteClass2);
  delete concreteClass1;
  delete concreteClass2;
  return 0;
}

输出结果:

Same client code can work with different subclasses:

AbstractClass says: I am doing the bulk of the work

ConcreteClass1 says: Implemented Operation1

AbstractClass says: But I let subclasses override some operations

ConcreteClass1 says: Implemented Operation2

AbstractClass says: But I am doing the bulk of the work anyway

Same client code can work with different subclasses:

AbstractClass says: I am doing the bulk of the work

ConcreteClass2 says: Implemented Operation1

AbstractClass says: But I let subclasses override some operations

ConcreteClass2 says: Overridden Hook1

ConcreteClass2 says: Implemented Operation2

AbstractClass says: But I am doing the bulk of the work anyway