【问题标题】:Where do you put your dependencies?您将依赖项放在哪里?
【发布时间】:2012-04-26 19:41:50
【问题描述】:

如果我使用依赖注入模式来删除依赖项,它们最终会出现在其他地方。

例如,Snippet 1,或者我所说的 Object Maker。

我的意思是你必须在某个地方实例化你的对象......所以当你将依赖从一个对象中移出时,你最终会将它放到另一个对象中。

我看到这将我所有的依赖项合并到一个对象中。关键是要减少您的依赖关系,以便它们都驻留在一个(尽可能接近)位置吗?

片段 1 - 对象制作器

<?php

class ObjectMaker
{
    public function makeSignUp()
    {
        $DatabaseObject = new Database();
        $TextObject = new Text();
        $MessageObject = new Message();

        $SignUpObject = new ControlSignUp();        
        $SignUpObject->setObjects($DatabaseObject, $TextObject, $MessageObject);
        return $SignUpObject;
    }
    public function makeSignIn()
    {
        $DatabaseObject = new Database();
        $TextObject = new Text();
        $MessageObject = new Message();

        $SignInObject = new ControlSignIn();
        $SignInObject->setObjects($DatabaseObject, $TextObject, $MessageObject);
        return $SignInObject;
    }
    public function makeTweet( $DatabaseObject = NULL, $TextObject = NULL, $MessageObject = NULL )
    {
        if( $DatabaseObject == 'small' )
        {
            $DatabaseObject = new Database();
        }
        else if( $DatabaseObject == NULL )
        {
            $DatabaseObject = new Database();
            $TextObject = new Text();
            $MessageObject = new Message();
        }
        $TweetObject = new ControlTweet();        
        $TweetObject->setObjects($DatabaseObject, $TextObject, $MessageObject);
        return $TweetObject;
    }
    public function makeBookmark( $DatabaseObject = NULL, $TextObject = NULL, $MessageObject = NULL )
    {
        if( $DatabaseObject == 'small' )
        {
            $DatabaseObject = new Database();
        }
        else if( $DatabaseObject == NULL )
        {
            $DatabaseObject = new Database();
            $TextObject = new Text();
            $MessageObject = new Message();
        }

        $BookmarkObject = new ControlBookmark();        
        $BookmarkObject->setObjects($DatabaseObject,$TextObject,$MessageObject);
        return $BookmarkObject;
    }
}

【问题讨论】:

标签: php oop design-patterns dependency-injection


【解决方案1】:

就我个人而言,我更愿意在任何有意义的地方实例化对象,并在一个特殊的文档文件中很好地记录依赖关系。

【讨论】:

    【解决方案2】:

    问问自己,“这属于一起吗?”

    如果某物是您对象的“一部分”,那么可能是“是”。如果某物是“的属性”,那么是的。

    Keep it Simple :)

    我能提供的最佳指南是什么?来自 PHP 手册:

    http://www.php.net/manual/en/language.oop5.basic.php

    一个 PHP 类可以用于多种用途,但最基本的是 水平,您将使用课程来“组织和处理志同道合的人 数据”。

    PS: 在您首先需要它的地方创建一个对象。

    PPS: “将我所有的依赖项合并到一个对象中” ...如果您捆绑在一起的对象不一定彼此直接相关...可能是您可以做的最糟糕的事情。恕我直言...

    【讨论】:

      【解决方案3】:

      关键是要减少您的依赖关系,以便它们都驻留在一个(尽可能接近)位置吗?

      我认为基本上就是这样,是的。这个想法是使应用程序的组件松散耦合。这意味着您可以更轻松地重用组件、互换它们并针对它们进行测试。如果您有一个简单的应用程序,那么在需要的地方实例化对象当然效果很好。但随着它变得越来越复杂,具有多个嵌套依赖项,您的代码可能会变得紧密耦合,这意味着难以维护、调整和测试。

      【讨论】:

      • 这取决于你的代码的复杂性...在我开始使用它之前我已经写了大约 1200 行。
      【解决方案4】:

      不,它与整合您的依赖关系无关。它与使对象更具可测试性有关。

      是的,副作用是您的依赖项往往会出现在其他地方,但关键是依赖项不在您正在测试的对象中。

      如果您不在目标对象中创建依赖项,那么您可以实例化测试(或伪造或模拟)对象以输入目标对象。如果对象创建了自己的依赖项,那么这是不可能的。

      这样想。假设您有一个 Car 对象。如果汽车创造了司机,那么其他司机就无法驾驶它。它只能是 All Foo Car,因为您有一个硬编码的驱动程序。

      现在,假设我们开发了一个机器人来在专门设计的赛道上测试汽车。同样,我们不能把机器人放在驾驶座上,因为你会在那里被硬编码。

      当然,可测试性只是依赖注入的好处之一,强制解耦依赖意味着你必须编写更多模块化的代码。如果您使用的是依赖注入框架(Crafty 或类似框架),那么您可以根据需要使依赖项自动实例化,这有很多好处,但对于更强大的类型语言来说,这往往更有好处。

      【讨论】:

      • @TheAllFoo - 依赖项必须存在于某处,否则它们不是依赖项。它们不会实例化自己(尽管我上面说过,某些东西仍在创建它们)
      • 我把我所有的都放在了一个叫做 ObjectMaker 的文件里,刚刚贴出来(上面),我还需要抽象出共同的元素。
      【解决方案5】:

      引用Wikipedia

      在传统的软件开发中,依赖对象自己决定它将使用哪些具体类。在依赖注入模式中,这个决定被委托给“注入器”,它可以选择在运行时而不是在编译时替换依赖合约接口的不同具体类实现。

      DI 会导致某些类与不稳定类的耦合较少。注入的实例通常是接口的实现。 OCP 告诉实现中的更改不应该要求修改依赖于它们的封闭类。

      tl;dr 仅依赖于接口 I 的实现注入的 A 类更具凝聚力(责任更少)。其他一些类被困在选择、实例化等责任上,但该类也更具凝聚力。

      【讨论】: