Modern Java in Action 4 - refactoring and testing
Refactoring, testing

Contents
Refatoring
Here are three simple refactorings that can be used if you want to migrate your codebase to Java 8 (or higher). You may want to do so for many different reasons (readability, conciseness, code reuse, security).
- Refactoring anonymous classes to lambda expressions
- Refactoring lambda expressions to method references
- Refactoring imperative-style data processing to streams
Recommended paper about automatic refactoing of pre-Java 8 codebases into Java8: Lambda Refactoring
Gotchas
- different meaning of
this
andsuper
(in lambdathis
refers to enclosing class, in inner class - to itself) - lambdas cannot (and anonymous inner classes can) shadow enclosing class variables
Code flexibility
Question: when to introduce functional interfaces?
deferred exectution
One usecase is for deferred execution; for example: this code exposes interrnal isLoggable
|
|
so one can do
|
|
and in order to not evaluate the logged message on each call, we provide a Supplier<String>
:
|
|
design patterns
The below patterns can be cleanly expressed with lambdas:
- Strategy - instead of creating behaviors as instances of specific abstract class or interface implementation and using them as constructor parameter in a class that uses specific strategy, you can pass a single lambda expression
- Template method - instead of defining abstract method for changing (moving part) fragment of a method and overriding the change in subclasses, you can pass lambda expression
- Observer - registering an observer doesn’t require creation of Observer implementations; it can be done by passing a lambda that will be called when observable wants to notify observers (good for simple behaviors)
- Chain of responsibility - each class that will take part in forming a chain would do its work and then call successor’s handling method; this can be easily expressed as function composition
- Factory - you create objects without exposing constructor
Testing lambdas
Here are some hints:
- focus on testing core lambdas behaviors
- extract complex lambdas to methods so that they can be separately tested
- when testing higher order lambdas, write tests that work with different lambdas
- stacktraces are easier to read when they refer methods than when they use lambdas
- use
peek()
to log data from in the middle of the pipeline
Ten wpis jest częścią serii modern-java-in-action.
- 2022-05-07 - Modern Java in Action 8 - concurrency and reactive programming
- 2022-02-07 - Modern Java in Action 7 - notes about the module system
- 2022-30-06 - Modern Java in Action 6 - Time and Date
- 2022-20-06 - Modern Java in Action 5 - Optional
- 2022-17-06 - Modern Java in Action 4 - refactoring and testing
- 2022-15-06 - Modern Java in Action 3 - collection API
- 2022-14-06 - Modern Java in Action 2 - fork-join and spliterators
- 2022-03-06 - Modern Java in Action 1 - Java 8 refresher