bit*_*inn 13 php dependency-injection simplepie laravel laravel-4
说我有一个接口CrawlerInterface与实现PageCrawler和FeedCrawler; 如果我们碰巧在控制器中需要两个类,那么如何通过构造函数注入实现?
以前我们使用中心ServiceProvider来注册(即App::bind)这样的类,但在大多数情况下我们只有一个接口的实现,所以这个问题还没有发生在我们身上.
PS:我也想知道这个问题是否表明我们应该拆分控制器.
更新:
感谢您的评论和回复,解释说,界面只有一个公共方法:crawl($uri),并且页面/提要抓取工具都将其实现为given a resource identifier, return resource.
我的后续问题:
假设我们处于calculator加法,减法和乘法共享同一个接口的情况下Operation,它只有一个公共方法run,在某些时候我们仍然会遇到这个问题吧?我们如何处理这些情况ServiceProvider?
Mat*_*oli 13
如果每个爬网程序由于其他原因而存在,则可以为实例使用任意名称,例如:
App::bind('crawler.allArticles', 'PageCrawler');
App::bind('crawler.latestArticles', 'FeedCrawler');
Run Code Online (Sandbox Code Playgroud)
对于控制器:
App::bind('CrawlerController', function($app) {
return new CrawlerController(
App::make('crawler.allArticles'),
App::make('crawler.latestArticles')
);
});
Run Code Online (Sandbox Code Playgroud)
然后,您的控制器代码将使用不同的爬虫:
public function showLatestArticlesAction()
$latestArticles = $this->latestArticlesCrawler->crawl();
// ...
}
public function showAllArticlesAction()
$allArticles = $this->allArticlesCrawler->crawl();
// ...
}
Run Code Online (Sandbox Code Playgroud)
如果您只有一个爬虫列表,其中每个爬虫都用于相同的事情,您可能想要做类似的事情:
App::bind('crawlers', function($app) {
return [
App::make('PageCrawler'),
App::make('FeedCrawler'),
];
});
Run Code Online (Sandbox Code Playgroud)
在您的控制器中,您将通过配置它来获得"爬虫"列表:
App::bind('CrawlerController', function($app) {
return new CrawlerController(App::make('crawlers'));
});
Run Code Online (Sandbox Code Playgroud)
您的控制器代码可能是这样的:
public function showArticlesAction()
$allArticles = array();
foreach ($this->crawlers as $crawler) {
$allArticles = array_merge($allArticles, $this->crawler->crawl());
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
好吧,假设你有一个 CrawlerController
class CrawlerController extends BaseController
{
protected $crawler1;
protected $crawler2;
public function __construct(CrawlerInterface $c1, CrawlerInterface $c2)
{
$this->crawler1 = $c1;
$this->crawler2 = $c2;
}
}
Run Code Online (Sandbox Code Playgroud)
一个界面
interface CrawlerInterface{}
Run Code Online (Sandbox Code Playgroud)
和intefrace的具体实现叫做PageCrawler和FeedCrawler
class PageCrawler implements CrawlerInterface{}
class FeedCrawler implements CrawlerInterface{}
Run Code Online (Sandbox Code Playgroud)
您可以通过编写服务定位器来注入依赖项
App::bind('CrawlerController', function($app) {
$controller = new CrawlerController(
new PageCrawler,
new FeedCrawler
);
return $controller;
});
Run Code Online (Sandbox Code Playgroud)
但正如其他人所建议的那样,你应该重新思考你的逻辑,只有在这种架构不可避免时才使用它