PHP中的依赖注入 - 简单的示例审查

时间:2012-10-15 12:21:31

标签: php oop

我是OOP的新手,我最近有asked question,这让我很满意:

  • 每个“操作”都应该在单独的类中实现,
  • 我遇到的问题应该通过依赖注入
  • 来解决
  • 一定不能为整个应用程序提供一个对象。

假设我有以下代码:

class FtpConnect {
     public $server;

     private function connect () { ... }

     public __construct ($db, $mailer, $server) {
         $this->server = $server;
         $this->connect();
     } 
}

class Database {
    public $database_property;
    ...
}

class Phpmailer {
    public $phpmailer_property;
    ...
}

$db = new Database();
$mail = new Phpmailer();

$ftp = new Ftpconnect ($db, $mail, "ftp.mozilla.org");

$ftp->db->database_property;
$ftp->mail->phpmailer_property;

这是一种正确的方法吗?我似乎还有一个对象$ftp

读取属性或调用像$ftp->db->database_property;这样的方法这是正确的方法吗?

2 个答案:

答案 0 :(得分:4)

你的例子中有一些好东西和一些坏东西!首先,祝贺您认真学习良好的编程实践。你正朝着正确的方向前进!

好东西:

  • 您正在使用正确的构造函数注入(DI的形式),因此您只在示例的最高级别编写new语句而在类中没有。
  • 你为每个不同的服务写了一个课,很棒。

坏事:

  • 您正在通过ftp实例访问db和mail的属性,请不要这样做!
  • 您正在使用公共属性,将属性设为私有,并使用公共getter和setter
  • 你在构造函数中调用main方法,不要这样做,你不应该在类中调用它,而是在外面调用它。
  • 你没有对传递给ftp实例的$ mailer实例做任何事情,ftp类真的需要邮件程序类吗?

改进示例,假设您的ftp类确实需要数据库和邮件:

class FtpConnect {

     private $db;
     private $mailer;

     private $server;

     public function connect () { ... }

     public __construct ($db, $mailer, $server) {
         $this->setServer($server);
         $this->setMailer($mailer);
         $this->setDb($db);
     }

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

     public setDb($db)
     {
         $this->db = $db;
     }

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

class Database {
    private $databaseProperty;
    public getDatabaseProperty()
    {
        return $this->databaseProperty;
    }
}

class Phpmailer {
    private $phpmailerProperty;
    public ... see above...
}

$db = new Database();
$mail = new Phpmailer();

$ftp = new FtpConnect ($db, $mail, "ftp.mozilla.org");
$ftp->connect();

$someProperty = $db->getDatabaseProperty();

答案 1 :(得分:0)

你的构造函数默默地丢弃除传递给它的第三个参数之外的所有内容。为什么要在dbp中放置db对象?这看起来有点奇怪。

除此之外,您已经初始化了db / mail对象的变量,因此您应该使用它们(减少链接使代码更容易阅读)或者写下这样的内容:$ftp = new Ftpconnect (new Database, new Phpmailer, "ftp.mozilla.org");不要使代码更多然后它必须是模糊的。

不要给ftp对象提供它不会使用的内容。此外,如果您尝试访问的属性不是特定于实例的(在该类的所有对象中它将是相同的),您应该使用类常量或静态变量