Php 在Laravel中何时使用存储库vs服务vs特征?

Php 在Laravel中何时使用存储库vs服务vs特征?,php,laravel,Php,Laravel,为了避免Laravel中的代码重复,我希望有一个由多个控制器使用的方法,它在数据库中插入一些行,并更新另一个表中的一些数据 我曾想过使用存储库,但我在某个地方读到,存储库更好地用于检索数据,而不应用于插入 所以我现在要用特质。但是我有点困惑 有人能简单地解释一下这些(存储库/服务/特征)的最佳用途是什么,它们有什么不同吗?特征 是继承的另一种方法,它解决了PHP使用的单类继承的一些限制。这通常用于跨模型共享类似的逻辑。让我们假设有两个模型有公司关系 trait HasCompany { p

为了避免Laravel中的代码重复,我希望有一个由多个控制器使用的方法,它在数据库中插入一些行,并更新另一个表中的一些数据

我曾想过使用存储库,但我在某个地方读到,存储库更好地用于检索数据,而不应用于插入

所以我现在要用特质。但是我有点困惑


有人能简单地解释一下这些(存储库/服务/特征)的最佳用途是什么,它们有什么不同吗?特征

是继承的另一种方法,它解决了
PHP
使用的单类继承的一些限制。这通常用于跨模型共享类似的逻辑。让我们假设有两个模型有公司关系

trait HasCompany {
   public function company() {
       return $this->belongsTo(Company::class);
   }
}
现在,用户可以使用,通过关键字
,轻松共享trait中的代码。这是一个例子,需要一个更复杂的用例才能让它有意义

class User {
   use HasCompany;
}
存储库

存储库是从应用程序中抽象数据层的设计模式。您的逻辑不应该关心如何存储数据,因此,如果您想从
Mysql
更改为
Mongodb
,您只需更换存储库,而不必更改业务逻辑

这里非常固执己见,但这不是一个适合
Laravel
的设计模式
Laravel
具有雄辩的功能,因此数据库层已经被抽象。存储库有时用于
Laravel
应用程序,但它是一个异常值,而不是一个常见的场景。存储库的主要原因之一是数据实现不可知,它已经存在,并且可以在SQL服务器之间完美地交换。另外,像
::find()
作用域等功能让人感觉像是存储库的替代品,同时使用起来也很奇怪

如果您使用条令作为
ORM
,您可以在
Laravel
中使用,它是他们架构的核心,应该使用

服务

通常用于在应用程序中存储业务逻辑或操作的构建块。在传统的
MVC
设计中,控制器应该只处理输入。通常,您会将逻辑放在模型中,但它们很快就会变得“胖”,当这种情况发生时,服务是放置业务逻辑的常见位置。有时也命名为动作或命令,这是类似的,但有点不同的方法

它解决的核心问题之一是使业务逻辑可重用。当您在其控制器中检索到活动标志时,映像将通过活动标志筛选所有用户

public function all() {
    return User::where('active', true)->get();
}
现在您有了业务逻辑,它强制您只处理活动用户,稍后您希望通过使用命令通知所有活动用户,并通过电子邮件通知所有活动用户

class NotifyUsers extends Command {
    public function handle() {
        foreach (User::where('active', true)->get() as $user) {
            $user->notify();
        }
    }
}
现在您必须手动使业务逻辑保持最新,下次添加第二个条件或类似条件时,因此必须在两个地方更改代码。在大型应用程序中,很难在多个位置维护这些条件。如果您使用此逻辑进行服务。您可以在整个应用程序中使用相同的业务逻辑,并且只需在一个地方维护它

class UserService {
    public function all() {
        return User::where('active', true)->get();
    }
}
无论您想在何处使用此业务逻辑获取活动用户,都可以使用该服务。因此,只有一个地方可以维护逻辑。调用可以是
resolve(UserService::class)->all()
。使用服务更新逻辑的示例如下

// controller
public function all(UserService $userService) {
    return $userService->all();
}

// command
class NotifyUsers extends Command {
    public function handle(UserService $userService) {
        $userService->all()->each->notify();
    }
}
结论


世界不是黑白的,你必须想出自己的方法。我的建议是,不要把时间花在存储库上,
Laravel
有很多功能来处理与数据相关的操作
范围
getters
setters
等,这些都与存储库设计模式相冲突。看看类似服务的设计方法是否适合您,您可以利用它们。
Traits
与服务和存储库无关,它只是一个类似于类继承的工具,用于在对象之间共享逻辑。

这太完美了,更像是一篇文章,而不是一个答案,非常感谢!很高兴你喜欢它,这是一个非常模糊的主题,观点和宗教比事实更重要:)