<?php

	/**
	 * 3.6 模版方法模式
	 * 	定义:
	 * 		定义一个操作中的算法的骨架,而将一些步骤延
	 * 		迟到子类中。模版方法是的子类可以不改变一个
	 * 		算法的结构即可重定义该算法的某些特定步骤。
	 * 	角色:
	 * 		1. 抽象模版方法类
	 * 			职责:定义并实现了一个模版方法。这个模
	 * 				  版方法一般是一个具体方法,它给出
	 * 				  了一个顶级逻辑的骨架,而逻辑的组
	 * 				  成步骤在相应的抽象操作中,推迟到
	 * 				  子类实现。顶级逻辑也有可能调用一
	 * 				  些具体方法。
	 * 		2. 具体类
	 * 			职责:实现父类定义的一个或多个抽象方法
	 * 				  。每一个抽象模版方法类都可以有任
	 * 				  意多个具体类与之对应,而每一个具
	 * 				  体类都可以给出这些抽象方法(也就
	 * 				  是顶级逻辑的组成步骤)的不同实现
	 * 				  ,从而使得顶级逻辑的实现各不相同。
	 *
	 * 	优点:
	 * 		1. 此模式在定义了一组算法,将具体的实现交友
	 * 		   子类负责。
	 * 		2. 复用了代码
	 * 		3. 导致了一种反向的控制结构,通过一个父类调
	 * 		   用子类的操作,通过对子类的扩展增加自己新
	 * 		   的行为,符合开闭原则。
	 * 	缺点:
	 * 		1. 每个一个不同的实现都需要一个子类来实现,
	 * 		   导致类的个数增加,加大了系统的复杂度。
	 *
	 * 	使用场景:
	 * 		1. 一次性实现一个算法的不变的部分,并将可变
	 * 		   的行为留给子类来实现。
	 * 		2. 个子类中公共的行为应被提取出来并集中到一
	 * 		   个公共父类中以避免代码重复。首先识别现有
	 * 		   代码中的不同之处,并且将不同之处分离为新
	 * 		   的操作。最后,用一个调用这些新的操作的模
	 * 		   版方法来替换这些不同的代码。
	 * 	   	3. 控制子类扩展。模版方法只在特定点调用“hook”
	 * 	   	   操作,这样就只允许在这些点进行扩展。
	 *
	 * 	
	 */

	//抽象模版类
	abstract class AbstractClass{
		//子类中不同的代码,在父类中使用抽象方法让子类
		//重写。
		abstract public function PrimitiveOperation1();
		abstract public function PrimitiveOperation2();
		//子类重复的代码都在此模版方法中来实现
		public function TemplateMethod(){
			$this->PrimitiveOperation1();
			$this->PrimitiveOperation2();
			echo '';
		}
	}
	//具体模版类
	class ConcreteClassA extends AbstractClass{
		public function PrimitiveOperation1(){
			echo '具体类A,方法的1的实现;';
		}
		public function PrimitiveOperation2(){
			echo '具体类A,方法的2的实现;';
		}
	}
	class ConcreteClassB extends AbstractClass{
		public function PrimitiveOperation1(){
			echo '具体类B,方法的1的实现;';
		}
		public function PrimitiveOperation2(){
			echo '具体类B,方法的2的实现;';
		}
	}

	//客户端
	$c=new ConcreteClassA();
	$c->TemplateMethod();

	$c=new ConcreteClassB();
	$c->TemplateMethod();

?>