ActiveRecord的大型应用设计问题

use*_*928 8 php oop design-patterns laravel eloquent

在大多数框架中,您具有表示数据库中的行的模型类.

例如php代码:

class User extends Model {}
Run Code Online (Sandbox Code Playgroud)

我正在给Laravel雄辩的例子,但对大多数php框架来说都是如此.

然后在类中添加关系:

public function pictures()
{
    return $this->hasMany('App\Picture');
}
Run Code Online (Sandbox Code Playgroud)

然后你添加一些像这样的方法:

public function deleteComments()
{
    // delete comments code here
}
Run Code Online (Sandbox Code Playgroud)

我的第一个问题是:这是一个好的设计架构,因为在项目变大之后,你会有很多关系(图片,评论,帖子,订阅等等与用户相关联).这个类可能会变成10k行代码.

在这种情况下,课程将变得非常庞大且难以维护.也可能违反了单一责任原则,因为你在一个班级中有太多的方法.

此外,如果我想在另一个应用程序中使用它,我不能,因为我将不得不在第二个应用程序(网站)中提取图片,评论等.

如果我创建其他类" UserPictures"," UserPictureDeleter"代码会变得更复杂.

这是一个好的做法,如果没有,你有什么建议,如何使代码不会膨胀这么多的方法,但易于使用.你是否同意所有这些方法属于User同类?

Max*_*rov 13

Laravel和另一个框架在其基类模型中提供Active Record概念.Active Record的主要思想是将表行表示为一个对象,包括行的数据和使用数据库的方法.

在小型简单应用程序中使用Active Record模式是完全合理的,因为这种模式可以快速开发您的应用程序.但是,如果您的应用程序具有大量代码和困难的业务逻辑,Active Record将在您的应用程序的体系结构中产生许多问题.Active Record可能会出现以下问题:

  • 违反单一责任原则,使得代码膨胀.Active Record总是违反这个原则,因为它总是有两个责任:它实现业务逻辑和数据库工作方法
  • 违反低耦合原则(GRASP),使代码重用更加困难
  • 如果使用Active Record模式,则难以进行合格抽象

这些问题的解决方案是使用OOP抽象而不是使用表行抽象.例如,您可以使用域模型域驱动设计.对于大型应用程序,此方法优于Active Record模式.

不幸的是,这些概念在本文中的解释量太大,但您可以阅读Eric Evans的"Domain Driven Design".这是一本关于应用程序设计的好书.此外,您可以在谷歌中找到许多关于这些概念的文章.例如,构建域模型,在PHP中实现域驱动设计(Laravel)