今天篇文章,我们来介绍一下原型模式。
原型模式,通俗点来说就是允许我们复制一个可定制化的对象,而不用去考虑对象的实际创建过程。举个栗子:小明在最大的同性交友论坛看到某个开源的项目很适合自己新项目,然后就把该项目下载下来(可定制化的对象)拿过来,然后对里面配置进行修改(对对象进行定制化操作),开始做开发了。(1.这个例子够通俗吧;2.最大的同性交友论坛是github~)这个就是原型模式。
我们来看下代码:
我们首先需要有个原型:
class Art implements Prototype
{
private $_name;
public function __construct($name)
{
$this->_name = $name;
}
/**
* 设置名字
*
* @param $name
*/
public function setName($name)
{
$this->_name = $name;
}
/**
* 获取名字
*
* @return mixed
*/
public function getName()
{
return $this->_name;
}
/**
* 浅拷贝
*/
public function shallowCopy()
{
return clone $this;
}
/**
* 深拷贝
*/
public function deepCopy()
{
//对对象进行序列化
$serialize_obj = serialize($this);
//进行反序列化
$clone_obj = unserialize($serialize_obj);
return $clone_obj;
}
}
这个原型允许浅拷贝和深拷贝(这个要记住,我们待会讲)。
我们调用过程:
class Client
{
/**
* 浅拷贝
*/
public static function shallow()
{
$cd = new CD();
$cd->content = "music";
$music = new Art($cd);
$movie = $music->shallowCopy();
p('$music->getName()',$music->getName());
p('$movie->getName()',$movie->getName());
$cd->content = "movie";
p('$music->getName()',$music->getName());
p('$movie->getName()',$movie->getName());
}
/**
* 深拷贝
*/
public static function deep()
{
$cd = new CD();
$cd->content = "music";
$music = new Art($cd);
$movie = $music->deepCopy();
p('$music->getName()',$music->getName());
p('$movie->getName()',$movie->getName());
$cd->content = "movie";
p('$music->getName()',$music->getName());
p('$movie->getName()',$movie->getName());
}
}
这个里面有个CD的类,这个类不是原型模式必备的,我放在这里只是为了辅助大家理解什么是浅拷贝和深拷贝(好人一生平安~)。
CD类如下:
class CD
{
public $content;
}
执行结果:
*******
$music->getName()=
object(CD)#2 (1) {
["content"]=>
string(5) "music"
}
*******
$movie->getName()=
object(CD)#2 (1) {
["content"]=>
string(5) "music"
}
*******
$music->getName()=
object(CD)#2 (1) {
["content"]=>
string(5) "movie"
}
*******
$movie->getName()=
object(CD)#2 (1) {
["content"]=>
string(5) "movie"
}
*******
$music->getName()=
object(CD)#4 (1) {
["content"]=>
string(5) "music"
}
*******
$movie->getName()=
object(CD)#5 (1) {
["content"]=>
string(5) "music"
}
*******
$music->getName()=
object(CD)#4 (1) {
["content"]=>
string(5) "movie"
}
*******
$movie->getName()=
object(CD)#5 (1) {
["content"]=>
string(5) "music"
}
这个例子中的movie是music对象的拷贝,在创建movie的过程中,不用考虑movie对象的创建过程,只需要使用movie对象即可。
同时,我们也注意到结果中,$movie->getName()和$music->getName()的不同,这个里面涉及另外要注意的问题:浅拷贝和深拷贝;
浅拷贝:被拷贝对象的所有变量都含有与原对象相同的值,并且对其他对象的引用(对象的地址)也是一致的,换句话说:浅拷贝只负责当前对象实例,对引用的对象不做拷贝。所以我们修改原来music对象的时候,也会修改movie对象中相应的值。
深拷贝:被拷贝对象的所有的变量都含有与原来对象相同的值,但是那些引用其他对象的变量将指向一个被拷贝的新对象,而不再是原来那些被引用的对象。即深拷贝把要拷贝的对象所引用的对象也拷贝了一次(也叫做间接拷贝)。
原型模式是先创建好一个原型对象,然后通过clone原型对象来创建新的对象。这种模式特别适合复杂对象的创建,如果复杂对象每次new就会消耗很大,原型模式仅需内存拷贝即可。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。