繁体   English   中英

此代码模式的目的是什么?

[英]What purpose of this code pattern?

我正在调试其他人的代码,而我只是不明白在Java中以这种方式进行编码的好处。

我不是Java Design Pattern专家,但是我想知道何时适用?

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);
    }
}

这是一个构建器模式的错误设置很少的实现:

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

这里奇怪的是,从MyClass调用了Builder类的构造函数。 通常不会执行此操作,因为将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();

根据命名,这看起来像是一种创建模式-构建器模式。 但是,这一方法实施得不好。

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

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

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

我个人对这种模式的看法:

它鼓励创建和使用复杂的对象。 我更喜欢重构一个对象,该对象的生成器具有较小的组件。 仅通过构造函数,该对象就变得易于测试和创建。

构建器模式公开了所谓的Fluent API。 可以在每个行上进行单独的set调用,而不是在每个行上进行单独的set调用,而可以使用final生成方法来链接该类实例。 通常,在构建器对象上没有吸气剂。

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

main方法的最后一行不执行任何操作,因为您没有分配该新类。 如前所述,无论如何,您通常会使用构建方法,而不是将构建器传递给构造器

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

MyClass.newBuilder()也可以替换为new MyClass.Builder()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM