Decorator Pattern using Java 8

In this post we are going to look at a couple of examples which use the GoF Decorator pattern. We will then refactor this code to use some of the features introduced in Java 8 which give Java a taste of functional programming. After this refactoring, we will see if the refactored code showcasing the decorator pattern becomes concise and easy to understand or makes it more complicated.

The basic idea behind the decorator pattern is that it allows us to add behavior to an object without affecting or modifying the interface of the class. I would suggest you to read and get a basic idea about the Decorator pattern in case you are completely unaware of it.

I would be considering 2 existing posts showcasing the decorator pattern and then we would be refactoring the code using Java 8.

Typical Decorator – Example one

The first example that we are going to look at is a code sample that I saw from a site, codeofdoom.com, which unfortunately does not exist anymore(domain seems to have expired). That post referred to an example which was simple to read and showed how a typical decorator pattern is implemented. I thought I had understood the pattern but I was mistaken.

The requirement in that example

The requirement that I understood from the code – We need to format a particular text supplied as input. The formatting can be one of several options- we return the text as it is, format the text to upper case, replace a word in the text with another word , concatenation of text with another string or a permutation and combination of the options. I have stated the requirements upfront but usually as developers we are never aware of the requirements upfront and requirements always keep changing. It would not make sense to create separate classes for each permutation – combination. In such situations, the decorator pattern can be extremely useful.

The example mentioned has an interface Text and a basic implementation of the same which returns the text. There are 3 classes AllCaps, StringConcat and ReplaceThisWithThat which are decorators taking the input text and adding specific behavior to it. The advantage of using the decorator pattern here is that we can use and combine 1 or more decorators to achieve formatting of the input text dynamically rather than sub-classing and creating different combinations of the sub-classes.However the implementation of a typical decorator is not so straightforward to understand. I had to debug a little bit to get a good understanding of how the code really decorates the object.

So let’s define an interface Text with a method format as shown below –

public interface Text {
    public String format(String s);
}

The BaseText class simply returns the text as is –

public class BaseText implements Text{

    public String format(String s){
        return s;
    }
}

The TextDecorator class serves as base decorator class which other classes extend. This decorator class is like a core class which helps in combining different functionalities.

public abstract class TextDecorator implements Text {

    private Text text;

    public TextDecorator(Text text) {
        this.text = text;
    }

    public abstract String format(String s);
}

The AllCaps class takes the input and formats it to uppercase –

public class AllCaps extends TextDecorator{

    public AllCaps(Text text){
        super(text);
    }

    public String format(String s){
        return text.format(s).toUpperCase();
    }
}

The StringConcat class calls format and then concatenates the input string –

public class StringConcat extends TextDecorator{

    public StringConcat(Text text){
        super(text);
    }

    public String format(String s){
        return text.format(s).concat(s);
    }
}

And finally, the class which replaces text “this” with “that” –

public class ReplaceThisWithThat extends TextDecorator{

    public ReplaceThisWithThat(Text text){
        super(text);
    }

    public String format(String s){
        return text.format(s).replaceAll("this","that");
    }
}

Test class to run the decorators –

public class TextDecoratorRunner{

    public static void main(String args[]){

        Text baseText = new BaseText();
                
        Text t = new ReplaceThisWithThat(new StringConcat(new AllCaps(baseText)) );

        System.out.println(t.format("this is some random text"));
    }
}

Notice how the call is done. It is actually inside-out but the code is read from the outside-in.

A pixel is worth 1024 bits
Flow of the Decorator pattern

The left hand side shows the calls to the format method in each decorator class and the right hand side shows how the decorators hold references or how they are chained.

The final output from this is – THIS IS SOME RANDOM TEXTthat is some random text.

Refactoring the decorator pattern using Java 8

Well, now to the main task of re-implementing the same using functional style. The BaseText class shown above has a function, format, which simply takes a String and returns a String. This can be represented using functional interface, Function<String,String> – introduced in Java 8.

import java.util.function.Function;

public class BaseText implements Function<String,String>{

    public BaseText(){
    }

    @Override
    public String apply(String t) {
        return t;
    }
}

Now, each decorator class implements a simple functionality of formatting a string in different ways and can be combined as shown below in a single class using static methods.

public class TextDecorators
{

    public static String allCaps(String s){
        return s.toUpperCase();
    }

    public static String concat(String input) {
        return input.concat("this is some random text");
    }

    public static String thisWithWhat(String input) {
        return input.replaceAll("this", "that");
    }

}

This simply leads us to the following –

public class TextDecoratorRunner {

