Java模型对象设计

Joh*_*n S 7 java model object effective-java

所以我一直在阅读一些有效的Java!本书最鼓舞人心的部分之一是Immutable Object/Builder部分,其中Bloch写的是关于"Builder" - 类,而不仅仅是POJO.

注意:我在这里谈论模型对象:例如文章汽车.

这是我之前写这些对象的方式:

public class Car {

     private String name;

     public void setName(String name) {
         this.name = name;
     }

     public String getName() {
         return name;
     }
}
Run Code Online (Sandbox Code Playgroud)

现在,当您看到此设计在许多方面存在缺陷时,它需要可变性,您必须首先使用构造函数构造对象,然后设置名称.

当然,你现在可以使name字段最终并将其用作构造函数中的参数,但是如果你有一个大对象包装例如一些SQL - Tables那么你将有一个丑陋的构造函数,如下所示:

public Car(int horsepowers, String name, String brand, int yearManufactured,
    User owner, List<User> previousOwners) {
    //Set the values
}
Run Code Online (Sandbox Code Playgroud)

这在创建对象时变得不可读,而这只是六个字段!

所以,布洛赫建议如下(具有不变性)

public class Car {

     public static class Builder {

         private String name;

         public Builder setName(String name) {
             this.name = name;
             return this;
         }

         public Car build() {
             reeturn new Car(this);
         }
     }

     private final String name;

     private Car(Builder builder) {
         name = builder.name;
     }

     public String getName() {
         return name;
     }
}

//Construction example
Car car = new Car.Builder().setName("Speedy").build();
Run Code Online (Sandbox Code Playgroud)

现在这给了我们不变的感觉!如果你有一些不是原始或不可变的对象,只需将它们复制到Buildersetter中,然后在Cargetter中再次复制它们.

但它非常冗长,如果类足够小,我一直在使用构造函数参数.如果一个类需要一个可变字段,我只是让该字段可变,如果该类有足够的属性(> 4个东西).

另一个问题是当使用android并且该类具有例如a时Bitmap,则必须返回实际的位图而不是复制它,因为这样性能相当昂贵.

我已经看到了很多这样的问题,但我似乎无法在这个问题上找到一个好的答案:这些设计是否有任何标准以及它们的设计如何?有什么好处/瑕疵?

提前致谢!

编辑:

问题是:

构造一个应该是不可变的对象模型的最佳方法是什么?A)少量字段和B)大量字段?如何处理上述Bitmap问题和类似问题?某些字段是否可变?

抱歉模糊不清.

Ada*_*old 5

设计模式一书是当前的阿尔法和欧米茄。然而,这不是新事物,但似乎它经过了时间的考验。

您可以阅读每种设计模式的详细实际示例,它们之间的关系,使用方法和时间以及对每种示例的详尽说明。当然包括了Builder模式。

关于回答您的问题,尽管他们当然没有权威性,但我可以提出我的观点。

我认为,如果字段数量很少,则可以使用构造函数。例如,如果使用checkstyle,它将在7个参数上发出警告。

但是,如果您确定要立即重构该类,或者必须扩展它,则我认为Builder模式会更好,因为它更易于重构。重构构造函数从来都不是一件好事。

如果您有7个以上的参数,我认为Builder会更好。我正在广泛从事的当前项目中一直在使用它。

请注意,通过使用Builder模式,您不会说“好吧,我是不可变的对象生成器”。您说“好的,我正在构建参数化对象”。因此,您的班级中有一组可变字段不是问题。但是,如果您将类命名为ImmutableFooDTO,后来又添加了可变字段,则会引起混乱。

因此,如果存在一组必须不可变的字段,则将它们标记为final,并使用构造函数/生成器并为可变字段提供setter。