Java Function<T, R> is functional interface which accepts one type of argument and return a result. We can leverage java Function to write more maintainable codes. For example, let's say, we are going to develop an API or service method to place an order for the customer. After successful placement of order, the service method should send a notification to the customer. At this moment, we have two ways of sending notification, ie: SMS and email. But, we don't know, in future, we might need to add more notification methods.
If we don't write this method in clear and maintainable manner, we have to modify this service method every time in order to add a new notification method.
First, we will see, the solution for this using object oriented approach and then we will improve the code using Java Function in a functional way.
As usual, let's define an interface as follows.
public interface Notifier {
void notify(Order order);
}
Then we need two concrete classes for each type of notification method.
As follows, we need to create a new concrete class for each notification method.
public class SmsNotifier implements Notifier {
@Override
public void notify(Order order) {
//code to send sms notification
}
}
public class EmailNotifier implements Notifier {
@Override
public void notify(Order order) {
// Code to send email notification
}
}
Let's write some sample client code in order to place an order
//OOP approch
//Assume we have an instanc eof order service
OrderService orderService = ...
//Assume we have the order object
Order order = ...
//Assume we have the customer object
Customer customer = ....
Notifier notifier = null;
if (customer.getNotificationPreference().equals("SMS")) {
notifier = new SmsNotifier();
} else {
notifier = new EmailNotifier();
}
orderService.placeOrder(order, notifier);
@FunctionalInterface
public interface Notifier {
void notify(Order order);
}
The client code using java lambda expression is as follows.
// functional approach.
if (customer.getNotificationPreference().equals("SMS")) {
orderService.placeOrder(order, (Order odr) -> {
//code to send SMS
});
} else {
orderService.placeOrder(order, (Order odr) -> {
//code toe send email
});
}
With the functional programming approch, we don't want to create a new class for each new notification method. You need to decide which approch to use based on your use case or scope of different strategy. If it is small piece of code that you want to customize, you can go with functional approch using java lambda.