Java 我怎样才能更好地抽象?

Java 我怎样才能更好地抽象?,java,java-stream,simplify,Java,Java Stream,Simplify,给定一个具有两个类似方法的util类,它们仅在字段setter/getter中有所不同: public static void method_A(Dbo dbo) { if (dbo instanceof Zdbo) { ((Zdbo)dbo) .getSome() .forEach(z -> z.setFieldX(dbo.getFieldX())); } } public static void method_B

给定一个具有两个类似方法的util类,它们仅在字段setter/getter中有所不同:

public static void method_A(Dbo dbo) {
    if (dbo instanceof Zdbo) {
      ((Zdbo)dbo)
          .getSome()
          .forEach(z -> z.setFieldX(dbo.getFieldX()));
    }
  }

public static void method_B(Dbo dbo) {
    if (dbo instanceof Zdbo) {
      ((Zdbo)dbo)
          .getSome()
          .forEach(z -> z.setFieldZ(dbo.getFieldZ()));
    }
  }
我的问题是:如何消除重复代码

我的方法是实现如下目标:

private static void xxx(Dbo dbo, Consumer c) {
    if (dbo instanceof Zdbo) {
      ((Zdbo)dbo).getSome().forEach(c);
    }
  }
publicstaticstreamgetsome(dbodbo){
返回Zdbo的dbo实例((Zdbo)dbo.getSome():Stream.empty();
}
公共静态可选asZdbo(Dbo Dbo){
返回dbo instanceof Zdbo?Optional.of((Zdbo)dbo):Optional.empty();
}
公共静态无效方法(Dbo Dbo){
getSome(dbo.forEach)(z->z.setFieldX(dbo.getFieldX());
}
公共静态无效方法(Dbo Dbo){
getSome(dbo.forEach)(z->z.setFieldZ(dbo.getFieldZ());
}
我会将它保持在流或可选级别。上面的方法A和方法B可以简单地由它们的内容替换,而不需要传递setter和getter。 此外,它更通用,并且不会产生代码开销


请注意,对于instanceof+cast,下一个java可能有更好的解决方案。

我将使用
函数
提取字段,并使用
双消费者
将字段设置为每个
对象:

private static <T> void setField(
        Dbo dbo, 
        Function<? super Dbo, ? extends T> extractor, 
        BiConsumer<? super Some, ? super T> setter) {

    Consumer<Some> c = some -> setter.accept(some, extractor.apply(dbo));

    if (dbo instanceof Zdbo) ((Zdbo) dbo).getSome().forEach(c);
}

如何区分
setFieldX
setFieldZ
?一个为空,而另一个有值?
private static <T> void setField(
        Dbo dbo, 
        Function<? super Dbo, ? extends T> extractor, 
        BiConsumer<? super Some, ? super T> setter) {

    Consumer<Some> c = some -> setter.accept(some, extractor.apply(dbo));

    if (dbo instanceof Zdbo) ((Zdbo) dbo).getSome().forEach(c);
}
public static void method_A(Dbo dbo) {
    setField(dbo, Some::getFieldX, Some::setFieldX);
}

public static void method_B(Dbo dbo) {
    setField(dbo, Some::getFieldY, Some::setFieldY);
}