2

私は小さな MVC を構築していますが、解決したい疑問があります。

Dispatcher クラスがあり、そのクラスには HTTP Request、HTTP Response、および Router クラスが必要です。

次のような依存性注入を使用してこれを行うことができます。

$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

いずれかのアプローチに問題があるとは言い難いです。必要な仕様を満たしていない場合にのみ問題があります。

最初のアプローチが 2 番目のアプローチよりも好まれる理由は、注入できるものに柔軟性を持たせることができるからです。例えば:

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

Dispatcher2 番目の例では、クラスとそれが使用する 3 つすべてとの間に密結合が生じます。これに違反する特定の法律または原則を探している場合、それはオープン/クローズド原則になります。

PS:イベント ドリブン アーキテクチャを使用していると確信していますか? それがDispatcherが言及されているのを見つけた唯一のコンテキストだからです。

于 2012-11-09T21:47:27.430 に答える
0

2 番目の例は、他のオブジェクトを作成するため、Factoryサフィックスを付けて呼び出す必要があります。

どちらの例でも、高結合の Dispatcher オブジェクト (依存関係の反転)になります。

ディスパッチャーは、他のオブジェクトが実装/登録されているインターフェイスまたはサービスを要求するだけでよいはずです。

于 2012-11-09T22:01:47.003 に答える
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 に答える