第 8 章 重构、测试和调试
8.1 为改善可读性和灵活性重构代码
8.1.2 从匿名类到Lambda表达式的转换
某些情况下,将匿名类转换为Lambda表达式可能是一个比较复杂的过程 。 首先,匿名类和Lambda 表达式中的this和super的含义是不同的。在匿名类中,this代表的是类自身,但是在Lambda中,它代 表的是包含类。其次,匿名类可以屏蔽包含类的变量,而Lambda表达式不能(它们会导致编译错误)
8.1.3 从Lambda表达式到方法引用的转换
8.1.4 从命令式的数据处理切换到Stream
8.1.5 增加代码的灵活性
1.采用函数式接口
- 有条件的延迟执行
- 环绕执行
8.2 使用Lambda重构面向对象的设计模式
8.2.1 策略模式
策略模式代表了 解决一类算法的通用解决方案,在运行时选择使用哪种方案.例如结算策略类,通过根据业务得到业务的唯一标识,然后拼接出不同的类名走不同的实现类.
8.2.2 模板方法
如果你需要采用某个算法的框架,同时又希望有一定的灵活度,能对它的某些部分进行改进,那么采用模 板方法设计模式是比较通用的方案。(类似继承重写父类,例如银行中 总行某一個方法,支行也需要,但是需求不同,不同的支行就可以考虑继承重写)
现在可以直接通过λ表达式插入不同的行为,不一定需要继承
8.2.3 观察者模式
观察者模式是一种比较常见的方案,某些事件发生时(比如状态转变),如果一个对象(通常我们称之为 主题)需要自动地通知其他多个对象(称为观察者),就会采用该方案。
这里代码稍微一复杂,就不适合用λ表达式,在这些情形下,还是继续使用原来用类的观察者模式比较好
8.2.4 责任链模式
8.2.5 工厂模式
8.4 调试
8.4.1 查看栈跟踪
总的来说,我们需要特别注意,涉及Lambda表达式的栈跟踪可能非常难理解。这是Java编译器未来版本可 以改进的一个方面。
随缘吧
8.4.2 使用日志调试
使用peek输出流数据处理之前和之后的值,可以清楚的看到每一步的结果
8.5 小结
Lambda表达式能提升代码的可读性和灵活性。
如果你的代码中使用了匿名类,尽量用Lambda表达式替换它们,但是要注意二者间语义的微妙差 别,比如关键字this,以及变量隐藏。
跟Lambda表达式比起来,方法引用的可读性更好 。
尽量使用Stream API替换迭代式的集合处理。
Lambda表达式有助于避免使用面向对象设计模式时容易出现的僵化的模板代码,典型的比如策略模 式、模板方法、观察者模式、责任链模式,以及工厂模式。
即使采用了Lambda表达式,也同样可以进行单元测试,但是通常你应该关注使用了Lambda表达式的 方法的行为。
尽量将复杂的Lambda表达式抽象到普通方法中。
Lambda表达式会让栈跟踪的分析变得更为复杂。
流提供的peek方法在分析Stream流水线时,能将中间变量的值输出到日志中,是非常有用的工具。