我有一个类层次结构,其中包含一个抽象基类和几个子类。基类有 ~25 个字段,每个子类都有额外的 0-8 个字段。
我想使用 Builder 模式来构造每个子实例,并且我想尽可能使用 Lombok 以保持代码简洁。按照这个建议, 我有如下代码:
@AllArgsConstructor
@Data
public abstract class Base {
private int b1, b2, ... , b25;
}
public class C1 extends Base {
private int c11, c12, ... , c16;
@Builder
private C1(int b1, int b2, ..., int b25, int c11, ... int c16) {
super(b1, b2, ...., b25);
this.c11 = c11;
...
this.c16 = c16;
}
}
public class C2 extends Base {
@Builder
private C2(int b1, int b2, ..., int b25) {
super(b1, b2, ...., b25);
}
}
这使得构建子类变得容易
C1 c1 = C1.builder().b1(1).b2(2)....b25(25).c11(101).c12(102).build();
C2 c2 = C2.builder().b1(1).b2(2)....b25(25).build();
问题是.b1().b2()...每次创建任何子类时都会重复链接调用。
理想情况下,我想要一种通用的方法来设置 B 值,而不管正在构建哪个子类。(假设还有另一个类BValuesProvider可以提供这些值)
public void setBValues(BValuesProvider bv, // what else goes here??? //) {
// something.b1(bv.b1()).b2(bv.b2()) ...
}
public createC1(BValuesProvider bv, c11, c12, ..., c16) {
C1.Builder c1b = C1.builder().c11(c11).c12(c12)....c16(c16);
// Call setBValues somehow
return c1b.build();
}
public createC2(BValuesProvider bv) {
// Call setBValues somehow
return c2b.build();
}
我当前的解决方案是将注释附加@Data到基类以公开 setter/getter,因此我的代码如下所示:
public void setBValues(BValuesProvider bv, Base cx) {
cx.setB1(bv.b1());
cx.setB2(bv.b2());
...
cx.setB25(bv.b25());
}
public createC1(BValuesProvider bv, c11, c12, ..., c16) {
C1 c1 = C1.builder().c11(c11).c12(c12)....c16(c16).build();
setBValues(bv, c1);
return c1;
}
public createC2(BValuesProvider bv) {
C2 c2 = C2.builder().build();
setBValues(bv, c2);
return c2;
}
问题:
有一个更好的方法吗?具体来说,我觉得首先(完全)构建一个子类,然后setBxx()
在其上调用函数似乎是一种糟糕的模式。暴露 setter 本身使类非常可变。
SO 上还有其他关于构建器/继承的问题
但是,他们都没有谈论拥有每个子构建器都是其子类的“基础构建器”。所以,我不知道使用泛型,函数的第二个参数setBValues
应该是什么。
建造者模式与继承
继承 Java Builder 类
如何在 Lombok 中调用超级构造函数
我也尝试了 Lombok 的@Superbuilder
注解,但同样,虽然它大大简化了代码,但我仍然不知道如何获得基础构建器。
ITMISS
喵喵时光机
相关分类