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 来封装,例如说:

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

  • 图片处理的工具类(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 网站上。

上一篇 下一篇
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
贡献者:1
讨论数量: 0
发起讨论 查看所有版本


暂无话题~