我可以想到创建一个完成目标的Laravel 4软件包有两种方法:
要求软件包的用户对其进行扩展:
// YourCoolService.php
class YourCoolService extends MyCoolPackage {
// add the appropiate properties & methods
// that MyCoolPackage will expect to use
}
// YourCoolController.php
...
// Example of how it would be called
$output = YourCoolService::make()->withInput(Input::all())->render();
...
或者将类名称作为字符串参数传递到我的包中:
// YourCoolService.php
class YourCoolService { // <-- no extending here
// add the appropiate properties & methods
// that MyCoolPackage will expect to use
}
// YourCoolController.php
...
// The passed class name would be used to instantiate the class
// by MyCoolPackage so that the package can use the expected
// properties and methods in the class
$output = MyCoolPackage::make('Namespace\YourCoolService')->withInput(Input::all())->render();
...
“扩展”解决方案
PRO的
CON的
parent::helper();
之类的调用将出现在整个YourCoolService类中(但我想我仍然可以像MyCoolPackage::helper();
一样调用它。) / LI>
“通过班级名称”解决方案
PRO的
MyCoolPackage::helper('foo');
,并且它们来自哪里显而易见。CON的
创建一个需要在用户自己的类实现中存在属性和方法的包的最佳做法是什么?
答案 0 :(得分:0)
我的观点是,最好选择composition over inheritance,并且考虑到Laravel提供的DI功能,您可以允许您的包的用户在{1}中注入MyCoolPackage
的实例。对象的构造函数。那么您的make
方法就不必静态调用(或者通过外观,如果是这种情况)。
基本上,我们的想法是,只要您的软件包的用户正在创建新服务,该服务类就应该为您的软件包注入一个实例。
<?php namespace Namespace;
use MyCoolPackage\MyCoolPackage;
class YourCoolService {
protected $myCoolPackage;
public function __construct( MyCoolPackage $package )
{
$this->myCoolPackage = $package;
}
...
$this->myCoolPackage->make('Namespace\YourCoolController')
->withInput(Input::all())->render();
或者更好:
$this->myCoolPackage->make($this)->withInput(Input::all())->render();
要提供DI功能,只要MyCoolPackage
在构造函数中提示类型,就需要创建一个服务提供程序来绑定IoC中MyCoolPackage\MyCoolPackage
的实例。请参阅:http://laravel.com/docs/packages#service-providers。
由于您要离开YourCoolService
以由其他人在其他地方定义,因此除了为将要编写服务的人员提供某种范例之外,您无法做其他事情。如果你可以为他们提供一个实现的接口,那将是最好的情况,因为它会为人们编写这些服务的模板开始。
您还可以提供一个抽象基类,它将为用户提供所有其他实现可以选择覆盖与否的任何可选方法的默认实现。这种方法与您的“扩展”方法类似,并为您提供一些相同的专业人员。
我从未成为将类名作为字符串传递的忠实粉丝。我打赌它有一些用例,但对我来说它只是在你真的不需要的时候做出一个隐含的依赖。
答案 1 :(得分:0)
根据观察者的回答,我最终做了这样的事情:
// YourCoolService.php
class YourCoolService implements MyCoolPackageInterface {
public function makeCool(MyCoolPackage $myCoolPackage)
{
return $myCoolPackage->make($this);
}
}
// YourController.php
$output = (new YourService)->makeCool()->withInput(Input::all())->render();
...
具有在Controller中看起来很漂亮的调用的优点,并且没有继承。太好了!