刚刚了解了原型模式,通过资料以及自身了解整合以下资料: 原型模式通过复制已经存在的实例来返回新的实例,而不是新建实例,并且原型(被复制的实例)是可定制的;原型模式多用于创建复杂的或耗时的实例,这种情况下,复制一个已经存在的实例是程序运行更高
刚刚了解了原型模式,通过资料以及自身了解整合以下资料:
原型模式通过复制已经存在的实例来返回新的实例,而不是新建实例,并且原型(被复制的实例)是可定制的;原型模式多用于创建复杂的或耗时的实例,这种情况下,复制一个已经存在的实例是程序运行更高效无疑是一种好办法;
概念:
用原型实例创建对象的种类,并通过拷贝这些原型创建的对象;
结构图:
主要角色:
抽象原型角色(Prototype):声明一个克隆自身的接口
具体原型角色(ConcretePrototype):实现一个克隆自身的操作
Prototype模式优点:
1、可以在运行时刻增加和删除产品
2、可以改变值或结构以指定新对象
3、减少子类的构造
4、用类动态配置应用
Prototype模式的缺点:
Prototype是的最主要的缺点就是每一个类必须包含一个克隆方法;
而且这个克隆方法需要对类的功能进行检测,这对于全新的类来说较容易,但对已有的类进行改造时将不是件容易的事情;
代码实现:
/1**/这些注释的居然全没了,纠结!!(就加个1吧)
/1**
*
* 原型模式
* 用原型实例指定创建对象的种类.并且通过拷贝这个原型来创建新的对象
* @author lzs
*
*/
/1**
*
* 声明一个克隆自身的接口,即抽象原型角色
* @author lzs
*
*/
interface Prototype
{
public function copy();
}
/1**
*
* 实现克隆自身的操作,具体原型角色
* @author lzs
*
*/
class ConcretePrototype implements Prototype
{
private $name;
function __construct($name)
{
$this->name = $name;
}
function getName()
{
return $this->name;
}
function setName($name)
{
$this->name = $name;
}
//克隆
function copy()
{
/1**
* 浅拷贝
*/
//return clone $this;
/1**
* 深拷贝
*/
$serialize_obj = serialize($this); //序列化
$clone_obj = unserialize($serialize_obj); //反序列化
return $clone_obj;
}
}
/1**
* 测试深拷贝的类
*/
class Test
{
public $array;
}
/1**
*
* 客户端
* @author lzs
*
*/
class Client
{
/1**
* 实现原型模式
*
* @return string 取出数据
*/
public static function main()
{
/1**
* 浅拷贝
*/
// $pro = new ConcretePrototype('prototype');
// $pro2 = $pro->copy();
// echo '1:'.$pro->getName().'
/>2:'.$pro2->getName();
/1**
* 深拷贝
*/
$test = new Test();
$test->array = array('1','2','3');
$pro1 = new ConcretePrototype($test);
$pro2 = $pro1->copy();
print_r($pro1->getName());
echo '
/>';
print_r($pro2->getName());
}
}
Client::main();
浅拷贝:
被拷贝对象的所有变量都含有与原对象相同的值,而且对其他对象的引用仍然是指向原来的对象。即浅拷贝只负责当前对象实例,对引用的对象不做拷贝。
深拷贝:
被拷贝对象的所有的变量都含有与原来对象相同的值,除了那些引用其他对象的变量。那些引用其他对象的变量将指向一个被拷贝的新对象,而不再是原有那些被引用对象。
即深拷贝把要拷贝的对象所引用的对象也都拷贝了一次,而这种对被引用到的对象拷贝叫做间接拷贝。深拷贝要深入到多少层,是一个不确定的问题。
在决定以深拷贝的方式拷贝一个对象的时候,必须决定对间接拷贝的对象是采取浅拷贝还是深拷贝还是继续采用深拷贝。
因此,在采取深拷贝时,需要决定多深才算深。此外,在深拷贝的过程中,很可能会出现循环引用的问题。
利用序列化来做深拷贝:
利用序列化来做深拷贝,把对象写到流里的过程是序列化(Serilization)过程,但在业界又将串行化这一过程形象的称为“冷冻”或“腌咸菜”过程;