php设计模式之模板模式
模板模式有一个抽象类作为父接口,将部分逻辑以具体方法以及具体构造形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。先制定一个顶级逻辑框架,而将逻辑的细节留给具体的子类去实现。
角色:
抽象模板角色 :抽象模板类,定义了一个具体的算法流程和一些留给子类必须实现的抽象方法。
具体子类角色 :实现抽象模板类中的抽象方法,子类可以有自己独特的实现形式,但是执行流程受抽象模板类的控制。
下面看一下具体代码的应用。比我我定义了一个汽车生产的抽象模板类,makeCar.php
1 <?php 2 /** 3 * author: NickBai 4 * createTime: 2016/11/28 0028 上午 9:02 5 */ 6 abstract class MakeCar 7 { 8 protected $name; 9 10 public function __construct( $name ) 11 { 12 $this->name = $name; 13 } 14 15 public function makeFlow() 16 { 17 $this->makeFrame(); 18 $this->makeEngine(); 19 $this->makewheel(); 20 21 echo $this->name . " 组装完成!<hr/>"; 22 } 23 24 public abstract function makeFrame(); //组装车架 25 public abstract function makeEngine(); //组装发动机 26 public abstract function makeWheel(); //组装车轮 27 }
可以看到,我定义了汽车的流程为-先组装车架,然后再组装发动机,最后组装车轮。这样的一辆汽车就算全部组装完毕了。这个流程的执行顺序,在这个类中已经通过makeFlow()方法强制规定了。子类不可重写这个方法,只需要去实现我定义好的几个抽象
方法即可。下面来看一下Benz.php
1 <?php 2 /** 3 * author: NickBai 4 * createTime: 2016/11/28 0028 上午 9:13 5 */ 6 include_once('MakeCar.php'); 7 8 class Benz extends MakeCar 9 { 10 protected $name; 11 12 public function __construct( $name = '奔驰s600' ) 13 { 14 $this->name = $name; 15 parent::__construct( $this->name ); 16 } 17 18 public function makeFrame() 19 { 20 echo $this->name . " 车架组装完毕!<br/>"; 21 } 22 23 public function makeEngine() 24 { 25 echo $this->name . " 引擎组装完毕!<br/>"; 26 } 27 28 public function makeWheel() 29 { 30 echo $this->name . " 车轮组装完毕!<br/>"; 31 } 32 }
保时捷汽车生产类:Porsche.php
1 <?php 2 /** 3 * author: NickBai 4 * createTime: 2016/11/28 0028 上午 9:18 5 */ 6 include_once('MakeCar.php'); 7 8 class Porsche extends MakeCar 9 { 10 protected $name; 11 public function __construct( $name = '保时捷911' ) 12 { 13 $this->name = $name; 14 parent::__construct( $this->name ); 15 } 16 17 public function makeFrame() 18 { 19 echo $this->name . " 车架组装完毕!<br/>"; 20 } 21 22 public function makeEngine() 23 { 24 echo $this->name . " 引擎组装完毕!<br/>"; 25 } 26 27 public function makeWheel() 28 { 29 echo $this->name . " 车轮组装完毕!<br/>"; 30 } 31 }
两个子类都只实现了自己独特的具体操作,而流程严格按照MakeCar的严格控制。看一下client怎么访问吧
1 <?php 2 /** 3 * author: NickBai 4 * createTime: 2016/11/28 0028 上午 9:21 5 */ 6 include_once('Benz.php'); 7 include_once('Porsche.php'); 8 9 class Client 10 { 11 public function __construct() 12 { 13 $Benz = new Benz(); 14 $Porsche = new Porsche(); 15 16 $Benz->makeFlow(); 17 $Porsche->makeFlow(); 18 } 19 } 20 header('Content-Type:text/html;charset=utf-8'); 21 new Client();
运行结果:
适用场景及优势:
1、完成某一细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时。我们通常考虑用模板模式来处理。
2、当不变的和可变的行为在方法的子类实现中混合在一起的时候,不变的行为就会在子类中重复出现,我们通过模板模式把这些行为搬移到单一的地方,这样就帮助子类摆脱重复的不变行为的纠缠。
3、模板模式通过把不变的行为搬移到超级抽象类,去除子类中的重复代码来体现它的优势。模板模式提供了一个很好的代码复用平台。
参考文章:
http://blog.csdn.net/jhq0113/article/details/46439683