重构、测试和调试

增加代码的灵活性

有条件if的延迟执行

    public static void main(String[] args) {
        // 即使内部不调用genString,这里已经调用了genString
        print(false, genString());
        // genString的调用延迟到内部supplier.get()时候调用
        print(false, () -> genString());
    }
    // 通过Supplier方式实现有条件的延迟加载
    public static void print(boolean b, Supplier genString) {
        if (b) 
          System.out.println(genString.get());
    }

    public static void print(boolean b, String s) {
        if (b)
        System.out.println(s);
    }

    public static String genString() {
        System.out.println("genString");
        return "string";
    }

环绕执行模式

// 先定义一个函数式接口
@FunctionalInterface
public interface BufferedReaderProcessor {
  String process(...);
}

// 定义模板方法, 之前的函数接口作为参数
public static String processFile(BufferedReaderProcessor p) {
  // 开头一堆代码, 比如打开文件
  ...
  
  // 容易变化的地方调用函数接口的方法
  p.process(br);  

  // 结尾一堆代码,比如关闭文件
  ...
}

// 不同的场景通过传递不同的业务逻辑lambda,只需要一份模板即可
String oneLine = processFile((BufferedReader br) -> ...);
String twoLine = processFile((BufferedReader br) -> ...);

重构设计模式

策略模式

// 直接new接口,传入lambda实现逻辑,相当于new了实现类
Validator numericValidator = new Validator((String s) -> ...);
Validator lowerValidator = new Validator((String s) -> ...);
boolean b1 = numericValidator.validate("...");
boolean b2 = lowerValidator.validate("...");

模板模式

// 定义模板方法,增加一个Consumer参数,负责变动部分逻辑(当然根据实际场景选择合适类型的函数式接口,本质是参数化行为)
public void processTemplate(int id, Consumer logicCode) {
    XXX xxx = getXXXX(id); // 固定逻辑的模板部分
    logicCode.accept(xxx); // 需要变化的部分使用comsumer.accept调用
    closeXXX();
}

观察者模式

// 使用lambda表达式,代替繁琐的new 实例化接口对象
f.registerObserver((String tweet) -> {...});

责任链模式

// handler用UnaryOperation表示
UnaryOperation headerProcessing = (String text) -> "From Raoul ... ";
UnaryOperation spellCheckerProcessing = (String text) -> text.replaceAll(...);
// 通过Function串联起handler
Function pipeline = headerProcessing.andThen(spellCheckerProcessing);
String result = pipeline.apply("...");

你可能感兴趣的:(重构、测试和调试)