简介

父类抽象类定义大的解决流程,局部细节做成形象办法,留给子类去实现。

如Java的JUnit中, setUp tearDown办法都是留给具体的测试用例来写,Servlet中service解决了一个申请的大部分工作,留下doGet和doPost给业务自定义解决。

另外callback个别分两种形式:同步回调、异步回调,其中同步回调相似于模板办法模式,异步回调相似于观察者模式。

模板办法要基于继承,而回调更相似组合,

角色

  • 形象模板类

    定义大的解决流程,留出局部办法给具体类实现

  • 具体模板类

    实现具体的解决逻辑

类图

如图,ConcreteClass实现了一些具体逻辑

代码

abstract class AbstractClass{    final public function templateMethod(): void    {        $this->baseOperation1();        $this->requiredOperations1();        $this->baseOperation2();        $this->hook1();        $this->requiredOperation2();        $this->baseOperation3();        $this->hook2();    }    protected function baseOperation1(): void    {        echo "AbstractClass says: I am doing the bulk of the work\n";    }    protected function baseOperation2(): void    {        echo "AbstractClass says: But I let subclasses override some operations\n";    }    protected function baseOperation3(): void    {        echo "AbstractClass says: But I am doing the bulk of the work anyway\n";    }    abstract protected function requiredOperations1(): void;    abstract protected function requiredOperation2(): void;    protected function hook1(): void { }    protected function hook2(): void { }}class ConcreteClass1 extends AbstractClass{    protected function requiredOperations1(): void    {        echo "ConcreteClass1 says: Implemented Operation1\n";    }    protected function requiredOperation2(): void    {        echo "ConcreteClass1 says: Implemented Operation2\n";    }}class ConcreteClass2 extends AbstractClass{    protected function requiredOperations1(): void    {        echo "ConcreteClass2 says: Implemented Operation1\n";    }    protected function requiredOperation2(): void    {        echo "ConcreteClass2 says: Implemented Operation2\n";    }    protected function hook1(): void    {        echo "ConcreteClass2 says: Overridden Hook1\n";    }}function clientCode(AbstractClass $class){    $class->templateMethod();}echo "Same client code can work with different subclasses:\n";clientCode(new ConcreteClass1());echo "Same client code can work with different subclasses:\n";clientCode(new ConcreteClass2());

output:

Same client code can work with different subclasses:AbstractClass says: I am doing the bulk of the workConcreteClass1 says: Implemented Operation1AbstractClass says: But I let subclasses override some operationsConcreteClass1 says: Implemented Operation2AbstractClass says: But I am doing the bulk of the work anywaySame client code can work with different subclasses:AbstractClass says: I am doing the bulk of the workConcreteClass2 says: Implemented Operation1AbstractClass says: But I let subclasses override some operationsConcreteClass2 says: Overridden Hook1ConcreteClass2 says: Implemented Operation2AbstractClass says: But I am doing the bulk of the work anyway

本文由mdnice多平台公布