如何在 Java 的函数中应用 DRY 原则?

How to apply DRY principle with Functions in Java?

在 JSF 应用程序中,我有一些具有多个 return 点的方法,如下所示:

public String Method1() {
 ...
 if (condition1) {
   elaborate1();
   return "Case1";
 }
 if (condition2) {
   elaborate2();
   return "Case2";
 }
 if (condition3) {
   elaborate3();
   return "Case3";
 }
 ...
}

条件和后续的阐述对于更多的方法是通用的,我想只写一次。不幸的是,由于多个 return 点,重构并不容易。

我对 函数式接口 不太满意,但我希望我可以使用它们来重构上面的代码。我的想法是这样写:

String elaboration1 ( T NextElaborations) {
 if (condition1) {
   elaborate1();
   return "Case1";
 }
 return NextElaborations.get();
}

可能吗?我卡住了,互联网上的大多数示例都使用 lambda 而不是方法。

更新 1 @亚历山大·伊万琴科 在评估您的答案之前,我需要研究您提供的链接,我对流不熟悉。

发布问题后,我对函数式接口进行了一些练习,最后得到以下伪 java 代码:

@FunctionalInterface
public interface MethodComposition {
   String Execute(Supplier<String> supplier)
}
...
String FinalStep() {
  FinalElaboration();
  return "finalResult";
}

String ElaborationX(Supplier<String> supplier) {
  if (conditionX) {
    elaborationX();
    return "ResultX";
  }
  return supplier.get();
}

...
 
public String Method1() {
   Supplier<String> finalSupplier = this::FinalStep;
   MethodComposition stepX = this::ElaborationX;
   ...
   return step1.Execute(() -> 
          step2.Execute(() ->
          ...
          stepN.Execute(finalSupplier))); 
   }

尽管语法丑陋,但它与我想要的非常接近,我需要更多的灵活性,因为 ElaborationX()Method1 非常相似但不相等Method_N.

您可以定义一个 集合 函数 来表示这些 条件 并将这个集合封装在里面a class 通过提供方便的交互方式。这将使该逻辑可重用。

例如,您可以创建一个 map 关联一个 Predicate,它是一个表示条件的 function解析为 boolean 值,具有特定的 return 。集合应该有一个可预测的迭代顺序以确保应用条件的顺序,因此您可以使用 LinkedHashMap 来强加迭代顺序。

并且您可以通过将单独的条件表示为对象来实现更大的灵活性,其中包含谓词和一些附加属性。这将允许对条件进行分类并构建不同的谓词组合。

您的方法 Method1() 带有一系列 if 语句,可以用映射条目流代替。或者,如果您对流感到不舒服,您可以使用普通的 for-loop 来代替它。关键是你需要一个方法来对 functions.

的集合执行迭代

I'm not comfortable with functional interfaces, but ...

I'm stuck, most examples on internet use lambdas and not methods.

无需产生许多相互依赖的方法,如elaboration1()elaboration2()等,这种方法不灵活。而且这种方法与 Java 中的 函数式接口 (您已经提到)和一般的函数式方法编程无关。要重构您的代码以使其在 stile 中发挥作用,除了真正熟悉函数式编程之外别无他法。

我鼓励你看看 lambda expressions 上的这些官方教程和 streams.

stream-logic的描述:

实现可能如下所示:

public class FunctionStorage {
    
    public static final Map<Predicate<String>, String> conditions = new LinkedHashMap<>(); // LinkedHashMap insures the order of iteration
        
    static {
        conditions.put(s -> false, "1");
        conditions.put(s -> true,  "2");
        conditions.put(s -> false, "3");
    }
    
    public static Stream<Map.Entry<Predicate<String>, String>> getConditions() {
        return conditions.entrySet().stream();
    }  
}

main()

public static void main(String[] args) {
    String result = FunctionStorage.getConditions()        // a stream of entries
        .filter(entry -> entry.getKey().test("someValue")) // filtering the entry containing the matching condition
        .findFirst()
        .map(Map.Entry::getValue)                          // extracting the return value
        .orElse("defaultValue"); // orElseThrow() depending on your needs
}