【问题标题】:PHP OO - how to initialize your business objects?PHP OO - 如何初始化您的业务对象?
【发布时间】:2012-01-07 06:47:42
【问题描述】:

通过业务模型或业务对象,我指的是普通的旧对象,例如“用户”,具有所有属性名称、地址、...;除了所有用户属性之外,假设每个用户都有一个“AppointmentBook”对象,每本书都有一组“TimeSlot”对象,等等。 业务模型的对象之间有引用,至少我是这样用 Java 编写业务模型的。 问题来了:

要初始化我的业务对象,在 Java 中,我会

  1. 在应用期间只从数据库中获取所有数据一次 初始化,
  2. 将数据从我的数据库映射到我的业务对象
  3. 存储在内存(映射)中,它们将在所有请求之间共享。

PHPShare-Nothing-Architecture 让我对正确的 OO 编程感到困惑: 如果我使用相同的逻辑,对于每个请求,我将不得不从数据库中获取所有对象(我知道我仍然可以缓存,但您不会缓存所有数据库,这不是关于缓存的问题,而是关于 PHP 及其架构的编程方式)。

假设对于一个 HTTP 请求,我只需要 User 属性,而不需要访问他的约会簿。从数据库中获取用户引用的所有对象的所有数据将是一个遗憾,因为我只需要他的属性。这意味着我将使用大量 NULL 值从我的模型中初始化 PHP 对象(NULL,因为我不会加载 User 中包含的对象),这可能会在以后导致错误。

我想知道专业的 PHP 开发人员通常如何使用他们的业务对象? (我来自 Java)


更新: 说我会在 Java 中的应用程序初始化期间将整个数据库加载到内存中有点愚蠢。我的意思是,如果我需要获取特定用户,我可以加载其所有数据,并且可以通过所有请求访问。

【问题讨论】:

  • 在我看来,OP 更熟悉 桌面应用程序 开发.. 桌面开发者 _can_ 在内存中加载大量信息,然后保留它们。

标签: php oop architecture business-objects


【解决方案1】:

您的 Java 示例意味着您将整个数据库内容存储在内存中。如果你这样做,数据库的意义何在?为什么不直接创建所有这些对象并将它们 memdump 以保持持久性。

如果我使用相同的逻辑,我将不得不为每个请求从数据库中获取所有对象

这简直太疯狂了,你不需要获取任何东西,你在需要它们时创建新实例,在不再需要它们时销毁它们。

假设对于一个 HTTP 请求,我只需要 User 属性,而不需要访问他的约会簿。

这很简单,重新设计您的用户。您的用户需要它的属性和一个名为约会簿的属性,它只是一个约会簿 ID 数组。

如果您确实需要这些约会,您可以稍后从数据库中获取它们。

这意味着我将使用大量 NULL 值从我的模型中初始化 PHP 对象(NULL 因为我不会加载 User 中包含的对象),这可能会在以后导致错误。

并非如此,如果是这种情况,您的 User 对象太大了。让它更小,你应该加载整个用户。当然,除了用户必须足够小,您才能合理加载它。

如果您不想这样,那么您可以随时创建一个 UserProperties 类并让每个用户都有一个。当您加载用户时,您会加载属性,但您也可以选择单独创建属性。

【讨论】:

    【解决方案2】:

    即使在 Java 中,您也不会将数据库中的所有数据都加载到内存中。但是,您可以 - 在您编写时 - 与通常在 PHP 中使用的短 Transaction Scripts 相比,通常加载更多。

    您的模型应该“聪明”,然后只从持久存储中加载执行请求操作所需的数据。这要求对象“聪明”到足以延迟加载数据。

    这可以通过对自身有足够了解的Domain Model 和对存储有足够了解的Data Mapper 来实现。

    还有其他模式可能适合您的需求,具体取决于应用程序的类型,但是 Domain ModelData Mapper 一起非常灵活。

    PHP 世界中的示例数据映射器是Doctrine

    【讨论】:

      【解决方案3】:

      在 PHP 中,您不会将领域业务模型的所有数据都保存在内存中。相反,您只需从数据库(如果需要,通过缓存)请求您想要的数据。

      php 中的模型层应该由多个域对象和数据映射器构建(我假设该部分与 Java 没有太大区别)。如果您需要User 详细信息,那么您只从数据库/缓存中获取该信息。您很可能会有一个单独的映射器来处理用户。

      您显示有关该用户的信息,而忘记了查询。下一个请求(何时以及是否出现)将需要不同的信息。也许你会想要ContactList 那个User ...那么你真的不需要用户本身,只需要他的user_id。同样,您让映射器将数据提取到负责处理联系人列表的域对象中,如果联系人列表包含 User 实例,则只需创建它们,但保持 "unfetched" 状态(对象只知道自己的 user_id)。仅在您确实需要时才获取它们,并且仅在该“视图”中使用您将使用的部分。


      附:你可能已经注意到了,我后来告诉过该模型应该被分段,但通常 php 开发人员只是创建每个 DB 表的单个类(实现 ActiveRecord)并将其称为“模型”。这是 Ruby on Rails 对 php 框架开发人员的影响造成的结果,恕我直言,这是过去 5 年来 PHP 发生的最糟糕的事情之一。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-22
        • 1970-01-01
        • 2018-10-17
        • 1970-01-01
        • 2013-06-27
        • 1970-01-01
        • 2018-02-23
        • 2010-10-15
        相关资源
        最近更新 更多