PHP中的办事容器与依赖注入的思想
当A类需要依靠于B类,也就是说需要在A类中实例化B类的对象来使用时候,假如B类中的功效发生改动,也会致使A类中使用B类的地方也要跟着修改,致使A类与B类高耦合。这个时候解决方式是,A类应当去依靠B类的接口,把详细的类的实例化交给外部。
就拿我们业务中常用的通知模块来说。
<?php /** * 定义了一个新闻类 * Class Message */ class Message{ public function seed() { return 'seed email'; } } /* * 订单发生的时候 需要发送新闻 */ class Order{ protected $messager = ''; function __construct() { $this->messager = new Message(); } public function seed_msg() { return $this->messager->seed(); } } $Order = new Order(); $Order->seed_msg();
上面的代码是我们传统的写法。第一由个新闻发送的类。然后在我们需要发送新闻的地方,调取发送新闻的接口。有一天你需要增加一个发送短信的接口以知足不一样的需求。那么你会发明你要再Message类里面做修改。一样也要再Order类里面做修改。这样就显得很费事。这个时候就有了依靠注入的思绪。下面把代码做一个调整
<?php /** * 为了束缚我们先定义一个新闻接口 * Interface Message */ interface Message{ public function seed(); } /** * 有一个发送邮件的类 * Class SeedEmail */ class SeedEmail implements Message { public function seed() { return 'seed email'; // TODO: Implement seed() method. } } /** *新增一个发送短信的类 * Class SeedSMS */ class SeedSMS implements Message { public function seed() { return 'seed sms'; // TODO: Implement seed() method. } } /* * 订单发生的时候 需要发送新闻 */ class Order{ protected $messager = ''; function __construct(Message $message) { $this->messager = $message; } public function seed_msg() { return $this->messager->seed(); } } //我们需要发送邮件的时候 $message = new SeedEmail(); //将邮件发送对象作为参数传递给Order $Order = new Order($message); $Order->seed_msg(); //我们需要发送短信的时候 $message = new SeedSMS(); $Order = new Order($message); $Order->seed_msg();
这样我们就实现了依靠注入的思绪,是不是很利便扩展了。
效劳容器
我懂得的效劳容器就是一个主动发生类的工厂。
<?php /** * 为了束缚我们先定义一个新闻接口 * Interface Message */ interface Message{ public function seed(); } /** * 有一个发送邮件的类 * Class SeedEmail */ class SeedEmail implements Message { public function seed() { return 'seed email'; // TODO: Implement seed() method. } } /** *新增一个发送短信的类 * Class SeedSMS */ class SeedSMS implements Message { public function seed() { return 'seed sms'; // TODO: Implement seed() method. } } /** * 这是一个简便的效劳容器 * Class Container */ class Container { protected $binds; protected $instances; public function bind($abstract, $concrete) { if ($concrete instanceof Closure) { $this->binds[$abstract] = $concrete; } else { $this->instances[$abstract] = $concrete; } } public function make($abstract, $parameters = []) { if (isset($this->instances[$abstract])) { return $this->instances[$abstract]; } array_unshift($parameters, $this); return call_user_func_array($this->binds[$abstract], $parameters); } } //创立一个新闻工厂 $message = new Container(); //将发送短信注册绑定到工厂里面 $message->bind('SMS',function (){ return new SeedSMS(); }); //将发送邮件注册绑定到工厂 $message->bind('EMAIL',function (){ return new SeedEmail(); }); //需要发送短信的时候 $SMS = $message->make('SMS'); $SMS->seed();
container是一个简便的效劳容器里面有bind,make两个办法
bind是向容器中绑定效劳对象。make则是沉着器中取出对象。
bind
在bind办法中需要传入一个 concrete 我们可以传入一个实例对象或者是一个闭包函数。
可以看到我这全使用的是闭包函数,其实也可以这样写
$sms = new SeedSMS(); $message->bind('SMS',$sms);
后面这种写法与闭包比拟的不同就是我们需要先实例化对象才能往容易中绑定效劳。而闭包则是我们使用这个效劳的时候才去实例化对象。可以看出闭包是有许多的优势的。
make
make办法就沉着器中出去办法。里面第一推断了instances变量中可否有当前乃至存在的效劳对象,假如有直接返回。假如没有那么会通过 call_user_func_array返回一个对象.
更多的PHP相关知识,请拜访PHP中文网!
以上就是PHP中的效劳容器与依靠注入的思想的具体内容,更多请关注百分百源码网其它相关文章!