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