PHP面向对象编程-如何初始化您的业务对象?

6
通过业务模型或业务对象,我指的是像“用户”这样的普通对象,具有所有属性名称、地址等;除了所有用户属性外,让我们假设每个用户都有一个“预约本”对象,每本书都有一组“时间段”对象等。业务模型具有对象之间的引用,至少这就是我在Java中编写业务模型的方式。
接下来是问题:
要在Java中初始化我的业务对象,我将
1. 在应用程序初始化期间仅从数据库中获取所有数据一次, 2. 将数据从我的数据库映射到我的业务对象 3. 存储在内存中(maps),它们将共享所有请求。
对于PHP的“无分享体系结构”,对于正确的面向对象编程,我感到困惑: 如果我使用相同的逻辑,我将不得不从DB检索所有对象,以供每个请求使用(我知道我仍然可以缓存,但您不会缓存所有DB,这不是关于缓存而是关于PHP及其架构的编程方式)。
所以,假设对于一个HTTP请求,我只需要用户属性,并且我不需要访问他的预约簿。为了获取用户引用的所有对象的所有数据,这将是一个遗憾,因为我只需要他的属性。这意味着我将使用许多NULL值(NULL是因为我不加载User中包含的对象)从我的模型初始化PHP对象,这可能会导致错误。
我想知道专业的PHP开发人员通常如何使用其业务对象? (我来自Java)

1
在我看来,OP更熟悉桌面应用程序开发... 桌面开发人员可以将大量信息加载到内存中并保留它们。 - tereško
3个回答

2
在PHP中,您不会将域业务模型的所有数据保存在内存中。相反,您只会从数据库(如果需要,则通过缓存)请求所需的数据。
在php中,模型层应该由多个域对象和数据映射器构建(我假设这一部分与Java并没有太大区别)。如果您需要“用户”的详细信息,则仅从数据库/缓存中获取该信息。您很可能会有一个单独的映射器来处理用户。
您显示有关该用户的信息,并忘记查询。下一个请求(如果有的话)将需要不同的信息。也许您想要该用户的“联系人列表”...然后您真的不需要该用户本身,只需要他的“user_id”。再次,您让映射器将数据提取到负责处理联系人列表的域对象中,如果联系人列表包含“用户”实例,则只需创建它们,但将其保留在“未提取”状态(对象仅知道自己的user_id)。仅在确实需要时获取它们,以及您将在该“视图”中使用的部分。
附言:您可能已经注意到,我说过模型层应该被分段,但相当多的php开发人员只创建每个DB表的单个类(实现ActiveRecord),并将其称为“model”。这是由于Ruby on Rails对php框架开发人员的影响所导致的结果,我认为这是过去5年中发生在PHP中最糟糕的事情之一。

2
您的Java示例意味着您将整个数据库内容存储在内存中。如果您这样做,那么使用数据库的意义何在?为什么不只是创建所有这些对象并进行内存转储以进行持久化。
如果我使用相同的逻辑,那么每次请求都必须从数据库中获取所有对象。
这根本是疯狂的,您不需要获取任何内容,您可以在需要时创建新实例,并在不再需要时销毁它们。
所以,假设对于一个HTTP请求,我只需要用户属性,而不需要访问他的预约簿。
那很容易,重新设计您的用户。您的用户需要其属性和一个名为appointmentBook的属性,它只是预约簿ID数组。
如果您确实需要这些预约,稍后可以从数据库中获取它们。
这意味着我将从我的模型中使用大量NULL值初始化PHP对象(由于包含在User中的对象不会加载),这可能会导致错误。
不一定,如果是这种情况,则您的用户对象太大了。使其更小,您应该加载整个用户。当然,用户必须足够小,以便您可以合理地加载它。
如果您不想这样做,那么您可以始终创建一个UserProperties类,并让每个User都有一个。当您加载用户时,您加载属性,但您还可以选择单独创建属性。

1

即使在Java中,您也不会将所有数据从数据库加载到内存中。但是,正如您所写的那样,与通常在PHP中使用的短事务脚本相比,您通常可以加载更多数据。

您的模型应该是“聪明”的,只需从持久性存储中加载执行所需操作所需的数据。这需要对象足够“聪明”,能够进行懒加载数据。

可以通过领域模型实现这一点,该模型足够了解自身,以及数据映射器足够了解存储等。

还有其他模式,可能适合您的需求,具体取决于应用程序的类型,但是领域模型数据映射器结合起来非常灵活。

在PHP世界中,一个典型的数据映射器是Doctrine


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接