我们希望整个工程项目中,DB类,Session类,FileSystem类“拿来即用”,不用每次繁琐的初始化,比如写$db=new DB(arg1,arg2);这类语句,也希望DB等类型的对象像一个“全局”变量一般,在整个程序运行期间,随时可以调用。
服务容器可以让调用DB等类型的程序员不用知道这个类太多的细节,甚至可以用一个字符串的别名来创建这样一个对象。
我们定义一个服务容器类
class Container{ public $bindings; public function bind($abstract,$concrete){ $this->bindings[$abstract]=$concrete; } public function make($abstract,$parameters=[]){ return call_user_func_array($this->bindings[$abstract],$parameters); } }
可以把服务容器简单的看成一个全局变量,bind方法就是用关联数组把字符串和构造函数做绑定。
至此,有了服务容器,我们的Model类就要做修改了
class Model implements IModel{ public static $table; public static $container; public static $db; public function __construct(){ self::$container=new Container(); self::$container->bind('db',function(){ return MySQL::getInstance(); }); self::$db=self::$container->make('db',[]); } public static function get($id){ return self::where('id',$id); } public static function where($condition,$value){ $sql=sprintf("select * from %s where %s='%s'",self::$table,$condition,$value); return self::$db->Query($sql); } public static function all(){ $sql=sprintf("select * from %s",self::$table); return self::$db->Query($sql); } }
观察上面代码,我们同时用了单例模式和服务容器。
总结:如果要做一个PHP框架,应该要做好代码的复用。设计模式一直是很多争论的焦点,“究竟该不该使用设计模式?”,本文开始,我也努力回避“过于纠结这个问题”,我认为,设计模式有其存在的价值,至少在具体项目中,确实在很多版本迭代中节省了工作量,提高工作效率,但是如果在一个小项目中为了“秀一下我会设计模式”而使用设计模式,就不合理了。
您可能感兴趣的文章: