Service层内容是更具哪个来写

我很好奇,大家的service层是围绕,哪个来写的,是更具model里面的功能来写单独的模块,然后再controller里面组合,还是直接更具controller里面的内容来写,我更具controller来写,感觉其实写直接在controller里面差不多,只能说一部分的功能可以重复调用,大部分还是无法的复用,感觉有点点鸡肋的感觉

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
最佳答案

最大的作用就是解耦和提高复用性,试想一下,例如我的很多个模块都需要查询一次用户信息,以往的做法都是在各个控制器中写一次:

$user = User::query()->find($id);

如果我做成服务,那就可以这样写:

// 控制器:
$user = $this->userService->findUserById($id);

// userService
return $this->userRepository->findUserById($id);

// userRepository(数据仓库)
return User::query()->find($id);

后续如果有更改,我只需要更改userService中的代码就可以,不需要每个调用的地方都要去修改。或者以往获取数据都是通过User这个模型去获取,我需要加缓存层来获取用户信息,那么我只需要修改userRepository中的代码就可以。 使用service有好几种写法:

一种是控制器处理简单的数据校验,调用serviceservice里调用不同的数据仓库组合完成一组服务;

// 控制器
$order = $this->userService->getOrderByOenId($openId);

// service
$user = $this->userRepository->getUserByOpenId($openID);
if($user) {
  $order = $this->orderRepository->getOrderByUserId($user->id);
}

一种是service和数据仓库一样符合单一原则,控制器除了数据校验,就是通过调用单一的service来组合完成需要完成的事,后续service的调用依赖于前面service返回的结果。

// 控制器
$user = $this->userService->getUserByOenId($openId);
if($user) {
  $order = $this->orderervice->getOrderByUserId($user->id);
}

还有一种就是service实现interfaceinterface里写好了传的参数类型、个数和返回值的类型。

8个月前 评论
讨论数量: 9

最大的作用就是解耦和提高复用性,试想一下,例如我的很多个模块都需要查询一次用户信息,以往的做法都是在各个控制器中写一次:

$user = User::query()->find($id);

如果我做成服务,那就可以这样写:

// 控制器:
$user = $this->userService->findUserById($id);

// userService
return $this->userRepository->findUserById($id);

// userRepository(数据仓库)
return User::query()->find($id);

后续如果有更改,我只需要更改userService中的代码就可以,不需要每个调用的地方都要去修改。或者以往获取数据都是通过User这个模型去获取,我需要加缓存层来获取用户信息,那么我只需要修改userRepository中的代码就可以。 使用service有好几种写法:

一种是控制器处理简单的数据校验,调用serviceservice里调用不同的数据仓库组合完成一组服务;

// 控制器
$order = $this->userService->getOrderByOenId($openId);

// service
$user = $this->userRepository->getUserByOpenId($openID);
if($user) {
  $order = $this->orderRepository->getOrderByUserId($user->id);
}

一种是service和数据仓库一样符合单一原则,控制器除了数据校验,就是通过调用单一的service来组合完成需要完成的事,后续service的调用依赖于前面service返回的结果。

// 控制器
$user = $this->userService->getUserByOenId($openId);
if($user) {
  $order = $this->orderervice->getOrderByUserId($user->id);
}

还有一种就是service实现interfaceinterface里写好了传的参数类型、个数和返回值的类型。

8个月前 评论

基本上就是控制器的逻辑多了 然后封装一个无状态的service出来

8个月前 评论

Service 要介于 Model 和 Controller 中间。一般来说,Model 也不应该和 Service 有直接关系,数据应该由 Repository 来处理,换句话说 Service 就应该做到独立、解耦、可复用。

Service 中至少不应该直接调用 request 或者使用其他方法来获取超全局变量,这些值的来源都应该作为参数传进来,尽可能减少“魔法依赖”。

单个服务还应尽可能考虑单一性,打个比方的说,对于处理用户登录、注册。这种情况应该怎么办?创建一个 UserService ,在里面分别创建 login 和 register 方法?还是分别创建 RegisterService 和 LoginService ?

两种方法都是可以,但是如果是前者的话,那就相当于把 Controller 直接搬到了 Service 了。但是也要视情况而定,对于前者来说,如果业务简单,自然是没有问题。对于复杂的业务而言,那可能后者会是更优的选择。

