Laravel 模式 - 工作与服务的使用

Laravel patterns - Usage of jobs vs services

我想知道大多数开发人员如何使用这两个 Laravel 工具。

在 Laravel 中,您可以使用服务或作业处理业务逻辑(我们只讨论不可排队的作业,只讨论那些 运行在同一个过程中)。

例如,用户想要创建一个实体,比方说一本书,您可以使用服务或调度作业来处理实体创建。

使用作业会是这样的:

class PostBook extends Job
{
    ...
    public function handle(Book $bookEntity)
    {
        // Business logic here.
    }
    ...
}

class BooksController extends Controller
{
    public function store(Request $request)
    {
        ...
        dispatch(new PostBook($request->all()));
        ...
    }
}

使用服务,它会是这样的:

class BookService
{
    public function store(Request $request)
    {
        // Business logic here.
    }
}

class BooksController extends Controller
{
    public function store(Request $request)
    {
        ...
        // I could inject the service instead.
        $bookService = $this->app()->make(App\Services\BookService::class);
        $bookService->store($request);
        ...
    }
}

问题是,您通常如何选择使用一种方式或另一种方式?为什么?

在这件事上肯定有两个"schools",但我想了解每一个的优缺点。

"Business logic" 可以用 任何东西 处理,所以看起来真正要问的是哪个选项更适合重复相同的业务逻辑 不重复代码.

A Job class 通常会做 一件事情 ,正如它的 handle() 方法所定义的那样。很难从比较中排除排队的作业,因为 运行 它们同步通常违背了处理缓慢、昂贵或不可靠的操作(例如调用网络 API)的目的 当前请求已完成并向用户显示响应后。

如果所有作业都应该是同步的,那么它与为您的业务逻辑定义一个 函数 没什么不同。这实际上与分派同步作业的作用非常接近:在调用堆栈的某个位置,它最终 运行 call_user_func([$job, 'handle']) 调用您作业上的单个方法 object。更重要的是,同步作业缺少重试 可能由于网络故障等外部原因而失败的作业的机制。

另一方面,

服务是围绕组件封装逻辑的简单方法,它们可能会不止一件事。在这种情况下,组件可以被认为是您的应用程序的一部分,可以换出不同的实现而无需修改使用它的代码。框架中包含的一个完美示例是 Filesystem 服务(最常通过 Storage 门面访问)。

考虑一下您是否没有通过将书籍插入数据库来存储书籍,而是通过发布到外部 API。你可能有一个 BookRepository service,它不仅有一个 store() 方法,还有一个 get(), update(), list(), delete(),或任意数量的其他方法。所有这些请求都共享用于向外部 Web 服务进行身份验证的逻辑(例如向请求添加 headers),并且您的 BookRepository class 可以封装该 re-usable 逻辑。您可以在计划的 artisan 命令、Web 控制器、api 控制器、作业、中间件等内部使用此服务 class — 无需重复代码。

使用此示例,您可以创建一个 Job 来存储一本新书,这样您就不会在 API 响应缓慢时让用户等待(而且它失败时可以重试)。在内部,您的作业在运行时会调用您的 Service 的 store() 方法。服务完成的工作由作业安排。