我在Laravel上有一个项目,需要进行重构。我已经阅读了有关服务提供者和依赖注入的信息,并且有一些问题。
这是一个简短的结构:user
模型,event
模型,favorite user
模型等。而且,所有模型都有控制器。每个event
都有一个creator
和client
(user
关系)。在每堂课中,我都会注入适当的服务:User
服务,Event
服务,Favorite user
服务等。
让我们考虑示例-我要delete
user
:
class UserController extends Controller
{
/**
* @var UserService $userService
*/
protected $userService;
/**
* UserController constructor.
* @param UserService $userService
*/
public function __construct(UserService $userService)
{
$this->userService = $userService;
}
protected function delete(int $id)
{
$user = User::find($id);
if ($user) {
$this->userService->setUser($user);
$this->userService->delete();
}
}
内部用户服务,我正在处理用户删除-更新相应的字段。另外,我需要取消所有用户事件并删除喜欢的用户。
我的问题是我应该在哪里做?我应该在event
或favorite user
中注入UserController
和UserService
服务吗?或者,也许有更好的方法可以执行此操作。提前谢谢
答案 0 :(得分:2)
似乎您有许多操作取决于删除用户,所以我会考虑使用“事件”,并在每个侦听器内部处理其细节。
class UserController extends Controller
{
/**
* @var UserService $userService
*/
protected $userService;
/**
* UserController constructor.
* @param UserService $userService
*/
public function __construct(UserService $userService)
{
$this->userService = $userService;
}
protected function delete(int $id)
{
if(!$this->userService->delete($id)) {
// return some error;
}
event(new UserWasRemoved($id));
// return success response
}
class DeleteUserService {
protected $user;
public function __construct(User $user)
{
$this->user = $user;
}
public function delete($id){
return $this->user->delete($id);
}
}
// app/Providers/EventServiceProvider
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
UserWasRemoved::class => [
CancelUserEvents::class,
RemoveUserFavorites::class,
// etc...
],
];
}
答案 1 :(得分:1)
如果删除用户的代码太多,我将创建DeleteUserService
类,其中将包含删除用户所需的所有代码以及删除的效果。
class DeleteUserService {
public function __construct(int $userId)
{
$this->userId = $userId;
}
public function delete(){
$this->deleteUser();
$this->updateAppropriateFields(); // of course the name should be clearer
$this->deleteEvents();
$this->deleteFavoriteUser();
...
}
private function deleteUser(){...}
private function updateAppropriateFields(){...}
private function deleteEvents(){...}
private function deleteFavoriteUser(){...}
...
}
然后在控制器中注入服务或在控制器方法中实例化新实例
class UserController extends Controller
{
...
public function delete(int $id)
{
$user = User::findOrFail($id);
$deleteService = new DeleteUserService($user->id);
$deleteService->delete();
}
}
将大型函数分为一个或多个类总是一个好主意。
答案 2 :(得分:0)
我建议您放弃使用此类服务的方法。您使用服务实现的所有内容都已经在Laravel中实现,甚至更加简单。您现在将在一个简单的现成的逻辑之上实现更多麻烦的逻辑。
为主题区域的每个对象(用户,事件,喜欢的用户)添加模型类。在表中添加表信息以及属于它们的数据-除非您当然使用关系存储Eloquent Model Conventions。在这里,我有一个问题要问-最喜欢的用户实体是否需要单独的类?如果User和FavoriteUser具有相同的特征(即,实现中的类成员),则无需将它们分发到不同的类中,并且只需添加一个附加的isFavourite()(bool)属性就可以了。类和表格中。
按照文档Defining Controllers中所述,在每个模型类的控制器中实现必要的方法。根据客户端部分的类型,响应的返回可以是RESTful API的JSON,也可以是带有传输数据Views的刀片模板。在这里,您应该在控制器中实现删除模型的方法。
如果您不希望逻辑相似,即摆脱UserController,EventController,all(),get(),post(),put(),delete()和其他方法的相似方法, ...(模型类除外-会有所不同),然后建议您使用以下体系结构技巧(当然这是可选的)。开发通用层-通用模型的类,通用控制器的类,通用模型存储库的类(如果在开发中使用的话)。然后在控制器中,描述所有模型类all(),get(),post(),put(),delete()的通用逻辑。然后从通用类继承模型的每个具体类,从通用类继承控制器的每个具体类-依此类推。但! 在模型的具体类中,例如在数组中,有必要列出关系存储表的属性,从中可以获取数据。还必须在变量中指定类的名称-以便控制器可以了解其应使用的类。 并以任何方式在控制器中传递有关模型类的数据-例如,使用DependencyInjection Dependency Injection & Controllers。 通过这种方法,具体控制器的类别变得越来越少,并且其中代码的增加仅是由于重新定义通用方法或实现自定义方法而引起的。 该方法的优点还在于,无需添加相似结构的路由。例如,一条通用路线就足够了
Route::get('{entity}/{id}', function ($entity, $id) {
$module = ucfirst($entity);
Route::get("{$entity}/{$id}", "{$module}Controller@get");
});
代替许多相同类型的
Route::get('user/{id}', 'UserController@get');
Route::get('event/{id}', 'EventController@get');
之类的。