通过商业模式或业务对象,我指的是像“用户”这样的普通旧对象,其所有属性名称,地址,......;除了所有用户属性之外,假设每个用户都有一个“AppointmentBook”对象,每本书都有一组“TimeSlot”对象等。 业务模型具有在它们之间具有引用的对象,至少这是我在Java中编写业务模型的方式。 问题出在这里:
要初始化我的业务对象,在 Java 中,我会
PHP 的 Share-Nothing-Architecture 让我对正确的OO编程感到困惑: 如果我使用相同的逻辑,我将不得不从DB中获取所有对象,对于每个请求(我知道我仍然可以缓存,但是你没有缓存所有的数据库,它不是关于缓存的问题,而不是PHP及其架构中的编程方式。)
因此,假设对于一个HTTP请求,我只需要用户属性,而不需要访问他的约会簿。从User获取的所有对象中获取DB的所有数据将是一个小问题,因为我只需要他的属性。这意味着我将使用大量NULL值从我的模型初始化PHP对象(因为我将不加载的User中包含的对象为NULL),这可能导致错误。
我想知道专业的PHP开发人员通常如何使用他们的业务对象? (我来自Java)
UPDATE: 在Java应用程序初始化过程中,我会将整个数据库加载到内存中,这有点蠢。我的意思是,如果我需要获取特定用户,我可以加载所有的数据,并且可以通过所有请求访问。
答案 0 :(得分:2)
在PHP中,您不会将域业务模型的所有数据保留在内存中。相反,您只需要从DB(尽管需要缓存,如果需要)请求您想要的数据。
php中的模型层应该是从多个域对象和数据映射器构建的(我假设,该部分与Java没有那么不同)。如果您需要User
详细信息,则只从数据库/缓存中获取该信息。您很可能只有一个单独的映射器来处理用户。
您显示有关该用户的信息,并忘记该查询。下一个请求(何时以及如果它)将需要不同的信息。也许你会想要ContactList
User
...那么你真的不需要用户本身,只需要他的user_id
。同样,您允许mapper将数据提取到负责处理联系人列表的域对象中,如果联系人列表包含User
个实例,那么只需创建它们,但保留“unfetched”状态(对象只知道自己的user_id)。只有在您真正需要时才会获取它们,并且只有您将使用的部分才能“查看”。
P.S。您可能已经注意到了,我告诉该模型以后应该进行细分,但是PHP开发人员通常只创建每个数据库表(实现ActiveRecord)的单个类并将其称为“模型”。这是Ruby on Rails对php框架开发人员的影响所导致的结果,恕我直言,这是过去5年中PHP发生的最糟糕的事情之一。
答案 1 :(得分:2)
您的Java示例意味着您将整个数据库内容存储在内存中。如果你这样做,数据库有什么意义?为什么不只是创建所有这些对象并将它们记忆为持久性。
如果我使用相同的逻辑,我将不得不为每个请求
从DB中获取所有对象
这简直就是疯狂,你不需要取任何东西,你需要它时创建新实例并在不再需要时销毁它们。
因此,假设对于一个HTTP请求,我只需要用户属性,而不需要访问他的约会簿。
这很简单,重新设计您的用户。您的用户需要它的属性和名为appointmentBook的属性,它只是一组预约书ID。
如果您确实需要这些约会,可以稍后从数据库中获取它们。
这意味着我将使用大量的NULL值从我的模型初始化PHP对象(因为我将不加载的User中包含的对象为NULL),这可能导致错误。
不是真的,如果是这种情况你的User对象太大了。减小它,你应该加载整个用户。除了用户必须小到足以让你明智地加载它。
如果你不想那样,你可以随时创建一个UserProperties类,让每个用户都有一个。加载用户时加载属性,但您也可以选择单独创建属性。
答案 2 :(得分:1)
即使在Java中,也不会将数据库中的所有数据加载到内存中。但是,您可以 - 在编写时 - 与PHP中通常使用的短Transaction Scripts相比,经常加载更多。
您的模型应该“聪明”,然后只加载执行请求的操作所需的持久性存储中的数据。这要求对象可能“聪明”到足以延迟加载数据。
这可以通过对自身了解得足够的Domain Model以及对存储有足够了解的Data Mapper来实现。
根据应用程序的类型,还有其他模式可能适合您的需求,但域模型与 Data Mapper 一起非常灵活。
PHP世界中的示例数据映射器是Doctrine。