8个月前 评论

考虑 service 的时候不要考虑 mvc 的东西,service 类就是纯代码逻辑。

我一开始写的时候也有迷茫,当时写的时候控制器写一个方法, 然后在 service 实现, service 内部的方法之间也没有什么内聚, 感觉不优雅。

后来优雅起来是因为我开始写自己的包,定义接口,然后接口的功能实现在 service 里面,就感觉特别自然, 复用也很OK, 感觉这才是 service 的合理用法。

不一定只有自己写包才能使用 service , 我上面的例子只是说明我学习的一个过程。现在我的项目工程文件也有 service 它的逻辑和我包里的 service 是一个逻辑。 就是 service 它是某个接口的实现。这个接口是某个功能模块开发前定义的对外的公开方法。和 控制器 模型 视图啥的关系都不大。 一个 service 类可能多个控制器会调用, 也可能依赖多个数据模型。

8个月前 评论

其实楼上说的都没错,核心就是解耦,避免流水账一样的代码,使用功能单一原则,提高代码复用率,让可维护性和可扩展性得到提升,只有合理的分割,后期维护后者迭代的时候才能顺畅

8个月前 评论
sanders

其实有没有 Service 层全看业务复杂程度,如果都是简单的资源访问,那便是不要 Service 层也可以。 一旦你发现某些控制器、队列任务或监听器的方法代码出现大量复制甚至是处理的模型也都一模一样的时候,那就该考虑是不是要拆出来一个 Service 层来保存这部分逻辑并在控制器间进行调用,或者被其他的 Service 调用。

8个月前 评论

最大的作用就是解耦和提高复用性,试想一下,例如我的很多个模块都需要查询一次用户信息,以往的做法都是在各个控制器中写一次:

$user = User::query()->find($id);

如果我做成服务,那就可以这样写:

// 控制器:
$user = $this->userService->findUserById($id);

// userService
return $this->userRepository->findUserById($id);

// userRepository(数据仓库)
return User::query()->find($id);

后续如果有更改,我只需要更改userService中的代码就可以,不需要每个调用的地方都要去修改。或者以往获取数据都是通过User这个模型去获取,我需要加缓存层来获取用户信息,那么我只需要修改userRepository中的代码就可以。 使用service有好几种写法:

一种是控制器处理简单的数据校验,调用serviceservice里调用不同的数据仓库组合完成一组服务;

// 控制器
$order = $this->userService->getOrderByOenId($openId);

// service
$user = $this->userRepository->getUserByOpenId($openID);
if($user) {
  $order = $this->orderRepository->getOrderByUserId($user->id);
}

一种是service和数据仓库一样符合单一原则,控制器除了数据校验,就是通过调用单一的service来组合完成需要完成的事,后续service的调用依赖于前面service返回的结果。

// 控制器
$user = $this->userService->getUserByOenId($openId);
if($user) {
  $order = $this->orderervice->getOrderByUserId($user->id);
}

还有一种就是service实现interfaceinterface里写好了传的参数类型、个数和返回值的类型。

8个月前 评论

我感觉你在使用Service定位有点乱了,
我的话Service对应Controller,查询数据在Model中或者增加Business来查询数据。Service主要用于在组装数据。

8个月前 评论

看过不少项目写的service层,现在维护的一个很多年的symfony项目里的service层也看过,我感觉自定义的service层在目前看来就是鸡肋,至少写出职责分明低耦合的service是一件很花精力的事,我现在一般都把逻辑全部放在controller里面了。

真想复用逻辑的话可能用一下其他的成熟的包提供的封装思路比较好,比如easywechat里面的事件推送,数据查询层面上封装一下repository啥的,像我目前处理文章的投稿流程,文章表十几个状态,已经考虑采用状态机了。

另外就是我觉得就是不要拘泥于呆板的service层这个概念,不要把service跟mvc绑定起来,可以写一些具象的服务,玩点设计模式,然后把操作类注入一下,比如一些handler(manager, processor, factory, builder)之类的,这样不是很好吗。

8个月前 评论
Complicated

项目大了 自然就能体会到什么样的代码要写在 service 层了。只不过往往做不到这么大的项目

7个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!