首页 文章

服务定位器,依赖注入(和容器)和控制反转

提问于
浏览
12

我已经编程了一段时间但从未对理解每个概念的含义感兴趣,我可能正在使用各种编程概念,但却不知道它 .

Service Locator :对我来说,是指通过减少代码量来加快开发速度的快捷方式记录 . 一个问题是:可能Locator仅引用名称空间/类,或者我可以拥有变量注册表?

以下是我对它的理解:

$locator = new ServiceLocator()
$locator->set('app', new System\Application());
$locator->set('db', new System\Pdo());

// Get the objects
$locator->get('db')->connect();
$locator->get('app')->run();

Dependency Injection (and Dependency Injection Container) :在对象中注入对象,无论工厂模式如何,都可以更快地访问这些对象 . 和DI容器?

以下是我对它的理解:

$app = new System\Application(System\Config::load());

Inversion of Control :唐't understand this Design Pattern (or understand but don'知道我做的是IoC)

然后,在理论上(最好用简单的例子),这些概念中的每一个意味着什么?我是正确的,还是有什么不对/可以改进?

谢谢!

2 回答

  • 20

    我想您正确理解了服务定位器 .

    关于 Dependency Injection ,意味着如果一个对象具有构造函数和/或属性依赖关系,那么这些属性是由外部注入到对象中,而不是对象自己获取依赖关系

    public class MyClass
    {
       private $_dep;
       public function __construct($dep=null)
       {
           //$dep has to be injected
           $this->_dep=$dep;                           
       }
    
       //this is wrong because it couples MyClass to a specific Dependency implementation
       public function __construct()
       {
           $this->_dep=new Dependency();
        }
    }
       $dep=new Dependency();
       $obj=new MyClass($dep);
    

    通常构造函数将抽象(接口)作为param,并在类外部实例化一个具体的实现,然后在创建MyClass的新实例时将其传递给构造函数 .

    DI容器,自动处理依赖注入 . 您只需配置它,以便它知道在提出抽象时要返回的具体类 . Container处理对象创建,通过构造函数和/或属性注入依赖项 . 根据容器(我不知道php的一个例子,我只熟悉.net DI容器)你可能还需要注册它可以创建的对象类型 .

    Inversion of Control 意味着取决于较低级别类(依赖性)实现而不是更高级别的类,控件被反转,因此较低级别的类实现依赖于较高级别类所需的抽象 .

    //abstraction defined for the use of higher level class
    public interface  IRepository {}
    
    // that's the dependency, the lower level class  
    public class XmlRepository implements IRepository {}
    
    //the higher level class
     public class MyClass
     {
         public function __construct(IRepository $repo) {}
      }
    

    DI容器提供IoC功能时,IoC和DiC一起使用 .

  • 10

    服务位置和依赖注入首先用于解耦类,以便可以轻松地测试和更改它们 .

    当您将 IoC ContainerregisterresolveService Locator seems 进行比较时,它们是相同的 .

    您可以使用IoC容器作为服务定位器,这被认为是反模式 . 使用服务位置时,您始终必须在整个架构中主动调用服务定位器 . 所以你要解耦你的课程,但另一方面你将它们全部联系到服务定位器 . 此外,使用服务定位器进行依赖性发现更加困难,因为您隐藏了依赖项 . 而使用依赖注入,您可以使用构造函数注入使依赖项“公开” .

    使用IoC容器时,可以使用依赖注入(构造函数注入或属性注入) . 现在,IoC容器可以通过查看构造函数参数来重新调整依赖关系图,并创建整个依赖关系图 . 这叫做 auto-wiring . 服务定位器无法自动连接依赖项 . 正如我已经提到的,你不会被迫使用自动连接,你可以通过简单地直接在每个类中调用IoC容器来轻松地使用像服务定位器这样的IoC容器, BUT YOU SHOULD NOT

    另见:https://stackoverflow.com/a/11319026/175399

    enter image description here

相关问题