何时在Laravel中使用存储库,服务与特征?[已关闭]

2022-08-30 18:06:58

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

我想过使用存储库,但我在某处读到存储库更好地用于检索数据,不应该用于插入。

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

有人可以用一个简单的方式解释一下其中每个(存储库/服务/特征)的最佳用法是什么,以及它们有什么不同?


答案 1

性状

是一种替代继承方法,可解决使用的单类继承的一些限制。这通常用于在模型之间共享类似的逻辑。让我们想象一下,几个模型有公司关系。PHP

trait HasCompany {
   public function company() {
       return $this->belongsTo(Company::class);
   }
}

现在用户可以轻松地通过关键字从特征中共享代码。这是一个示例,通常需要更复杂的用例才能使其有意义。using

class User {
   use HasCompany;
}

存储 库

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

这里非常固执己见,但这不是一个合适的设计模式。 具有雄辩,并且数据库层已经抽象化。存储库有时用于应用程序,但与其说是一个常见的景象,不如说是一个异常值。存储库的主要原因之一是数据实现不可知,这已经存在,您可以在SQL服务器之间完美地交换。此外,诸如 等功能感觉就像是存储库的替代品,同时使用起来很古怪。LaravelLaravelLaravelEloquents::find()scopes

如果你使用 Doctrine 作为 ,你可以在其中使用它,它是他们架构的核心,应该被使用。ORMLaravel

服务业

通常用于存储业务逻辑或应用程序中操作的构建基块的位置。在传统设计中,控制器应仅处理输入。通常情况下,你会把你的逻辑放在模型中,但是它们很快就会变得“胖”,当这种情况发生时,服务是放置业务逻辑的常见位置。有时也命名操作或命令,这是相似的,但略有不同的方法。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();
    }
}

结论

世界不是非黑即白的,你必须弄清楚自己的方法。我的建议是,不要花时间在存储库上,有很多功能来处理与存储库设计模式冲突的数据相关操作等。看看像设计方法这样的服务是否适合您,您可以利用em。 与其说是一种架构设计模式,不如说它是一种类继承替代方案,只是在类之间共享逻辑。LaravelscopesgetterssettersTraits


答案 2

推荐