构建器模式的抽象类

Kim*_*Man 6 java abstract-class design-patterns

我有现有的模型类,它们总是使用这样的构建器模式:

public class Model {
    public static class Builder {
        private boolean isValid;
        private List<String> errorMessagesOrNull;

        public Builder setIsValid(final boolean isValid) {
            this.isValid = isValid;
            return this;
        }

        public Builder setErrorMessages(final List<String> errorMessages) {
            this.errorMessagesOrNull = errorMessages;
            return this;
        }

        public List<String> getErrorMessages() {
            return this.errorMessagesOrNull == null ? new ArrayList<>() : this.errorMessagesOrNull;
        }

        public Model Build() {
            return new Model(this);
        }
    }

    private boolean isValid;
    private List<String> errorMessages;

    private Model(final Builder builder) {
        this.isValid = builder.isValid;
        this.errorMessages = builder.getErrorMessages();
    }

    public boolean getIsValid() {
        return isValid;
    }

    public List<String> getErrorMessages() {
        return errorMessages;
    }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,模型类始终具有isValiderrorMessages。我想编写一个抽象类来尽量减少这些模型类的重复逻辑。

所以我想出了这个抽象类:

public abstract class AbstractModel<T extends AbstractModel<T>> {

    public static abstract class Builder<T> {
        private boolean isValid;
        private List<String> errorMessagesOrNull;

        public Builder<T> setIsValid(final boolean isValid) {
            this.isValid = isValid;
            return this;
        }

        public Builder<T> setErrorMessages(final List<String> errorMessages) {
            this.errorMessagesOrNull = errorMessages;
            return this;
        }

        public List<String> getErrorMessages() {
            return this.errorMessagesOrNull == null ? new ArrayList<>() : this.errorMessagesOrNull;
        }

        public abstract T Build();
    }

    private boolean isValid;
    private List<String> errorMessages;

    private AbstractModel(final Builder<T> builder) {
        this.isValid = builder.isValid;
        this.errorMessages = builder.getErrorMessages();
    }

    public boolean getIsValid() {
        return isValid;
    }

    public List<String> getErrorMessages() {
        return errorMessages;
    }
}
Run Code Online (Sandbox Code Playgroud)

但它并没有真正按照我的预期工作。当我扩展抽象类时:

public class Model extends AbstractModel<Model> {
    // Empty here since all fields are extended
}
Run Code Online (Sandbox Code Playgroud)

我不能做类似的事情:

Model model = new Model.Builder.setIsValid(true).Build();
Run Code Online (Sandbox Code Playgroud)

我希望抽象类有Builder静态类,这样我就不需要Builder每次都编写静态类。

请指教。

deh*_*asi 5

您还需要实施Builder.

public class Model extends AbstractModel<Model>{


    private Model(final Builder builder) {
        super(builder);
    }

    public static class Builder2 extends AbstractModel.Builder<Model> {

        @Override
        public Model Build() {
            return new Model(this);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后就可以调用

Model model = new Model.Builder2().Build();
Run Code Online (Sandbox Code Playgroud)

编辑

另外,AbstractBuilder 的构造函数也必须是protected.

  protected AbstractModel(final Builder<? extends Builder<T>> builder) {
        this.isValid = builder.isValid;
        this.errorMessages = builder.getErrorMessages();
    }
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!这正是我一直在寻找的。我不需要 `protected AbstractModel(final Builder&lt;? extends Builder&lt;T&gt;&gt; builder) {...}` - 我只需 `protected AbstractModel(final Builder&lt;T&gt; builder) {...}`并且运行良好。多谢。 (2认同)