使具有相同字段的两个不同 POJO 的构建器 return 对象的最佳方法是什么
What is the best way to make a builder return objects of two different POJOs having same fields
POJO1
@Builder
Class POJO1
{
private String astring;
private String bstring;
}
POJO2
@Builder
Class POJO2
{
private String astring;
private String bstring;
}
建造者方法
private POJO1 buildPOJO()
{
return POJO1.builder().withaString().withbString().build();
}
我想要什么
POJO1 pojo = buildPOJO();
POJO2 pojo = buildPOJO(); // Same method to build both pojo's
我的代码中有这两个 pojo。我必须在几个地方建造它们。两个 pojo 总是包含相同的字段,而且字段的数量也很大。我必须构建一个 buildPOJO 方法,通过它我可以创建两个 POJO 的对象。我没有明确的想法,但因为领域总是相似的。铸造或任何其他方式是否有助于实现这一目标?
使用代理包装器,您可以使用通用接口,而无需在 类 中实现它。将公共 setter 提取到接口,并在您的构建器中使用它来设置公共字段。
代理代码最少:
public class Wrapper<T> implements InvocationHandler {
private final T delegate;
public Wrapper(T delegate) {
this.delegate = delegate;
}
public static <T, I> I proxy(T delegate, Class<I> facade) {
return (I) Proxy.newProxyInstance(
facade.getClassLoader(),
new Class[] { facade },
new Wrapper(delegate)
);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return delegate.getClass().getDeclaredMethod(method.getName(), method.getParameterTypes()).invoke(delegate, args);
}
}
并且足够简单,可以在生成器中使用:
class PojoBuilder {
private String foo;
private int bar;
private String a, b;
public PojoBuilder withFoo(String foo) {
this.foo = foo;
return this;
}
public PojoBuilder withBar(int bar) {
this.bar = bar;
return this;
}
public PojoBuilder withA(String a) {
this.a = a;
return this;
}
public PojoBuilder withB(String b) {
this.b = b;
return this;
}
public PojoA buildA() {
PojoA a = new PojoA();
buildCommon(Wrapper.proxy(a, Pojo.class));
a.setA(this.a);
return a;
}
public PojoB buildB() {
PojoB b = new PojoB();
buildCommon(Wrapper.proxy(b, Pojo.class));
b.setB(this.b);
return b;
}
private void buildCommon(Pojo common) {
common.setFoo(foo);
common.setBar(bar);
}
}
// Common setters for all pojos
interface Pojo {
void setFoo(String foo);
void setBar(int bar);
}
// One of the pojos.
// Note that this doesn't actually implement Pojo
class PojoA {
private String foo;
private int bar;
private String a;
public String getFoo() {
return foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
public int getBar() {
return bar;
}
public void setBar(int bar) {
this.bar = bar;
}
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
}
class PojoB {
private String foo;
private int bar;
private String b;
public String getFoo() {
return foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
public int getBar() {
return bar;
}
public void setBar(int bar) {
this.bar = bar;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
}
POJO1
@Builder
Class POJO1
{
private String astring;
private String bstring;
}
POJO2
@Builder
Class POJO2
{
private String astring;
private String bstring;
}
建造者方法
private POJO1 buildPOJO()
{
return POJO1.builder().withaString().withbString().build();
}
我想要什么
POJO1 pojo = buildPOJO();
POJO2 pojo = buildPOJO(); // Same method to build both pojo's
我的代码中有这两个 pojo。我必须在几个地方建造它们。两个 pojo 总是包含相同的字段,而且字段的数量也很大。我必须构建一个 buildPOJO 方法,通过它我可以创建两个 POJO 的对象。我没有明确的想法,但因为领域总是相似的。铸造或任何其他方式是否有助于实现这一目标?
使用代理包装器,您可以使用通用接口,而无需在 类 中实现它。将公共 setter 提取到接口,并在您的构建器中使用它来设置公共字段。
代理代码最少:
public class Wrapper<T> implements InvocationHandler {
private final T delegate;
public Wrapper(T delegate) {
this.delegate = delegate;
}
public static <T, I> I proxy(T delegate, Class<I> facade) {
return (I) Proxy.newProxyInstance(
facade.getClassLoader(),
new Class[] { facade },
new Wrapper(delegate)
);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return delegate.getClass().getDeclaredMethod(method.getName(), method.getParameterTypes()).invoke(delegate, args);
}
}
并且足够简单,可以在生成器中使用:
class PojoBuilder {
private String foo;
private int bar;
private String a, b;
public PojoBuilder withFoo(String foo) {
this.foo = foo;
return this;
}
public PojoBuilder withBar(int bar) {
this.bar = bar;
return this;
}
public PojoBuilder withA(String a) {
this.a = a;
return this;
}
public PojoBuilder withB(String b) {
this.b = b;
return this;
}
public PojoA buildA() {
PojoA a = new PojoA();
buildCommon(Wrapper.proxy(a, Pojo.class));
a.setA(this.a);
return a;
}
public PojoB buildB() {
PojoB b = new PojoB();
buildCommon(Wrapper.proxy(b, Pojo.class));
b.setB(this.b);
return b;
}
private void buildCommon(Pojo common) {
common.setFoo(foo);
common.setBar(bar);
}
}
// Common setters for all pojos
interface Pojo {
void setFoo(String foo);
void setBar(int bar);
}
// One of the pojos.
// Note that this doesn't actually implement Pojo
class PojoA {
private String foo;
private int bar;
private String a;
public String getFoo() {
return foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
public int getBar() {
return bar;
}
public void setBar(int bar) {
this.bar = bar;
}
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
}
class PojoB {
private String foo;
private int bar;
private String b;
public String getFoo() {
return foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
public int getBar() {
return bar;
}
public void setBar(int bar) {
this.bar = bar;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
}