hp设计模式中Ioc(控制反转)和Di(依赖注入)主要是为了程序的解耦用的,网上找了一下资料,文章都是复制来复制去,没有什么价值,感觉最有价值的文章
推荐文章:http://www.51glacier.com/blog/Container.html

下面的laravel中的使用
Laravel容器的简化版,中间加了注释,不懂可以加群讨论


  1. <?php
  2. interface Visit{
  3. public function go();
  4. }
  5. class Leg implements Visit{
  6. public function go(){
  7. echo 'walt to Tibet!!!';
  8. }
  9. }
  10. class Car implements Visit{
  11. public function go(){
  12. echo "drive car to Tibet!!!";
  13. }
  14. }
  15. class Train implements Visit{
  16. public function go(){
  17. echo "go to Tibet by train!!!";
  18. }
  19. }
  20. class Container{
  21. protected $bindings=[];
  22. //全局变量保持闭包函数
  23. public function bind($abstract,$concrete=null,$shared=false){
  24. //如果这个不是一个闭包函数,就用getClosure创建一个闭包函数
  25. if(!$concrete instanceof Closure){
  26. $concrete=$this->getClosure($abstract,$concrete);
  27. }
  28. //保存成多位数组
  29. $this->bindings[$abstract]=compact('concrete','shared');
  30. }
  31. //生成一个闭包函数
  32. protected function getClosure($abstract,$concrete){
  33. //这里的$c对应build方法$concrete($this);中的this
  34. return function($c) use($abstract,$concrete){
  35. $method=($abstract==$concrete)?'build':'make';
  36. return $c->$method($concrete);
  37. };
  38. }
  39. public function make($abstract){
  40. $concrete=$this->getConcrete($abstract);
  41. //判断是否是一个闭包函数
  42. if($this->isBuildable($concrete,$abstract)){
  43. //是一个闭包函数就实例化
  44. $object=$this->build($concrete);
  45. }else{
  46. $object=$this->make($concrete);
  47. }
  48. return $object;
  49. }
  50. //判断是否是一个闭包函数
  51. protected function isBuildable($concrete,$abstract){
  52. return $concrete===$abstract||$concrete instanceof Closure;
  53. }
  54. //判断全局变量$this->bindings里有没有注入这个类
  55. protected function getConcrete($abstract){
  56. if(!isset($this->bindings[$abstract])){
  57. return $abstract;
  58. }
  59. return $this->bindings[$abstract]['concrete'];
  60. }
  61. //用反射的方式实例化类
  62. public function build($concrete){
  63. //如果是一个闭包函数就直接返回
  64. if($concrete instanceof Closure){
  65. return $concrete($this);
  66. }
  67. //反射实例化类
  68. $reflector=new ReflectionClass($concrete);
  69. //反射的方式判断类是否可以实例化
  70. if(!$reflector->isInstantiable()){
  71. echo $message="Target [$concrete] is not instantiable.";
  72. }
  73. //判断有没有构造函数
  74. $constructor=$reflector->getConstructor();
  75. //如果没有构造函数就直接实例化
  76. if(is_null($constructor)){
  77. return new $concrete;
  78. }
  79. //反射构造函数的参数
  80. $dependencies=$constructor->getParameters();
  81. $instances=$this->getDependencies($dependencies);
  82. return $reflector->newInstanceArgs($instances);
  83. }
  84. protected function getDependencies($parameters){
  85. $dependencies=[];
  86. foreach($parameters as $parameter){
  87. //反射方式参数的接口比如Traveller类中的$trafficTool的变量必须是Visit这个类型的
  88. $dependency=$parameter->getClass();
  89. if(is_null($dependency)){
  90. $dependencies[]=NULL;
  91. }else{
  92. //如果要有限制的参数,在注入这个类
  93. $dependencies[]=$this->resolveClass($parameter);
  94. }
  95. }
  96. return (array)$dependencies;
  97. }
  98. protected function resolveClass(ReflectionParameter $parameter){
  99. return $this->make($parameter->getClass()->name);
  100. }
  101. }
  102. class Traveller{
  103. protected $trafficTool;
  104. public function __construct(Visit $trafficTool)
  105. {
  106. $this->trafficTool=$trafficTool;
  107. }
  108. public function visitTibet(){
  109. $this->trafficTool->go();
  110. }
  111. }
  112. $app=new Container();
  113. $app->bind("Visit","Train");
  114. $app->bind("traveller","Traveller");
  115. $tra=$app->make("traveller");
  116. $tra->visitTibet();

容器是laravel的核心知识点,看懂这一块内容感觉又牛逼了点


相关评论(0)
您是不是忘了说点什么?

友情提示:垃圾评论一律封号...

还没有评论,快来抢沙发吧!