单例即一个类是能有一个实例,并提供一个当前类的全局唯一访问入口(getInstance)。防止类被多次实例化和clone,拥有单例带来好处的同时,也会失去在其他地方带来的不便。可能你们还是不懂,我就来举个发送邮件例子,smtp是可以设置自己账号作为发送邮件账号的,只需开启邮件密码就可以编写发送邮件代码,伪代码如下:
class Mail | |
{ | |
private static $instance = null; | |
public function __construct(string $driver = 'smtp', array $config) | |
{ | |
if (!isset(self::$instance[$driver]) | |
self::$instance[$driver] = new self($driver, $config); | |
} | |
return self::$instance[$driver]; | |
} | |
public function to(string $emai) { | |
// todo... | |
} | |
} | |
$senders = [ | |
[ | |
'driver' => 'smtp', | |
'name' => '小明', | |
'email' => 'xiaoming@qq.com', | |
'password' => '123456', | |
], | |
[ | |
'driver' => 'smtp', | |
'name' => '小华', | |
'email' => 'xiiaohua@qq.com', | |
'password' => '123456', | |
] | |
]; | |
foreach($senders as $sender) { | |
$mail = new Mail($sender['driver'],config('mail')); | |
$mail->to('wanger@qq.com')->send(); | |
} |
看到这样的代码就知道一眼看上了问题所在了吧,执行小明发送是没有问题的,但是轮到小华发送的时候其实延用了小明的smtp邮件发送。单例带来的不便就显现出来了吧。当然避开这个抗也是挺方便的,我们观察一下容易发现,其实是邮件的发送者不同,我们可以改造一下代码, 将配置文件作为参数传递,问题就得到解决:
class Mail | |
{ | |
private static $instance = null; | |
public function __construct(string $driver = 'smtp') | |
{ | |
if (!isset(self::$instance[$driver]) | |
self::$instance[$driver] = new self($driver); | |
} | |
return self::$instance[$driver]; | |
} | |
public function to(string $emai) { | |
// todo... | |
} | |
public function config(array $config) { | |
// todo... | |
} | |
} | |
// 调用就改为 | |
foreach($senders as $sender) { | |
$mail = new Mail($sender['driver']); | |
$mail->config($send['config'])->to($send['mail'])->send(); | |
} |