Visitor_访问者模式_PHP语言描述

Visitor_访问者模式的定义:

表示一个作用于某对象结构中的各元素的操作。它使你可以再不改变各元素的类的前提下定义作用于这些元素的新操作。

我们先来看看这段定义说明,这是JAVA研磨设计模式中对Visitor模式的定义描述。一开始读到这个定义的时候说实话我没看懂,什么叫某对象结构,说白了就是一组继承于某个基类的子类集合或者数组的意思。

我尝试着用便于理解的语言来描述一下访问者模式,为一组对象提供批量动态添加及访问功能的模式。

应用Visitor_访问者模式解决问题的思路:

现在电商很火,我们来简单分析一下电商的客户,可能有企业客户还有个人用户。现在我们需要分析一下每个客户的购买偏好。并且不想把具体的实现封装在具体的元素对象中,因为实际上不可能只有两种客户,可能很多,如果我要添加一个通用的功能,把具体功能封装在对象中,太不便于管理了。

首先定义一个接口来表示要新加入的功能,为了通用,也就是定义一个通用的功能在这个方法来代表新加入的功能。

在对象结构(封装了一组元素对象的容器)添加一个方法,作为通用的功能方法,回调传入具体访问者的功能即具体的实现新功能的对象。

最后我们需要提供新功能的接口及具体的实现类。

Visitor(interface):访问者接口,为所有的访问者对象声明一个visit方法,用来代表为对象结构添加的功能,理论上可以代表任意的功能。

ConcreteVisitor(class):具体的访问者实现对象,实现要真正被添加到对象结构中的功能。

Element(abstract class):抽象的元素对象,对象结构的顶层接口,定义接受访问的操作。

ConcreteElement:具体元素对象,对象结构中具体的对象,也是被访问的对象,通常会回调访问者的真实功能,同时开放自身的数据提供给访问者使用。

ObjectStructure:对象结构,通常包含多个被访问对象,它可以遍历多个被访问的对象,也可以让访问者访问它的元素。

我们来看看具体的实现:

<?php
	/**
	 * Visitor_访问者模式_PHP语言描述
	 */
	
	/**
	 * 元素类的抽象方法
	 */
	abstract class Customer{
		protected $customerId,$name;
		/**
		 * 接受访问者的访问
		 * @param Object $visitor
		 */
		public abstract function accept($visitor);
		
		/**
		 * 实现get/set功能
		 */
		public function __set($pro_name,$value){
			$this->$pro_name = $value;
		}
		
		public function __get($pro_name){
			return $this->$pro_name;
		}
	}
	
	/**
	 * 具体的元素类的实现
	 */
	class EnterpriseCustomer extends Customer{
		
		protected $linkman,$linkTelephone,$registerAddress;
		
		public function accept($visitor){
			$visitor->visitEnterpriseCustomer($this);
		}
	}
	
	class PersonalCustomer extends Customer{
		protected $telephone,$age;
		
		public function accept($visitor){
			$visitor->visitPersonalCustomer($this);
		}
	}
	
	/**
	 * 访问者接口
	 */
	interface Visitor{
		/**
		 * 访问企业用户,相当于给企业客户添加访问者功能
		 * @param ECustomerObject $ec
		 */
		public function visitEnterpriseCustomer($ec);
		
		/**
		 * 访问普通用户,相当于给普通用户添加访问者功能
		 * @param PCustomerObject $pc
		 */
		public function visitPersonalCustomer($pc);
	}
	
	/**
	 * 具体的访问者,实现客户提出服务的请求的功能
	 */
	class ServiceRequestVisitor implements Visitor{
		public function visitEnterpriseCustomer($ec){
			//企业客户提出的具体服务请求
			echo $ec->name."企业提出服务的请求<br>";
		}
		
		public function visitPersonalCustomer($pc){
			//个人客户提出的具体服务请求
			echo "客户".$pc->name."提出服务的请求<br>";			
		}
	}
	
	/**
	 * 具体的访问者,实现对客户偏好分析的功能
	 */
	class PredilectionAnalyzeVisitor implements Visitor{
		public function visitEnterpriseCustomer($ec){
			//根据以往购买的历史,潜在购买意向以及客户所在行业的发展趋势、客户的发展预期等的分析
			echo "现在对企业客户".$ec->name."进行产品偏好分析<br>";
		}
		
		public function visitPersonalCustomer($pc){
			//个人客户提出的具体服务请求
			echo "现在对个人客户".$ec->name."进行产品偏好分析<br>";
		}		
	}
	
	/**
	 * ObjectStructure对象的实现
	 */
	class ObjectStructure{
		/**
		 * 要操作的客户数组
		 */
		private $col = array();
		
		/**
		 * 提供给客户端操作的高层接口,具体的功能由客户端传入的访问者决定
		 * @param visitorObject visitor
		 */
		public function handleRequest($visitor){
			//循环对象结构中的元素,接受访问
			for($i=0;$i<count($this->col);$i++){
				$this->col[$i]->accept($visitor);
			}
		}
		
		/**
		 * 组建对象结构,向对象结构中添加元素
		 * 不同的对象结构有不同的构造方法
		 * @param Object ele 加入到对象结构的元素
		 */
		public function addElement($ele){
			array_push($this->col, $ele);
		}
	}
	
	//具体看看怎么用
	
	//创建ObjectStructure
	$os = new ObjectStructure();
	//准备一些测试数据,创建客户对象,并加入到os中
	$cm1 = new EnterpriseCustomer();
	$cm1->name = "ABC集团";
	$os->addElement($cm1);
	
	$cm2 = new EnterpriseCustomer();
	$cm2->name = "CDE公司";
	$os->addElement($cm2);
	
	$cm3 = new PersonalCustomer();
	$cm3->name="张三";
	$os->addElement($cm3);
	
	//客户提出服务请求,传入服务请求的Visitor
	$srVisitor = new ServiceRequestVisitor();
	$os->handleRequest($srVisitor);
?>


你可能感兴趣的:(PHP,visitor,访问者模式)