原型模式(Prototype)

<?php
/**
 * 设计模式 一 原型模式 Prototype
 */

/**
 * 定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型达到创建新的对象目的。
 * Prototype原型模式是一种创建型设计模式,Prototype模式允许一个对象再创建另一个可制定的对象,
 * 根本无需知道任何创建的细节。
 * 
 * 工作原理:通过一个原型对象传给 那个要发动创建的对象,这个要发动创建的对象是通过请求原型对象克隆原型对象自身。
 *
 */


/**
 * 优点:
 * 1、可以在运行时刻添加和删除产品
 * 2、可以改变值以指定新对象。
 * 3、可以改变结构以指定新对象。
 * 4、减少子类构造。
 * 5、用类动态配置应用。
 *
 * 缺点:
 * 1、prototype模式的最主要缺点就是每个类必须配备一个克隆方法。
 * 而且这个克隆方法需要对类的功能进行通盘考虑,这对全新的类来说不是很难,但对已有的类进行改造时,不一定是件容易的事。
 *
 */

 /**
  * 适用场景
  * 1、当一个系统应该独立于它的产品创建、构成和表示时,要使用Prototype
  * 2、当要实例化的类是在运行时刻指定时,例如动态加载。
  * 简历,星际小怪。
  */

/**
 * 抽象原型。
 */

abstract class Prototype {
	public abstract function clone();
}

class ConcreteAPrototype extends Prototype {
	public $name;
	public function __construct($name) {
		$this->name = $name;
	}

	public function getName() {
		return $this->name;
	}

	public function clone() {
		return clone $this;
	}
}

$p1 = new ConcreteAPrototype('lmq');
$p2 = $p1->clone();
var_export($p1);

$p2->name = 'lmq2';
var_export($p2);




/**
 * 继续发展,由于原型对象比较多,需要一个原型管理类,
 */


class PrototypeManager {
	private $_prototypeList = array();

	//增加原型,第一个参数为原型的名字,第二个参数为原型对象
	public function addPrototype($name, $prototype) {
		$this->_prototypeList[$name] = $prototype;
	}

	public function getPrototype($name) {
		return $this->_prototypeList[$name];
	}

	public function removePrototype($name) {
		return unset($this->_prototypeList[$name]);
	}
	
	//获取原型的克隆,也就是替代new的方法,参数为原型的名字
	public function getClone($name) {
		return clone $this->_prototypeList[$name];
	}
}

 //初始化管理类
$manager = new PrototypeManager();

//初始化两个属于不同的原型
$prototypeA = new ConcreteAPrototype('lmq');
$prototypeB = new ConcreteAPrototype('lmq2');

 //增加原型,同时用比较容易记忆的名字来命名原型
$manager->addPrototype('p1', $prototypeA);
$manager->addPrototype('p2', $prototypeB);
 

 //当需要新增对象的时候,我们可以不必知道对象的类名和初始化的工作
$objcetA = $manager->getClone('p1');

/*
   我们一般用new来新增对象,不过很多时候新增一个对象需要一些工作。而星际里面往往会新增某些类的大量的对象,比如新增很多机枪兵和龙骑。

    待解决的问题:我们能否减少new的使用,同时避免需要新增对象的时候,了解对象的类名。

    思路:php5提供了克隆方法,我们可以新增一个对象,然后每次需要新增和她同类的对象,克隆他就可以了。

    原型(Prototype)模式示例:
*/

//机枪兵类

class Marine {
  //所属的用户ID
  public $playerID

  //构造函数,参数为用户的id
  public function __construct($id) {
	$this->playerID = $id;
  }
}

//兵种的管理类

class TroopManager {

	//数组,用于存放多个兵种的原型
	public $troopPrototype = array();

	//增加原型,第一个参数为原型的名字,第二个参数为原型对象
	public function addPrototype($name, $prototype) {
		$this->troopPrototype[$name] = $prototype;
	}

	//获取原型的克隆,也就是替代new的方法,参数为原型的名字

	public function getPrototype($name) {
		return clone $this->troopPrototype[$name];
	}
}

     
//初始化兵种的管理类
$manager = new TroopManager();

//初始化两个属于不同玩家的机枪兵的原型
$m1 = new Marine(1);
$m2 = new Marine(2);

//增加原型,同时用比较容易记忆的名字来命名原型
$manager->addPrototype('Marine of 1', $m1);
$manager->addPrototype('Marine of 2', $m2);

//当需要新增对象的时候,我们可以不必知道对象的类名和初始化的工作
$m3 = $manager->getPrototype('Marine of 1');


/*

用途总结:原型模式可以将新增对象的工作细节封装。
实现总结:需要一个原型管理类,实现增加和获取克隆原型的方法。注意这里由于为了简明,省略了一些东西,实际上我们可以在克隆方法上做一些改动,也可以用接口规范每个原型类。

*/



设计模式目录


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值