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

Vik*_*dor 4 java oop design-patterns

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

这个Invoice类目前被定义如下:

  • public full-arg构造函数.
  • 公众获得者.
  • 受保护的二传手.

现在,它正在吓唬这个创建Invoice对象的类的客户端,将所有60个奇数属性传递给构造函数.由于显而易见的原因,我坚决反对公开场所.

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

Pau*_*gas 18

使用 Builder模式

使用 Joshua Bloch在他的" Effective Java 2nd Edition"一书中描述的Builder Pattern.您可以在http://www.javaspecialists.eu/archive/Issue163.html中找到相同的示例

特别注意这条线:

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


运用 BeansUtils.populate

另一种方法是使用的方法org.apache.commons.beanutils.BeanUtils.populate(Object, Map)Apache的百科全书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));

}
Run Code Online (Sandbox Code Playgroud)

输出:

NutritionFacts@188d2ae[
  servingSize=10
  servings=2
  calories=1000
  fat=1
  sodium=<null>
  carbohydrate=<null>
]
Run Code Online (Sandbox Code Playgroud)