这是我们经常遇到的问题。必须有一些最佳实践来解决这个问题......
哪里是放置操纵POJO的通用代码的最佳位置?
这样:
我们有一个定义我们域名的架构。从那时起,我们生成一个“纯”模型,它由来自JAXB的简单对象(POJO)组成。
在使用此模型时,团队中的几位开发人员已创建了用于访问和操作模型的样板代码。它在许多地方“撒了”。有些人创建了包装器对象,它们继承了模型的实例并添加了功能。其他人创建了外部实用程序类。我正在寻求统一这个代码,以便它不再“洒在各处”。 理想情况下,逻辑可以包含在某类对象中,这些对象明确负责模型的通用操作。
让我们使用杂货店作为一般例子。模型对象包括以下内容:
Products, Aisle, Shelf, Employee, WorkSchedule, Vendor
常见的模型操作包括:
findManagerWorkingOnDay(day, schedule), findAisleForProduct(apples), countItemsOnShelf(topShelf), product.isModified(), removeProductFromVendor(apples, vendor)
我们不希望使用removeProductFromVendor
之类的功能“污染”我们的供应商POJO。同样,我们不一定要扩展每个模型对象,只是添加isModified
属性,这样我们的GUI就可以知道“启用/禁用”保存按钮。
或者我们呢?
一旦模型对象在内存中,谁应该负责操纵它 - 例如,迭代一个“今天值班的员工”列表并找到一个“经理人”?
在这些情况下,数据库调用过度,因为我们已经在内存中拥有了所需的一切(例如:我们已经查询过DataStore,我们需要在整个应用程序中使用结果对象)。 理想情况下,此代码可供具有员工列表的任何对象使用。
就最佳实践而言,静态方法的理想位置在哪里:
public static Employee findManager(List<Employee> employeesOnDuty);
将迭代员工列表(POJO)并返回第一个employee.title.toLowerCase().contains("manager")
如果团队使用此示例对象模型,则有几个人会编写这样的函数。有哪些最佳实践可以捕捉到这一责任,这样POJO仍然是“纯粹的”,并且相同的锅炉板代码不会“随处散布”。
答案 0 :(得分:6)
鉴于您的POJO对象来自供应商,我理解您不愿意为他们添加功能,并且您显然不希望代码随机散布在您的项目周围。
对于一组装饰器子类或者Ken建议的外墙来说,听起来像是一个工作。
我喜欢这里的装饰器,因为你只需要通过装饰器类的名称来引用你的供应商pojo,然后在一个地方添加行为(isModified,searchByName等)。
答案 1 :(得分:5)
据我所知,听起来你的POJO模型只是数据(或者你想保持这种方式)。为什么不创建外观对象,如Query
,Count
或其他命名的功能分组,它隐藏了操作算法的所有相关机制?
它不会污染 POJO,这听起来是你想要避免的。
答案 2 :(得分:3)
如果将业务逻辑放入模型bean中,这就是所谓的域驱动设计 - 人们会在这里和那里询问它(我个人并不是域驱动设计的崇拜者)。
希望,这有帮助。
答案 3 :(得分:2)
在类似的情况下,我们决定将所有“功能”(行为)推广为对象模型的一等公民。
所以我们现在有了不同的包,一个只有POJO,另一个是我们在这些对象上有函数对象(也就是处理器)的函数。
例如,Contract对象作为POJO,ContractBilling,ContractFinder,ContractCloser等作为处理器。他们中的大多数是根据合同或合同清单运作。
我们发现它非常有效,这迫使我们正确记录系统中的所有内容(因为函数已成为对象)。这种方法的架构优势非常棒,即使我们在这个设计中有更多的对象,我们也有更小的类更易于管理,易于理解和易于发展。
答案 4 :(得分:0)
我想对于像find这样的操作,它们属于服务类;但对于'isModified',服务类不会有帮助,它必须在pojo本身,除非当然通过服务类进行修改。然后,相应的服务类可以在集合中维护此类对象的状态。