    public static void main(String[] args) {
        String finalString = new BaseText()
                .andThen(TextDecorators::allCaps)
                .andThen(TextDecorators::concat)
                .andThen(TextDecorators::thisWithWhat)
                .apply("this is some random text");

        System.out.println(finalString);
    }
}

The code above does function chaining and uses method reference. It takes the text and passes it through a chain of functions which act as decorators. Each function applies a decoration and passes the decorated string as output to the next function which treats it as an input.  In this scenario, there is no need to have separate classes which act as decorators or the abstract base class. This implementation offers the same flexibility as the typical solution but I think it is also much much easier to understand as compared to the typical way of implementing the decorator pattern. There is also no inside-out or outside-in business when we call the function.

Typical Decorator – Example two

The second example that we are going to consider is shown here groovy decorator.  I would suggest you to read it to get a basic understanding of the use case. Also note the confusion between whether the complete text is logged in upper case or timestamp is logged in lower case.

Decorator pattern refactored

Let us try and use the same concept of function chaining to refactor this.

The code for the Logger interface would look like this –

public interface Logger {
	public void log(String message);
}

The SimpleLogger class –

public class SimpleLogger implements Logger {

	@Override
	public void log(String message) {
		System.out.println(message);

	}
}

The individual decorated logger can be represented as below –

import java.util.Calendar;

public class Loggers {
	
	public static String withTimeStamp(String message){
		
		Calendar now = Calendar.getInstance(); 
		return now.getTime() + ": "+  message;
	}
	
	public static String uppperCase(String message){
		
		return message.toUpperCase();
	}
}

And finally using function chaining –

import java.util.function.Function;
import java.util.stream.Stream;

public class LoggerTest {
	public static void main(String[] args) {

Logger logger = new SimpleLogger();

        Function<String,String> decorators = Stream.<Function<String,String>>of(Loggers::withTimeStamp,Loggers::uppperCase)
                .reduce(Function.identity(),Function::andThen);

        logger.log(decorators.apply("G'day Mate"));

	}
}

The code above looks a little daunting at first glance but it is actually simple, let us break it down –

Lines 9- 12 are the key to understanding this. I am using Stream.of and passing method references which are individual decorators.

  1. To combine them or to chain them, we use the Stream.of. The Function<String,String> in Stream.<Function<String,String>>of  is more of a compilation thing , to represent the Stream that the output is a Function<String,String>.  Using the Stream.of, we are forming a chain of functions.
  2. Now to the reduce part, the reduce part chains all of them together to form a single function. What do we want to do with each function as they come out from the stream ? We want to combine them, this is done using the andThen, that is exactly done in the 2nd parameter to the reduce function.  The first parameter to the reduce method is an initial value, this is the identity function – given a function, just return the function. Every reduction needs a starting point. In this case, the starting point is the function itself.
  3. The chaining yields a Function<String,String> decorators.
  4. We just call the apply method to this using the parameter G’day Mate which passes it through the chain of functions( decorators) and finally sends that to the logger.log method.

This version of the decorator pattern is easier to understand, we simply took a message, added the timestamp to it , converted it to upper case and logged it.The Stream.of and the methods references being passed to it might seem difficult at the first read, but trust me it is more of a new way of solving the problem and an easier one in my opinion.

Conclusion

We took 2 examples of the decorator pattern but both examples have clarified that there is certainly an easier and better way to implement the decorator pattern. In both cases the decorator pattern using the functional style is definitely more concise and easier to understand. Code that is easier to understand is always easy to maintain. Can we safely conclude that we probably don’t need the typical decorator pattern anymore?

Well, in the examples that we considered, we had just one method or one functionality to decorate, the format method in the first example and log method in the second example. In these scenarios, the functional style definitely seems better and there is no need to go about creating different classes, the abstract class and then use the cryptic way of calling them. But what if we had more than a single method to decorate ? This is something that needs to be looked at and I will try and answer that in another post.

Command Pattern using Java 8 Lambdas

I have been looking at how to improve my knowledge of Design Patterns and at the same time sharpen my Java 8 skills too. I have begun to realize that one can combine the two and also realized that Java 8 Lambdas are extremely powerful.

In this post, we are going to take a look at how the implementation of the Command Design Pattern can be simplified using Java 8 Lambdas.

I have written another blog where you can understand the essence of the Command Design Pattern.

The example we are going to refactor using Java 8 Lambdas is from here. This article on the tutorialspoint site refers to the typical way of implementing the pattern. You must take a look at it to get a basic understanding of the domain/problem at hand. The following is not a UML but I have shown the main components for the example mentioned.

 

CommandPatternWithoutClient

