这个代码模式的目的是什么?

时间:2018-05-30 12:50:26

标签: java design-patterns

我正在调试其他人的代码,我只是不了解在Java中以这种方式编码的好处。

我不是Java设计模式专家,但我想知道什么时候适用?

public class MyClass {

    public static class Builder {
        //Getters and setters
    }

    public static Builder newBuilder() {
        return new Builder();
    }

    public MyClass(Builder builder) {
        //More Methods
    }

    public static void main(String[] args) {
        MyClass.Builder builder = MyClass.newBuilder();
        new MyClass(builder);
    }
}

3 个答案:

答案 0 :(得分:2)

这项实施的错误设置很少builder pattern

  

Builder设计模式的目的是将复杂对象的构造与其表示分开。通过这样做,相同的构造过程可以创建不同的表示。

这里奇怪的是Builder类的构造函数是从MyClass调用的。通常不会这样做,因为MyClass类与Builder绑定而不是反之。

此外,MyClass构造函数应为private,以便没有人无法直接访问它,只能使用Builder

正确的实施应如下:

public class MyClass {
    // Often fields are final to create an immutable class
    private final String fieldA;

    // Private constructor using Builder to set inner fields
    // To create MyClass you have to use Builder
    private MyClass(Builder builder) {
        // Setting fields from builder
        this.a = builder.getFieldA();
    }

    public static class Builder {
       // Fields on Builder are not final
       private String fieldA;

       //Getters and setters

       // Method to set field of builder
       public Builder setFieldA(String a) {
          this.a = a;
          return this;   // Returning this to chain setters
       }

    ...
        // Method to instantiate MyClass
        public MyClass build() {
           return new MyClass(this);
        }
    }
}

// Calling it as follow
MyClass a = new MyClass.Builder()
                .setFieldA("value")
                .setFieldB("value")
                .build();

答案 1 :(得分:2)

根据命名,这看起来像一个创作模式 - Builder模式。但是,这个没有得到很好的实施。

此模式的目的是编写可读且干净的代码以创建非常复杂的对象。一个好而简单的例子是StringBuilder。它通常使用流畅的界面实现 - 典型的例子是Stream<T>

正确的实现是例如here。它允许您使用返回构建器的方法创建对象。例如:

MyClass foo = MyClass.newBuilder()
    .cached()
    .with(new Feature1())
    .with(new Feature2())
    .foo()
    .bar()
    .build();

我个人对这种模式的观点:

  

它鼓励创建和使用复杂的对象。我更喜欢重构一个具有较小组件的构建器的对象。该对象只能通过构造函数轻松测试和创建。

答案 2 :(得分:1)

Builder模式公开了所谓的Fluent API。您可以链接setter,然后使用最终构建方法来获取类实例,而不是在每一行上进行单独的set调用。在构建器对象上通常不会有getter。

该构造函数是复制构造函数的一种形式。我猜测还有其他代码使用它来构建具有相同数据的对象的唯一实例。

您的主要方法的最后一行不做任何事情,因为您没有分配该新类。无论如何,如上所述,您通常使用构建方法,而不是将构建器传递给构造函数

MyClass foo = MyClass.newBuilder()
    .withBar("blah")
    .build();

MyClass.newBuilder()也可以由new MyClass.Builder()

替换