4

我有一个域对象Invoice,它有大约 60 个属性,有些是强制性的,有些是可选的。此类Invoice是底层 DB 表中记录的表示形式,其中某些列值用应用程序层类包装(例如 Enum 表示存储在 DB 中的简单整数,Currency 表示双精度等)。

这个Invoice类目前定义如下:

  • 公共全参数构造函数。
  • 公共吸气剂。
  • 受保护的二传手。

现在,创建对象的这个类的客户害怕Invoice将所有 60 个奇怪的属性传递给构造函数。出于显而易见的原因,我坚决反对将二传手公开。

您能否建议一种更好的方法来允许创建/修改此发票对象?如果您需要更多详细信息,请告诉我。

4

4 回答 4

18

使用构建器模式

使用 Joshua Bloch 在其《Effective Java 2nd Edition 》一书中描述的构建器模式。您可以在http://www.javaspecialists.eu/archive/Issue163.html中找到相同的示例

特别注意这一行:

NutritionFacts locoCola = new NutritionFacts.Builder(240, 8) // Mandatory
                          .sodium(30) // Optional
                          .carbohydrate(28) // Optional
                          .build();


使用 BeansUtils.populate

其他方法是使用org.apache.commons.beanutils.BeanUtils.populate(Object, Map)Apache Commons BeansUtils中的方法。在这种情况下,您需要一个映射来存储对象的属性。

代码

public static void main(String[] args) throws Exception {

    Map<String, Object> map = new HashMap<>();
    map.put("servingSize", 10);
    map.put("servings", 2);
    map.put("calories", 1000);
    map.put("fat", 1);

    // Create the object
    NutritionFacts bean = new NutritionFacts();

    // Populate with the map properties
    BeanUtils.populate(bean, map);

    System.out.println(ToStringBuilder.reflectionToString(bean,
            ToStringStyle.MULTI_LINE_STYLE));

}

输出

NutritionFacts@188d2ae[
  servingSize=10
  servings=2
  calories=1000
  fat=1
  sodium=<null>
  carbohydrate=<null>
]
于 2012-09-17T05:23:07.350 回答
4

你可以做的可能是将你的对象分解成更小的对象。根据上面的评论,您可能需要用户构建这些新对象,但是,根据您的数据库设计,您可能只需要将主键或外键传递给类。

然后该类将具有一些从数据库中查找相关数据的行为。这显然会增加您的数据库服务器上的负载,但它会允许您使用不太复杂(尽管数量更多)的类。复杂性的降低很可能会增加代码重用的机会,并使其更易于维护。

于 2012-09-17T05:24:41.227 回答
0

正如@Jake King 所建议的那样,将 60 个属性组合成更小的数据对象总是更好。

在这样做的同时,我将研究一个方面,哪些可能的组合是可选的,我将以这种方式进行创作。例如,如果客户点击说使用当前地址和邮寄地址,则邮寄地址是可选的。

围绕这些组合对象构建构造函数将帮助您轻松有效地管理/维护类。

于 2012-09-18T11:19:00.863 回答
-3

如果您的 Invoice 对象有 60 个属性,并且您确定不需要其中一些属性,则无需为这些属性创建 getter 和 setter。始终建议您在代码中创建所需属性的 getter setter。但您需要确保省略的字段应允许数据库中的空约束。

否则,如果您需要代码中的所有 60 个属性,则根据客户端的要求创建不同的构造函数。如果客户端只需要传递 4 个,则创建接受 4 个参数的构造函数,您可以为数据库中的属性设置默认值,其值不是客户通过。

于 2012-09-17T06:37:32.897 回答