在java中,可以使用具有必需和可重新分配字段的构建器模式吗? [英] In java, can you use the builder pattern with required and reassignable fields?

查看:77
本文介绍了在java中,可以使用具有必需和可重新分配字段的构建器模式吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这与以下问题有关:

如何改进构建器模式?

我很好奇是否可以实现具有以下属性的构建器: p>

I'm curious whether it's possible to implement a builder with the following properties:


  1. 需要一些或所有参数

  2. 没有方法接收到很多参数(即没有提供默认列表

  3. 所有构建器字段都可以重新分配任意次数

  4. 编译器应检查所有参数是否已设置

  5. 要求参数最初按某种顺序设置是可以的,但一旦设置了任何参数,所有以下构建器都可以重新设置此参数(即,可以重新分配您希望的构建器的任何字段)

  6. setter不应存在重复的代码(例如,构建器子类型中没有重写setter方法)

  1. Some or all parameters are required
  2. No method receives many parameters (i.e., no list of defaults supplied to the initial builder factory method)
  3. All builder fields can be reassigned an arbitrary number of times
  4. The compiler should check that all parameters have been set
  5. It is ok to require that parameters are initially set in some order, but once any parameter is set, all following builders can have this parameter set again (i.e., you can reassign the value of any field of the builder you wish)
  6. No duplicate code should exist for setters (e.g., no overriding setter methods in builder subtypes)

一个失败的尝试在下面(省略空的私有构造函数)。请考虑下面的玩具构建器实现,并注意到带有Foo f2的行具有编译器错误,因为一个继承的setter返回一个BuilderB而不是一个BuilderFinal。有没有办法使用java类型的系统参数化setter的返回类型来实现上述目标,或者以其他方式实现。

One failed attempt is below (empty private constructors omitted). Consider the following toy builder implementation, and note that line with "Foo f2" has a compiler error because the inherited setter for a returns a BuilderB, not a BuilderFinal. Is there a way to use the java type system to parameterize the return types of the setters to achieve the above goals, or achieve them some other way.

public final class Foo {

    public final int a;
    public final int b;
    public final int c;

    private Foo(
            int a,
            int b,
            int c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }

    public static BuilderA newBuilder() {
        return new BuilderC();
    }

    public static class BuilderA {
        private volatile int a;

        public BuilderB a(int v) {
            a = v;
            return (BuilderB) this;
        }

        public int a() {
            return a;
        }
    }

    public static class BuilderB extends BuilderA {
        private volatile int b;

        public BuilderC b(int v) {
            b = v;
            return (BuilderC) this;
        }

        public int b() {
            return b;
        }
    }

    public static class BuilderC extends BuilderB {
        private volatile int c;

        public BuilderFinal c(int v) {
            c = v;
            return (BuilderFinal) this;
        }

        public int c() {
            return c;
        }
    }

    public static class BuilderFinal extends BuilderC {

        public Foo build() {
            return new Foo(
                    a(),
                    b(),
                    c());
        }
    }

    public static void main(String[] args) {
        Foo f1 = newBuilder().a(1).b(2).c(3).build();
        Foo f2 = newBuilder().a(1).b(2).c(3).a(4).build();
    }

}


推荐答案

您的要求非常困难,但请看这个通用解决方案是否适合账单:

Your requirements are really hard, but see if this generic solution fits the bill:

public final class Foo {

    public final int a;
    public final int b;
    public final int c;

    private Foo(
            int a,
            int b,
            int c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }

    public static BuilderA<? extends BuilderB<?>> newBuilder() {
        return new BuilderFinal();
    }

    public static class BuilderA<T extends BuilderB<?>> {
        private volatile int a;

        @SuppressWarnings("unchecked")
        public T a(int v) {
            a = v;
            return (T) this;
        }

        public int a() {
            return a;
        }
    }

    public static class BuilderB<T extends BuilderC<?>> extends BuilderA<T> {
        private volatile int b;

        @SuppressWarnings("unchecked")
        public T b(int v) {
            b = v;
            return (T) this;
        }

        public int b() {
            return b;
        }
    }

    public static class BuilderC<T extends BuilderFinal> extends BuilderB<T> {
        private volatile int c;

        @SuppressWarnings("unchecked")
        public T c(int v) {
            c = v;
            return (T) this;
        }

        public int c() {
            return c;
        }
    }

    public static class BuilderFinal extends BuilderC<BuilderFinal> {

        public Foo build() {
            return new Foo(
                    a(),
                    b(),
                    c());
        }
    }

    public static void main(String[] args) {
        Foo f1 = newBuilder().a(1).b(2).c(3).build();
        Foo f2 = newBuilder().a(1).b(2).c(3).a(4).build();
    }

}

这篇关于在java中,可以使用具有必需和可重新分配字段的构建器模式吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