【发布时间】:2016-01-26 10:10:38
【问题描述】:
我阅读了许多资料,暗示 laravel 外观最终存在是为了方便,并且这些类应该改为 injected 以允许松散耦合。甚至Taylor Otwell has a post 解释如何做到这一点。看来wonder this的不止我一个。
use Redirect;
class Example class
{
public function example()
{
return Redirect::route("route.name");
}
}
会变成
use Illuminate\Routing\Redirector as Redirect;
class Example class
{
protected $redirect;
public function __constructor(Redirect $redirect)
{
$this->redirect = $redirect
}
public function example()
{
return $this->redirect->route("route.name");
}
}
这很好,只是我开始发现一些构造函数和方法开始采用四个以上的参数。
由于 Laravel IoC似乎只注入到类构造函数和某些方法(控制器)中,即使我有相当精简的函数和类,我发现类的构造函数正在被打包将所需的类注入所需的方法中。
现在我发现,如果我继续这种方法,我将需要我自己的 IoC 容器,如果我使用像 laravel 这样的框架,这感觉就像重新发明轮子?
例如,我使用服务来控制业务/视图逻辑,而不是使用控制器来处理它们——它们只是路由视图。因此控制器将首先获取其对应的service,然后是其url 中的parameter。一个服务功能还需要检查表单中的值,所以我需要Request 和Validator。就这样,我有四个参数。
// MyServiceInterface is binded using the laravel container
use Interfaces\MyServiceInterface;
use Illuminate\Http\Request;
use Illuminate\Validation\Factory as Validator;
...
public function exampleController(MyServiceInterface $my_service, Request $request, Validator $validator, $user_id)
{
// Call some method in the service to do complex validation
$validation = $my_service->doValidation($request, $validator);
// Also return the view information
$viewinfo = $my_service->getViewInfo($user_id);
if ($validation === 'ok') {
return view("some_view", ['view_info'=>$viewinfo]);
} else {
return view("another_view", ['view_info'=>$viewinfo]);
}
}
这是一个例子。实际上,我的许多构造函数已经注入了多个类(模型、服务、参数、外观)。我已经开始将构造函数注入(如果适用)“卸载”到方法注入,并让调用这些方法的类使用它们的构造函数来注入依赖项。
有人告诉我,根据经验,方法或类构造函数的参数超过四个是不好的做法/代码异味。但是,如果您选择注入 laravel 外观的路径,我看不出如何真正避免这种情况。
我是不是把这个想法搞错了?我的课程/功能不够精简吗?我是否错过了 laravel 容器的要点,还是真的需要考虑创建自己的 IoC 容器? Some 其他 answers 似乎暗示 laravel 容器能够消除我的问题?
也就是说,在这个问题上似乎没有一个明确的共识......
【问题讨论】:
-
最佳实践始终是指导方针,而不是一成不变的规则。有些模式完全冲突,因此您必须权衡每种模式的利弊并做出判断。就个人而言,当涉及到构造函数时,许多注入的依赖项可能是不可避免的。但它也不是你在 Laravel 中测试之外一直使用的东西。 IoC 会为你处理它们,所以不要太害怕加载你的构造函数。
-
纠正我自己,当我说“不是你一直使用的东西”时,我的意思是你不会为你的构造函数手动提供依赖项。由于 IoC 将处理提供它们,因此方法过多导致的问题并不完全相同。不过,我个人会将其保留给构造函数,而不是特定的方法。
-
所以你不认为注入大量类的构造函数(在中心位置)是个问题?
-
为什么不直接使用
redirect()辅助函数呢?return redirect('something'); -
@myol - 不,我没有。我认为这可能是问题的证据,正如另一个答案中所说,但有时可能存在原则不适合您的用例的情况。您还想避免过度设计您的软件。编写可读、可管理的代码与被锁定在一个设计原则中以致于你花费数小时试图在没有意义的情况下强行将代码写入其中之间有一条很好的界限。
标签: php laravel dependency-injection laravel-facade