In short , BuyStock and SellStock are 2 commands which implement the Order interface. Stock is the recipient and finally the Broker is the invoker. The Broker class deals only with the Order interface and has no idea about the concrete commands.

Let us implement the same using Java 8 Lambdas. The Order interface is a Functional interface and each ConcreteCommand above is really a function. Do we really a class to represent each Command ? Well, take a look at the client code now using Lambdas:


public class CommandPatternDemo {
public static void main(String[] args) {
Stock abcStock = new Stock();
Broker broker = new Broker();
broker.takeOrder(() -> abcStock.buy());
broker.takeOrder(() -> abcStock.sell());
broker.placeOrders();
}
}

The Broker,Order interface remain the same and so does the Stock class. We can get rid of the individual Concrete Commands (BuyStock, SellStock) classes.

What we have done is actually passed behavior to the takeOrder method. This works as the Order interface has a method execute which takes no parameters and returns void. And hence () -> abcStock.buy() is a lambda expression which takes no parameters and returns void.

To understand this pattern better,  let us extend our problem. Imagine that in the same system, we had to sell Bonds too. The process of buying/selling stocks is different from bonds. With the Broker and the Order interface, the system can easily be extended with minimal changes.

NewCommandPattern

We added 2 more classes BuyBond and SellBond which implement the Order interface. These commands would invoke the Bond class( Receiver) which would perform the task of either buying or selling bonds. The Broker class remains untouched as it deals with only the Order Interface. Well, using Java 8 Lambdas, we don’t need the BuyBond or SellBond classes either.


//Client
public class CommandPatternDemo {
public static void main(String[] args) {
//Stock
Stock abcStock = new Stock();
Broker broker = new Broker();
broker.takeOrder(() -> abcStock.buy());
broker.takeOrder(() -> abcStock.sell());
//Bond
Bond bond = new Bond();
broker.takeOrder(() -> bond.buyBonds());
broker.takeOrder(() -> bond.sellBonds());
broker.placeOrders();
}
}

The Command pattern can be implemented easily using Lambdas. One could argue that the Order interface has just 1 method and we haven’t considered the undo and redo commands in the Command Design pattern. We can always fall back on the typical implementation of the pattern in case we need an undo and redo in addition to the execute functionality.

Having said that, do we always need an Order interface which acts as the Command interface ? How about using the Runnable interface instead  to run all the commands?  It could affect the readability of the code a little bit but otherwise the use of Java 8 Lambdas really makes the implementation easy and powerful at the same time.

Understanding the Command Design Pattern

Let us forget all design patterns for a moment and let us try to solve a simple problem using basic Java programming knowledge.

Problem: I would like to collect tasks to be executed later.

Let us break this down:

  1. The first part is collecting tasks –  this would mean using some kind of a storage which would add tasks together in a data structure. In Java, this can be done using  a Collection. So we need to maintain a Collection<Something>.
  2. Well a better idea would be a List<Something>. A List would be more specific.
  3. What is this Something ? It is a Task ! Okay,  a List<Task> ?
  4. That gives birth to a class Task, now we have a List<Task> to which we can add a task.
  5. Let us get more specific, let us begin with an ArrayList, this would be List<Task> tasks = new ArrayList<>()
  6. But this Task could be different types of tasks. Each “type” of Task… Each “type” of Task…List is generic, it is an interface,  ArrayList, LinkList are different “types” of List. So what next ?
  7. Refactor Task to an interface, and let each “type” of Task be a class which implements the interface Task.
  8. With this in place, we can add any type of Task to the tasks arraylist above. Task1,Task2….Taskn implements Task.
  9. As we are now done with collecting tasks, let us turn to the second part of running the tasks. The interface Task should have a method, let us call it executeTask(). Each type of Task will now override the executeTask() and perform it’s own task.
  10. To run each task – loop through each task and simply call the executeTask method.

for(Task task : tasks) {
task.executeTask();
}

In fact, the above for loop can be executed by using the Runnable interface/Thread class.

Let us turn our attention to the UML of actual Command Design Pattern :

 

Command_Pattern

Each type of Task is really a ConcreteCommand. The Command interface is really the same Task interface. The Invoker is a class which executes the for loop above and maintains a list of tasks/command. The only thing we have not seen is the Receiver, well when each Task/Command is executed, the Receiver will be invoked from each task. It is the work horse of the Command, the object that really does the work.

Advantages of using the Command Pattern:

  1. We can add ‘n’ different commands to the system later but the Invoker remains the same as it only deals with the Interface(Command/Task).
  2. Invoker is not aware of the work horse or the Receiver of each Command. So our system is extensible and loosely coupled.

This is really the essence of the Command Design Pattern.

I have written another blog where I dive into the implementation of the pattern.

