A decorator pattern allows a user to add new functionality to an existing object without altering its structure.
Example
BufferedReader buffer = new BufferedReader(new FileReader("file path"));
But rather than being a decorator, this pattern looks ugly.
Using Lambda makes creating a decorator pattern very simple. Let’s look at a very simple example first, before applying the decorator pattern.
import java.util.function.Function
public class Sample {
public static void print(Integer num, String message, Function<Integer, Integer> func) {
System.out.println(num + " " + message + ": " + func.apply(num));
}
public static void main(String[] args) {
Function<Integer, Integer> increment = e -> e + 1;
Function<Integer, Integer> doubled = e -> e * 2;
print(5, "Incremented", increment);
print(5, "doubled", doubled);
}
}
Output
5 Incremented: 6 5 doubled: 10
We can easily call the increment method to increment a number. to double a number we can call the method doubled.
Now lets you want to double a number but increment it first. How are you going to carry this out? One of the answers will be to add a new method incAndThendouble like this.
Function<Integer, Integer> incAndThendouble = e -> (e + 1) * 2;
We may now use the method to get the desired outcome. but this is the incorrect strategy.
The method composition can be used to obtain the desired output that lambda provides out of the box. Let’s explore how to use the method composition.
print(5, "incrented and doubled", increment.andThen(doubled));
Output
5 increented and doubled: 12
Let’s examine how we may use this method’s composition capability to make a Decorator Pattern.
Consider a camera with filters. We could add 0 or more filters to the camera. This is a perfect example of a Decorator Pattern.
import java.awt.Color
import java.util.function.Function;
import java.util.stream.Stream;
class Camera {
private Function<Color, Color> filter;
public Camera(Function<Color, Color> ...filters) {
filter = Stream.of(filters)
.reduce(Function.identity(),Function::andThen);
}
public Color snap(Color input) {
return filter.apply(input);
}
}
public class Sample {
public static void print(Camera camera) {
//Default color of the snap
System.out.println(camera.snap(new Color(125, 125, 125)));
}
public static void main(String[] args) {
// Camera with 0 filter
print(new Camera());
//Camera with one filter
print(new Camera(Color::brighter));
//Camera with two filters
print(new Camera(Color::brighter, Color::darker));
}
}
Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…
Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…
Technology has emerged a lot in the last decade, and now we have artificial intelligence;…
Managing a database is becoming increasingly complex now due to the vast amount of data…
Overview In this article, we will explore Spring Scheduler how we could use it by…
Overview In this article, we will explore a simple Spring Boot application to implement a…