欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

clone的原型模式(Prototype Pattern)

程序员文章站 2022-05-05 12:12:03
...

发邮件的功能想必都做过,发邮件相当的耗时,于是大多使用多线程来实现。但假设产生第一封邮件对象,放到线程1中运行,还没有发送出去,线程2也启动了,直接把邮件对象修改了,线程不安全了。在这里我使用原型模式来解决

<?php
class Mail{
	private $title;
	private $content;
	private $receiver;
	public function setTitle($title){
		$this->title = $title;
	}
	public function getTitle(){
		return $this->title;
	}
	public function setContent($content){
		$this->content = $content;
	}
	public function getContent(){
		return $this->content;
	}
	public function setReceiver($receiver){
		$this->receiver = $receiver;
	}
	public function getReveiver(){
		return $this->receiver;
	}
	public function sendMail(){
		echo "内容为:".$this->content."的邮件已发送至".$this->receiver."\n";
	}
}
$mail = new Mail();
$mail->setTitle('测试');
$i = 0;
while ($i<5) {//这里是例子,真实情况换为遍历用户
	$cloneMail = clone $mail;//克隆一个邮件对象
	$receiver = rand();
	$cloneMail->setReceiver($receiver);
	$cloneMail->setContent($receiver.'你好:......');
	$cloneMail->sendMail();
	$i++;
}
?>
运行结果:
内容为:32436你好:......的邮件已发送至32436
内容为:31453你好:......的邮件已发送至31453
内容为:22098你好:......的邮件已发送至22098
内容为:27939你好:......的邮件已发送至27939
内容为:21024你好:......的邮件已发送至21024
[Finished in 0.1s]

 通过克隆一个对象,可以将线程中的对象相隔离,因此互不影响。

 

 

原型模式的定义

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。太简单了,原型模式的核心是一个clone方法,通过该方法进行对象的拷贝,php5中提供了一个魔术方法__clone。

 

 

原型模式的优点

1、性能优良

原型模式是在内存二进制流的拷贝,要比直接new一个对象性能好很多,特别是要在一个循环体内产生大量的对象时,原型模式可以更好地体现其优点 。

2、逃避构造函数的约束

这既是它的优点也是缺点,直接在内存中拷贝,构造函数是不会执行的。优点就是减少了约束,缺点也是减少了约束,需要在实际应用中考虑

 

 

原型模式的使用场景

1、资源优化场景

类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等2

2、性能和安全要求的场景

通过new产生一个对象需要繁琐的数据准备或访问权限,则可以使用原型模式。

3、一个对象多个修改者的场景

一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型式拷贝多个对象供调用者使用。

在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过clone的方法创建一个对象,然后由工厂方法提供给调用者。

 

 

原型模式的注意事项

1、构造函数不会被执行

2、浅复制和深复制

使用clone来复制对象,这种复制叫做“浅复制”:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。也就是说,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。相对于浅复制,当然也有一个深复制:被复制的对象的所有的变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。也就是说,深复制把要复制的对象所引用的对象都复制了一遍。深复制需要决定深入到多少层,这是一个不容易确定的问题,此外可有会出现循环引用的问题,这些都必须小心处理。

3、clone和final两个冤家

尝试在类的一个成员变量加final,将会Cannot declare property Mail::$title final, the final modifier is allowed only for methods and classes这种类型的错误。要想使用clone方法,类的成员变量上不要增加final关键字