Function composition using Java 8

The objective of this blog post is to give you a basic idea of functional composition in Java 8. We will look at 2 methods, andThen and compose which are part of the functional interface, Function.  We will then build on it further to show how we can apply a stream to a variable number of functions to combine all the functions.

Let us take a very simple example of 2 functions, one function adds 0.2 to an incoming value and another one adds 0.5 to an input value. So the input is a double and the output is also a double. This can represented as a Function<Double,Double>. Function is the functional interface introduced in Java 8.

Function<Double, Double> func1  =  d -> d + 0.2;
Function<Double, Double> func2  = d -> d + 0.5;

Both andThen and compose are default methods.

The andThen method:

To compose these 2 functions together , we can use andThen method from the Function interface. What do we get now ?

func1.andThen(func2)

Let us start with an initial value, 1.0.

Hence :

func1.andThen(func2).apply(1.0)

This gives us an output of 1.7.

How ?

  1. The call to the andThen method first applies the func1 to 1.0 which is the input. This gives us an output of 1.2 as behavior of func1 is d -> d+0.2, here d = 1.0
  2. The output from above , 1.2 , serves as an input to func2 and hence we get 1.2+0.5 = 1.7.

The compose method:

To understand this let us slightly modify the 2 functions:

Function<Double, Double> func1 = d -> d + 0.2;
Function<Double, Double> func2 = d -> d * 10.0;

The second function multiplies the incoming value by 10.

If we were to do:

func1.compose(func2).apply(1.0)

The output is 10.2

How?

  1. The call to the compose method first applies the func2 to 1.0 which is the input. This gives us an output of 10.0 as behavior of func2 is d -> d * 10.0, here d = 1.0
  2. The output from above , 10.0 , serves as an input to func1 and hence we get 10.0 + 0.2 = 10.2

What if we applied andThen to the above?  Well, the output is 12.0 . Surprised ?

Why?

  1. The call to the andThen method first applies the func1 to 1.0 which is the input. This gives us an output of 1.2 as behavior of func1 is d -> d+0.2, here d = 1.0
  2. The output from above , 1.2 , serves as an input to func2 and hence we get 1.2 * 10.0 = 12.0.

Remember:

The andThen method applies the first function, func1 to the input, that is the parameter to the apply method but the compose method operates by applying func2 to the value in the apply and then passes the value to func1.

andThen:

func1.andThen(func2).apply(1.0)

compose:

func1.compose(func2).apply(1.0)

More fun with functional composition:

Let us go back to :

Function<Double, Double> func1 = d -> d + 0.2;
Function<Double, Double> func2 = d -> d + 0.5;

When we did the following, we got the output as 1.7 :

func1.andThen(func2).apply(1.0)

Let us apply a Stream.of to func1 and func2.


Function<Double,Double> combined = Stream.of(func1,func2)
.reduce(Function.identity(), Function::andThen);
combined.apply(1.0);

The output from this is also 1.7

The Stream.of(…) returns a stream of Function<Double,Double>. The reduce method takes a Function.identity(), this is just saying, hey whatever is the next element in the stream, return it to me as it is. The Function::andThen specifies that combine each element in the stream with  andThen(). So <element_from_the stream>.andThen<next_element_from_stream>. The combination of stream and reduce method combines or chains all the functions together and gives us a single Function<Double,Double> which is a chain of functions.

Now how is this useful ? We can create a function which accepts  a variable number of functions and then they can all be chained in one place.


import java.util.function.Function;
import java.util.stream.Stream;
public class FunctionalChaining {
public static void main(String[] args)
{
Function<Double, Double> func1 = d -> d + 0.2;
Function<Double, Double> func2 = d -> d + 0.5;
// Simple chaining
System.out.println(func1.andThen(func2).apply(1.0));
// Chaining using Stream.of
Function<Double, Double> combined = Stream.of(func1, func2)
.reduce(Function.identity(), Function::andThen);
System.out.println(combined.apply(1.0));
// Pass it to a function which can accept variable number of functions.
System.out.println(combineFunctions(func1, func2));
}
private static Double combineFunctions(Function<Double, Double>… combineFunctions)
{
Function<Double, Double> chainedFunction = Stream.of(combineFunctions)
.reduce(function -> function,Function::andThen);
return chainedFunction.apply(1.0);
}
}

Output from all 3 types:

1.7
1.7
1.7

We used a very simple Function<Double,Double> which just added a double value but we could easily pass and chain functions which do a lot more.Function composition is a powerful mechanism which can be used to solve a variety of problems.Think about the decorator pattern or how consecutive filters are applied , can’t we use functional composition instead ?