1.控制反转(IOC)
使用IOC的:
优点:消除对象之间的耦合关系,提高代码的灵活性,从而加快开发速度,提升代码质量
缺点:在真实框架中,由于会使用反射机制,会降低代码的运行速度,如果对速度很敏感,就不适合使用IOC了.
以下是我整理的注释加强印象加深版代码,其中的bind其实就是工厂模式的一种体现
<?php class Superman{ function __construct($skill){ //print_r($skill); } } class XPower{ function __construct(){ //echo __CLASS__.PHP_EOL; } } class Container { protected $binds; protected $instances; public function bind($abstract, $concrete) { if ($concrete instanceof Closure) { $this->binds[$abstract] = $concrete; } else { $this->instances[$abstract] = $concrete; } } //make方法其实是传入参数,调用已经绑定的闭包/方法,为什么使用call_user_func_array?因为参数个数未知,使用call_user_func_array会更灵活 public function make($abstract, $parameters = []) { if (isset($this->instances[$abstract])) { return $this->instances[$abstract]; } array_unshift($parameters, $this);//必须有一个container参数,因为很有可能在make时使用container return call_user_func_array($this->binds[$abstract], $parameters); } } // 创建一个容器(后面称作超级工厂) $container = new Container; // 向该 超级工厂 添加 超人 的生产脚本(告诉容器待会如何生产对象) $container->bind('superman', function($container, $moduleName) { return new Superman($container->make($moduleName)); }); // 向该 超级工厂 添加 超能力模组 的生产脚本(告诉容器待会如何生产对象) $container->bind('xpower', function($container) { return new XPower; }); // ****************** 华丽丽的分割线 ********************** // 开始启动生产 $superman_1 = $container->make('superman', ['xpower']);//生产对象,用的是刚刚绑定的方法
2.单例模式
在整个应用生命周期内,对某个类,只实例化一次,应用场景为:连接数据库,记录日志,使用单例模式可以避免不必要的资源消耗
<?php class Singleton{ private static $obj=null; private function __construct(){} private function __clone(){} static function getInstance(){ if(!self::$obj){ self::$obj=new self; } return self::$obj; } } $res=Singleton::getInstance(); $res2=Singleton::getInstance(); $res3=Singleton::getInstance(); var_dump($res); var_dump($res2); var_dump($res3);
3.工厂模式
工厂模式用于生产对象,在最原始的代码中,如果一个对象obj1需要另一个对象obj2,通常是在obj1内部new一个obj2,但是这种硬性的编码很不灵活,比如因需求改变,要使用另一个和obj2功能类似的obj3,或者obj2修改了类名,这样会使代码改动很大
使用工厂模式,可以让obj1只使用工厂Factory得到对象obj2,obj3,obj4...
工厂模式解除了obj1与obj2的耦合关系,使代码便于修改.实现了低耦合.
在上面例1中IOC容器的binds属性,其实就是工厂模式的体现.通过对ioc容器对象bind方法的调用,得到了许多小车间(new各种类的闭包函数),车间装载完毕,在使用make方法时就会根据参数使用相应车间..
4.观察者模式
将触发事件(发布者)与发生事件后需要执行的动作(订阅者需要做的动作)解耦
目的:代码更灵活,大大提升可维护性
<?php /** * Created by PhpStorm. * User: zhudong * Date: 16/8/11 * Time: 下午4:02 */ class Newspaper implements SplSubject { private $name; private $observers; private $content; public function __construct($name){ $this->$name = $name; $this->observers = new SplObjectStorage(); } public function attach(SplObserver $observer){ $this->observers->attach($observer); } public function detach(SplObserver $observer){ $this->observers->detach($observer); } public function notify(){ foreach ($this->observers as $observer) { $observer->update($this); } } public function getContent(){ return $this->content."{$this->name}"; } public function breakOutNews($content) { $this->content = $content; $this->notify(); } } //不同的观察者,对新闻做出不同的反应,此处举例Reader和Reader2 class Reader implements SplObserver { private $name; public function __construct($name){ $this->name = $name; } public function update(SplSubject $subject) { echo $this->name.' received breakout news'.$subject->getContent().'and say 不错~~'.PHP_EOL; } } class Reader2 implements SplObserver { private $name; public function __construct($name){ $this->name = $name; } public function update(SplSubject $subject) { echo $this->name.' received breakout news'.$subject->getContent().'and say 垃圾!'.PHP_EOL; } } $newspaper = new Newspaper('齐鲁晚报'); $allen = new Reader("allen"); $jimmy = new Reader("mike"); $tom = new Reader2("tom"); $jerry = new Reader2("jerry"); $newspaper->attach($allen); $newspaper->attach($jimmy); $newspaper->attach($tom); $newspaper->attach($jerry); $newspaper->detach($jerry); $newspaper->breakOutNews('本报讯...');
参考资料