Service 模式

未匹配的标注

介绍

项目中的大部分业务逻辑,都应该封装到 Service 层。这不仅能更好地组织代码,还方便单元测试。

ModelService

Model 的操作,涉及到业务逻辑的,绝不放置于控制器方法或模型文件中。

控制器方法只处理请求逻辑。模型只处理模型定义,以及数据关联逻辑。

业务逻辑必须封装到对应的 ModelService 类中。

例如 LearnKu.com 的 Reply 模型,用户发布 Reply 时需要的逻辑,如发送通知给话题的作者,或者增加话题的评论数等操作,放置于 ReplyService 类的 create 方法。

ModelService 方法命名

必须参照 Laravel Model 的方法来命名,如:

$reply_service->create();
$reply_service->all();
$reply_service->update();
$reply_service->delete();

其他 Service

其他类型的类,都应该使用 Service 来封装,例如说:

  • 请求第三方接口的类(SendCloundService)

  • 图片处理的工具类(ImageService)

  • 包含业务逻辑的类(对 Elasticsearch 封装的 SearchService )

存放目录

所有的 Service 类都必须存放于 app/Services 目录中(注意是复数)。

目录组织

应该避免直接将 Service 类放置于 app/Services 目录下,应该考虑通过业务逻辑,将其归类于子目录中。如:

Auth —— 存放登录、授权相关的 Service;
Payment —— 存放支付相关的 Service;
Book —— 存放课程相关的 Service.

Service 方法无状态

必须 做到 Service 类无状态。

无状态意味着是无论在控制器方法、命令行、测试代码中,皆可调用。

❌ 错误的例子:

// CommentService
public function create($content)
{
    return Comment::create([
        'content' => $content,
        'user_id' => Auth::user()->id
    ]);
}

// PostService
public function update(Request $request)
{
    return $this->comments()->create([
        'content' => $request->get('content'),
        'category_id' => $request->category_id
        'user_id' => Auth::user()->id
    ]);
}

✅正确的例子

// CommentService
public function create($content, $user)
{
    return Comment::create([
        'content' => $content,
        'user_id' => $user->id
    ]);
}

// PostService
public function create($content, $category_id, $user)
{
    return Post::create([
        'content' => $content,
        'category_id' => $category_id,
        'user_id' => $user->id
    ]);
}

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
贡献者:1
讨论数量: 0
发起讨论 只看当前版本


暂无话题~