拉拉维尔大型模型的最佳实践


Best practices for large models in Laravel

我决定重新创建一个我在Laravel中的现有站点,作为学习框架如何工作的一种手段,并且遇到了一个我似乎无法得到像样解释的问题。

目前使用我构建的自定义 MVC 框架。目前,我将拥有一个包含大量业务逻辑的"模型"。例如,在我的UserModel中,我拥有与数据库交互的所有函数,但我还有许多其他与用户相关但与数据库没有交互的函数。

可以将

此代码放在 Eloquent 模型中吗?

没关系。但是,如果模型类变得太大,有时我会创建一个"管理器"对象来推开模型类中的一些责任。例如:

class User extends Model
{
    protected $permissionManager;
    public function __contruct(){
        //create a Manager object (in laravel create it through App:make )
        $this->permissionManager = new PermissionManager( $this );
    }
}
class PermissionManager
{
    protected $user;
    public function __contruct(User $user){
        $this->user = $user;
    }
    public function hasAccessTo(Resource $res){
        //code
    }
    public function isManager(){
        //code
    }
}
这些管理器对象

与用户模型严格相关,实际上您将模型的依赖关系传递给管理器类的构造函数,但主要好处是避免创建"god"类并使用对象组合来划分责任。

使用此结构,您可以调用:

$user->permissionManager->hasAccessTo( $resource );

您甚至可以使用接口、User的子类和PermissionManager类,并根据实例在层次结构中创建不同的类型(也称为工厂方法)

减轻模型负担的另一种方法是使用特征。Laravel本身在应用程序的各个部分使用特征;查看核心类以了解它们的使用方式。由于各种原因,许多人不太喜欢特质,我刚才提出的方法的优点是,它比使用特质更明确,更不容易发生冲突。

意见很少,但我认为将用户相关的逻辑保留在那里是可以的。至少我在非常大的项目中看到了完全相同的方法,其中有很多臃肿的控制器/模型类。使用单一责任原则是个好主意,但在使用它时不要狂热。过度设计是邪恶的。

我建议你使用traits .您可以在应用目录中有一个traits文件夹。然后,我将每个函数分类在其单独的文件夹中,例如:

  • 使用数据库的函数将位于app/traits/database文件夹中。
  • 不使用数据库的函数将位于app/traits/misc文件夹中。

然后,我将创建一个名为 UserFunctions.php 的抽象类,它将包含所有特征。然后,我将用抽象类扩展我的用户模型。

class User extends BaseUser,UserFunctions