我有一个应用程序,它对实体使用Doctrine ORM。我尝试按照 OO 设计将尽可能多的业务逻辑推送到实体中。但是我遇到了一个小问题。某些业务逻辑需要在我的外部应用程序配置中定义的变量(因为它们有时需要调整(。如何在不违反 OO 原则的情况下将这些内容放入我的实体中?我不想直接从我的实体访问我的全局配置,我也不想将这些变量存储在我的实体和数据库中。
下面是一个模式具体示例。我将PHP与Doctrine ORM一起使用,但相同的OO原则适用于Hibernate(JAVA(,nHibernate(C#(等。
我的应用程序具有"产品和用户"。有许多不同类型的用户(真正的人类用户,自动化机器人等(。它们都需要处理产品对象。所有用户共享具有单一方法的同一用户界面:
class UserInterface {
function canProcess(Product $product);
}
我有一个在产品和用户之间进行调解的流程服务。它只是遍历附加到产品的所有用户,直到找到当时愿意处理它的用户。
class ProcessService {
// Process a product
function process(Product $product) {
foreach ($this->getUsers() as $user) {
if ($user->canProcess($product)) {
...
}
}
}
问题是一些用户(在我的例子中是其中一个机器人(需要一个外部配置变量来确定它是否可以处理产品。
我不想将该值存储在我的实体和数据库中(这不是正确的位置(,也不想从机器人实体内部访问我的全局配置对象(违反 OO(。但是,我也无法通过canProcess()
接口方法传递它,因为此变量仅适用于一种类型的机器人,而不适用于我系统中的所有其他类型的用户。因此,它在用户界面中也没有位置。
那么,如何将此配置变量放入我的实体中?
好吧,我只看到三种选择:
- 使用值创建机器人实体
- 该值在某个时间点传递到机器人实体中
- 机器人实体获取值,很可能来自某种工厂或单例
我认为备选方案3将是最好的办法。
我通过使用postLoad
事件处理程序解决了它。应用程序配置将传递给事件处理程序,并在postLoad
事件上,我将配置设置注入到需要它的相应User
实体中。