13

CrawlerInterface実装PageCrawlerとのインターフェースがあるとしFeedCrawlerます; コントローラーで両方のクラスが必要になった場合、コンストラクター インジェクションを使用してそれをどのように実現できますか?

以前は、このようなクラスServiceProviderを登録 (つまりApp::bind) するためにセントラルを使用していましたが、ほとんどの場合、インターフェイスの実装は 1 つしかないため、この問題はまだ発生していません。

PS: この問題は、コントローラーを分割する必要があることを示しているのでしょうか。


アップデート:

コメントと応答をありがとう、説明するために、インターフェイスにはパブリックメソッドが1つしかなくcrawl($uri)、ページ/フィードクローラーの両方がそれを次のように実装していますgiven a resource identifier, return resource.


私のフォローアップの質問:

calculator足し算、引き算、掛け算が同じインターフェイスを共有し、Operationパブリック メソッドが 1 つしかないシナリオにいるとします。あるrun時点で、まだこの問題に遭遇するでしょうか? 一般に、このような状況を でどのように処理しServiceProviderますか?

4

3 に答える 3

14

各クローラーが異なる理由で存在する場合は、インスタンスに任意の名前を使用できます。次に例を示します。

App::bind('crawler.allArticles', 'PageCrawler');
App::bind('crawler.latestArticles', 'FeedCrawler');

コントローラーの場合:

App::bind('CrawlerController', function($app) {
    return new CrawlerController(
        App::make('crawler.allArticles'),
        App::make('crawler.latestArticles')
    );
});

コントローラー コードは、各クローラーを異なる方法で使用します。

public function showLatestArticlesAction()
    $latestArticles = $this->latestArticlesCrawler->crawl();
    // ...
}

public function showAllArticlesAction()
    $allArticles = $this->allArticlesCrawler->crawl();
    // ...
}

それぞれが同じ目的で使用されるクローラーのリストがある場合は、おそらく次のようなことを行います。

App::bind('crawlers', function($app) {
    return [
        App::make('PageCrawler'),
        App::make('FeedCrawler'),
    ];
});

コントローラーで、次のように構成することで「クローラー」のリストを取得します。

App::bind('CrawlerController', function($app) {
    return new CrawlerController(App::make('crawlers'));
});

コントローラーのコードは次のようになります。

public function showArticlesAction()
    $allArticles = array();
    foreach ($this->crawlers as $crawler) {
        $allArticles = array_merge($allArticles, $this->crawler->crawl());
    }
    // ...
}
于 2013-10-14T20:44:21.383 に答える
3

この場合、インターフェースは役に立たないと思います。

行うことによって:

App::bind('CrawlerInterface', '<implementation>');

次のいずれかを選択する必要があります。

App::bind('CrawlerInterface', 'PageCrawler');

また

App::bind('CrawlerInterface', 'FeedCrawler');

そして、Laravelはそれを注入します:

class CrawlerController {

    public function __construct(CrawlerInterface $crawler)
    {
    }

}

両方を持つには、2 つのオプションがあります

- 2 つの異なるインターフェイスを持つ

-実装を直接注入します。

class CrawlerController {

    public function __construct(PageCrawler $pageCrawler, FeedCrawler $feedCrawler)
    {
    }

}

しかし、このようなものが必要な場合は、ロジックを再考したほうがよいと思います.

于 2013-10-14T18:53:02.367 に答える