In java, can you use the builder pattern with required and reassignable fields?

后端 未结 5 701
南笙
南笙 2021-01-20 01:57

This is related to the following question:

How to improve the builder pattern?

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

5条回答
  •  天涯浪人
    2021-01-20 02:11

    I had a crazy idea once, and it kind of goes against some of your requirements, but I think you can have the builder constructor take the required parameters, but in a way that makes it still clear which parameters are being set. Take a look:

    package myapp;
    
    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 class Builder {
        private int a;
        private int b;
        private int c;
    
        public Builder(A a, B b, C c) {
          this.a = a.v;
          this.b = b.v;
          this.c = c.v;
        }
    
        public Builder a(int v) { a = v; return this; }
        public Builder b(int v) { b = v; return this; }
        public Builder c(int v) { c = v; return this; }
    
        public Foo build() {
          return new Foo(a, b, c);
        }
      }
    
      private static class V {
        int v;
        V(int v) { this.v = v; }
      }
      public static class A extends V { A(int v) { super(v); } }
      public static class B extends V { B(int v) { super(v); } }
      public static class C extends V { C(int v) { super(v); } }
      public static A a(int v) { return new A(v); }
      public static B b(int v) { return new B(v); }
      public static C c(int v) { return new C(v); }
    
      public static void main(String[] args) {
        Foo f1 = new Builder(a(1), b(2), c(3)).build();
        Foo f2 = new Builder(a(1), b(2), c(3)).a(4).build();
      }
    
    }
    

    For other clients, static imports are your friends:

    package myotherapp;
    
    import myapp.Foo;
    import static myapp.Foo.*;
    
    public class Program {
    
      public static void main(String[] args) {
        Foo f1 = new Builder(a(1), b(2), c(3)).build();
        Foo f2 = new Builder(a(1), b(2), c(3)).a(4).build();
      }
    
    }
    

提交回复
热议问题