2

我正在构建小型MVC,并且有一些疑问想要解决。

我有调度程序类,该类需要 HTTP 请求、HTTP 响应和路由器类。

我可以使用依赖注入来做到这一点,例如:

$dispatcher = new Dispatcher($request, $response, $router);

现在可以说我不喜欢这种方法,并且想在 Dispatcher 类中使用这样的类:

class Dispatcher()
{
    protected $request;
    protected $response;
    protected $router;

    public function __construct()
    {
        $this->request = new Request();
        $this->response = new Response();
        $this->router = new Router();
    }
}

2方法有什么问题吗?我是否在阻止一些 OOP 原则?还是以这种方式使用它就可以了?

4

4 回答 4

1

很难说一种方法或另一种方法有什么问题。只有当它不符合要求的规格时,它才是错误的。

第一种方法优于第二种方法的原因是因为它允许您灵活地选择可以注入的内容。例如:

class Dispatcher {
   private $req;
   public function __construct(IRequest $req) {
      $this->req = $req;
   }
}
interface IRequest {}
class Request implements IRequest {}
class MockRequest implements IRequest {}

//PRODUCTION
new Dispatcher(new Request);
//TESTING
new Dispatcher(new MockRequest);
于 2012-11-09T21:31:42.907 回答
0

第二个示例应该使用Factory后缀调用,因为它会创建其他对象。

在这两个示例中,您最终都会得到一个高耦合的 Dispatcher 对象(依赖反转

Dispatcher 应该能够只请求其他对象实现/注册到的接口或服务。

于 2012-11-09T22:01:47.003 回答
0

第二个示例导致Dispatcher该类与其使用的所有 3 个类之间的紧密耦合。如果您正在寻找违反此规定的特定法律或原则,那将是开放/封闭原则

PS:你确定你使用的是事件驱动架构吗?因为这是我发现Dispatcher提到的唯一上下文。

于 2012-11-09T21:47:27.430 回答
0

您应该使用 DI 是有原因的:依赖注入从您的代码中删除依赖项并将它们抽象给调用者。这也使得对代码进行单元测试变得更加容易,因为代码本身并不需要外部依赖来运行。

这在一个例子中得到了最好的证明。想象一下,如果您的课程需要数据库连接:

class Dispatcher()
{
    protected $db

    public function __construct() {
        $this->db = new MysqlDB();
    }
}

现在,你只是强迫每个人都使用 MySQL 数据库。但是,如果你使用了 DI,你可以抽象出数据库的细节,只依赖一些代表数据库对象的类:

class Dispatcher()
{
    protected $db

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

然后,定义一些代表不同数据库连接的对象:

interface Database {
    public function query( $sql);
}

class MySQLDB implements Database {
    public function query( $sql) { // Stuff for MySQL 
    }
}

class OracleDB implements Database {
    public function query( $sql) { // Stuff for Oracle 
    }
}

现在,您的用户是否这样做:

$dispatcher = new Dispatcher( new MysqlDB());

或者:

$dispatcher = new Dispatcher( new OracleDB());

没关系 - 两个数据库都可以重用同一个类。

于 2012-11-09T21:37:44.313 回答