创建具有大量属性的对象的更好方法

时间:2012-09-17 05:09:16

标签: java oop design-patterns

我有一个域对象Invoice,它有大约60个属性,有些是必需的,有些是可选的。此Invoice类表示基础数据库表中的记录,其中某些列值包含应用程序层类(如存储在DB中的简单整数的枚举,双精度货币等)。

Invoice类目前定义如下:

  • Public full-arg构造函数。
  • 公众吸气。
  • 受保护的制定者。

现在,它正在吓唬这个创建Invoice对象的类的客户端,将所有60个奇数属性传递给构造函数。我坚决反对以明显的理由制作 public

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

4 个答案:

答案 0 :(得分:18)

使用构建器模式

使用Joshua Bloch在他的书Builder Pattern中描述的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>
]

答案 1 :(得分:4)

你可以做的可能是decompose你的对象变成较小的对象。根据上面的注释,您可能需要用户构建这些新对象,但是,根据您的数据库设计,您可能只需要将主键或外键传递给该类。

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

答案 2 :(得分:0)

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

在这样做时,我将研究一个方面,可能的组合是可选的,我将以这种方式组成。例如,如果客户端点击表示使用当前地址和邮寄地址,则邮件地址是可选的。

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

答案 3 :(得分:-3)

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

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

相关问题