依赖注入/ LoD

时间:2014-10-17 12:07:11

标签: php class object dependency-injection

我理解依赖注入的基本原则,但是想要了解如何处理在其他类方法中实例化的类;这会违反依赖注入模式吗?

此外,我想将对象(类)写入DB(对象形式的mongo),因此不希望它与其他依赖项一起膨胀。

为了更好地解释我的意思,这里有一个例子:

假设我们有一个注入了服务器类的用户类 -

class User{
    public $user_id
    public $user_name;

    public function __construct(server $server){
        $this->server = $server;
    }

    public function delete(){
        //...delete user code

        // Send mail to user
        $mailer = new mailer($this->server);
        $mailer->sendMail();
    }

}

关于这个的两件事

  1. 这意味着User类现在变得臃肿,因为它也包含服务器类
  2. 这会违反得墨忒耳法吗?因为User类实际上不需要Server类而不是将它传递给Mailer类。
  3. 我理解解决这个问题的方法是在从外部控制器调用时将邮件程序类注入delete函数,这意味着User类永远不必注入服务器类:

    $server = new server();
    $mailer = new mailer($server);
    $user = new User();
    $user->delete($mailer);
    
    class User{
        public $user_id
        public $user_name;
    
        public function __construct(){
            // other code
        }
    
        public function delete(mailer $mailer){
            //...delete user code
    
            // Send mail to user          
            $mailer->sendMail();
        }
    
    }
    

    但是这肯定意味着你需要知道一个类中方法所需的每个类,如果这个嵌套变得很深,那肯定很难跟踪。

    如果user-> delete是私有方法,会发生什么?您将无法从外部控制器调用它来传入邮件程序对象。

    所以我的问题是什么才是最好的解决方法?

1 个答案:

答案 0 :(得分:0)

对我而言,依赖于某个对象是一种气味,这样你就可以构建一个不同的对象。

而是依赖于您要构造的对象。因此,在您的情况下,只需将邮件传递给您的User构造函数,然后您就不需要创建邮件程序而且您不需要关心服务器。

这里你的User依赖于邮件程序(进行邮件发送),所以这是应该注入的东西。

您的对象应该只创建叶对象/数据持有者/ DTO的新实例。任何提供任何功能(即服务)的东西都应该注入需要使用该功能的对象中。

修改

我不做PHP,但我认为你的用户类应该更像这样:

class User{
    public $user_id
    public $user_name;

    public function __construct(mailer $mailer){
        $this->mailer = $mailer;
    }

    public function delete(){
        //...delete user code

        // Send mail to user
        $this->mailer->sendMail();
    }    
}

至于通过构造函数注入vs传入方法,这归结为期望User的用户在想要删除用户时提供邮件是否合理。对我而言,它听起来并不像是,所以我会把它传递给构造函数。