Sunday, March 17, 2019

Java By Comparison: the book review

Recently I had a pleasure to read book "Java By Comparison" by Simon Harrer, Jörg Lenhard and Linus Deitz.
This book plays the role of a mentor that helps a Java beginner to pass the labyrinth of different solutions, coding styles, best practices, tools and libraries and to be ready to develop production ready software.
Java is not the first and not the last language I have learned. When I started coding Java I brought with me a lot of practices and habits I had acquired coding other languages. Fortunately, I had a couple of more experienced colleagues that helped me to become a Java programmer. This book can do the same. A reader who is familiar with the Java syntax and its main concepts but does not have enough professional development skills in Java can significantly improve these skills.
Experience is not always measured in years. It also depends on the working environment, colleagues, tasks. This book may be useful for experienced programmers as well. It refers to a lot of third party tools everyone should know. It leads the reader step-by-step from simple to tricky mistakes and traps and teaches how to avoid them. Several hours which are required to read the book will be compensated very soon by dozens of hours that will not be wasted on debugging.
I think that everyone will find a lot of new information here. I highly recommend this book for any developer who wants to improve the coding skills in Java or other languages.

Monday, March 4, 2019

New life of old Visitor design pattern

Introduction



Visitor [1, 2] is a widely known classical design pattern. There are a lot of resources that explain it in details. Without digging into the implementation I will briefly remind the idea of the pattern, will explain its benefits and downsides and will suggest some improvements that can be easily applied to it using Java programming language. 


Classical Visitor


[Visitor] Allows for one or more operation to be applied to a set of objects at runtime, decoupling the operations from the object structure. (Gang of Four book)

The pattern is based on interface typically called Visitable that has to be implemented by model class and a set of Visitors that implement method (algorithm) for each relevant model class.

public interface Visitable {
  public void accept(Visitor visitor);
}

public class Book implements Visitable {
   .......
   @Override public void accept(Visitor visitor) {visitor.visit(this)};
   .......
}

public class Cd implements Visitable {
   .......
   @Override public void accept(Visitor visitor) {visitor.visit(this)};
   .......
}

interface Visitor {
   public void visit(Book book);
   public void visit(Magazine magazine);
   public void visit(Cd cd);
}



Now we can implement various visitors, e.g.

  • PrintVisitor that prints provided Visitable
  • DbVisitor that stores it in database, 
  • ShoppingCart that adds it to a shopping cart 

etc.


Downsides of visitor pattern


  1. Return type of the visit() methods must be defined at design time. In fact in most cases these methods are void.
  2. Implementations of the accept() method are identical in all classes. Obviously we prefer to avoid code duplication. 
  3. Every time the new model class is added each visitor must be updated, so the maintenance becomes hard. 
  4. It is impossible to have optional implementations for certain model class in certain visitor. For example, software can be sent to a buyer by email while milk cannot be sent. However, both can be delivered using traditional post. So, EmailSendingVisitor cannot implement method visit(Milk) but can implement visit(Software). Possible solution is to throw UnsupportedOperationException but the caller cannot know in advance that this exception will be thrown before it calls the method. 

Improvements to classical Visitor pattern


Return value


First, let's add return value to the Visitor interface. General definition can be done using generics.

public interface Visitable {
  public <R> R accept(Visitor<R> visitor);
}


interface Visitor<R> {
   public R visit(Book book);
   public R visit(Magazine magazine);
   public R visit(Cd cd);
}


Well, this was easy. Now we can apply to our Book any kind of Visitor that returns value. For example, DbVisitor may return number of changed records in DB (Integer) and ToJson visitor may return JSON representation of our object as String. (Probably the example is not too organic, in real life we typically use other techniques for serializing object to JSON, but it is good enough as theoretically possible usage of Visitor pattern).

Default implementation


Next, let's thank Java 8 for its ability to hold default implementations inside the interface:

public interface Visitable<R> {
  default R accept(Visitor<R> visitor) {
      return visitor.visit(this);
  }
}

Now class that implements Visitable does not have to implement visit() itself: the default implementation is good enough in most cases.


The improvements suggested above fix downsides #1 and #2.

MonoVisitor


Let's try to apply further improvements. First, let's define interface MonoVisitor as following:

public interface MonoVisitor<T, R> {
    R visit(T t);
}


The name Visitor was changed to MonoVisitor to avoid name clash and possible confusion. By the book visitor defines many overloaded methods visit(). Each of them accepts argument of different type for each Visitable. Therefore, Visitor by definition cannot be generic. It has to be defined and maintained on project level. MonoVisitor defines one single method only. The type safety is guaranteed by generics. Single class cannot implement the same interface several times even with different generic parameters. This means that we will have to hold several separate implementations of MonoVisitor even if they are grouped into one class.


Function reference instead of Visitor


Since MonoVisitor has only one business method we have to create implementation per model class. However, we do not want to create separate top level classes but prefer to group them in one class. This new visitor holds Map between various Visitable classes and implementations of java.util.Function and dispatches call of visit() method to particular implementation.

So, let's have a look at MapVisitor.


public class MapVisitor<R> implements 
        Function<Class<? extends Visitable>, MonoVisitor<? extends Visitable, R>> {
    private final Map<Class<? extends Visitable>, MonoVisitor<? extends Visitable, R>> visitors;

    MapVisitor(Map<Class<? extends Visitable>, MonoVisitor<? extends Visitable, R>> visitors) {
        this.visitors = visitors;
    }

    @Override
    public MonoVisitor apply(Class clazz) {
        return visitors.get(clazz);
    }
}

The MapVisitor
  • Implements Function in order to retrieve particular implementation (full generics are omitted here for readability; have a look at the code snippet for detailed definition)
  • Receives mapping between class and implementation in map
  • Retrieves particular implementation suitable for given class
MapVisitor has a package-private constructor. Initialization of MapVisitor done using special builder is very simple and flexible:

        
MapVisitor<Void> printVisitor = MapVisitor.builder(Void.class)
        .with(Book.class, book -> {System.out.println(book.getTitle()); return null;})
        .with(Magazine.class, magazine -> {System.out.println(magazine.getName()); return null;})
        .build();


MapVisitor usage is similar to one of the traditional Visitor:

someBook.accept(printVisitor);
someMagazine.accept(printVisitor);

Our MapVisitor has one more benefit. All methods declared in interface of a traditional visitor must be implemented. However, often some methods cannot be implemented.

For example, we want to implement application that demonstrates various actions that animals can do. The user can choose an animal and then make it do something by selecting specific action from the menu.
Here is the list of animals: Duck, Penguin, Wale, Ostrich
And this is the list of actions: Walk, Fly, Swim.
We decided to have visitor per action: WalkVisitor, FlyVisitor, SwimVisitor. Duck can do all three actions, Penguin cannot fly, Wale can only swim and Ostrich can only walk. So, we decided to throw exception if a user tries to cause Wale to walk or Ostrich to fly. But such behavior is not user friendly. Indeed, a user will get error message only when he presses the action button. We would probably prefer to disable irrelevant buttons. MapVisitor allows this without additional data structure or code duplication. We even do not have to define new or extend any other interface. Instead we prefer to use standard interface java.util.Predicate:


public class MapVisitor<R> implements 
        Function<Class<? extends Visitable>, MonoVisitor<? extends Visitable, R>>, 
        Predicate<Class<? extends Visitable>> {
    private final Map<Class<? extends Visitable>, MonoVisitor<? extends Visitable, R>> visitors;
    ...............
    @Override
    public boolean test(Class<? extends Visitable> clazz) {
        return visitors.containsKey(clazz);
    }
}

Now we can call function test() in order to define whether action button for selected animal has to be enabled or shown.

Full source code of examples used here is available on github.

Conclusions


This article demonstrates several improvements that make the good old Visitor pattern more flexible and powerful. The suggested implementation avoids some boiler plate code necessary for implementation of classic Vistor pattern. Here is the brief list of improvements explained above. 
  1. visit() methods of Visitor described here can return values and therefore may be implemented as pure functions [3] that help to combine Visitor pattern with functional programming paradigm.
  2. Breaking monolithic Visitor interface into separate blocks makes it more flexible and simplifies the code maintenance. 
  3. MapVisitor can be configured using builder at runtime, so it may change its behavior depending on information known only at runtime and unavailable during development. 
  4. Visitors with different return type can be applied to the same Visitable classes.
  5. Default implementation of methods done in interfaces removes a lot of boiler plate code usual for typical Visitor implementation. 

References




Wednesday, February 13, 2019

Two ways to extend enum functionality

Preface

In my previous article I explained how and why to use enums instead of switch/case control structure in Java code. Here I will show how how to extend functionality of existing enums.


Introduction

Java enum is a kind of a compiler magic. In the byte code any enum is represented as a class that extends abstract class java.lang.Enum and has several static members. Therefore enum cannot extend any other class or enum: there is no multiple inheritance.

Class cannot extend enum as well. This limitation is enforced by compiler.

Here is a simple enum:

enum Color {red, green, blue}

This class tries to extend it:

class SubColor extends Color {}

This is the result of an attempt to compile class SubColor:

$ javac SubColor.java 
SubColor.java:1: error: cannot inherit from final Color
class SubColor extends Color {}
                       ^
SubColor.java:1: error: enum types are not extensible
class SubColor extends Color {}
^
2 errors

Enum cannot either extend or be extended. So, how is it possible to extend its functionality? The key word is "functionality". Enum can implement methods. For example enum Color may declare abstract method draw() and each member can override it:
enum Color {
    red { @Override public void draw() { } },
    green { @Override public void draw() { } },
    blue { @Override public void draw() { } },
    ;
    public abstract void draw();
}

Popular usage of this technique is explained here. Unfortunately it is no always possible to implement method in enum itself because:
  1. the enum may belong to third party library or other team in the company
  2. the enum is probably overloaded with too many other data and functions so it becomes not readable
  3. the enum belongs to module that does not have dependencies required for implementation of method draw().
This article suggests the following solutions for this problem.


Mirror enum

We cannot modify enum Color? No problem! Let's create enum DrawableColor that has exactly same elements as Color. This new enum will implement our method draw():
enum DrawableColor {
    red { @Override public void draw() { } },
    green { @Override public void draw() { } },
    blue { @Override public void draw() { } },
    ;
    public abstract void draw();
}
This enum is a kind of reflection of source enum Color, i.e. Color is its mirror.
But how to use the new enum? All our code uses Color, not DrawableColor. The simplest way to implement this transition is using built-in enum methods name() and valueOf() as following:
Color color = ...
DrawableColor.valueOf(color.name()).draw();
Since name() method is final and cannot be overridden and valueOf() is generated by a compiler these methods are always fit each other, so no functional problems are expected here. Performance of such transition is good also: method name() even does not create new String but returns pre-initialized one (see source code of java.lang.Enum). Method valueOf() is implemented using Map, so its complexity is O(1).
The code above contains obvious problem. If source enum Color is changed the secondary enum DrawableColor does not know this fact, so the trick with name() and valueOf() will fail at runtime. We do not want this to happen. But how to prevent possible failure? We have to let DrawableColor to know that its mirror is Color and enforce this preferably at compile time or at least at unit test phase. Here we suggest validation during unit tests execution. Enum can implement static initializer that is executed when enum is mentioned in any code. This actually means that if static initializer validates that enum DrawableColor fits Color it is enough to implement test like following to be sure that the code will be never broken in production environment:
@Test
public void drawableColorFitsMirror {
    DrawableColor.values();
}
Static initializer just have to compare elements of DrawableColor and Color and throw exception if they do not match. This code is simple and can be written for each particular case. Fortunately simple  open source library named enumus already implements this functionality, so the task becomes trivial:
enum DrawableColor {
    ....
    static {
        Mirror.of(Color.class);
    }
}
That's it. The test will fail if source enum and DrawableColor do not fit it any more. Utility class Mirror has other method that gets 2 arguments: classes of 2 enums that have to fit. This version can be called from any place in code and not only from enum that has to be validated.

EnumMap

Do we really have to define another enum that just holds implementation of one method? In fact, we do not have to. Here is an alternative solution. Let's define interface Drawer as following:
public interface Drawer {
    void draw();
}
Now let's create mapping between enum elements and implementation of interface Drawer:
Map<Color, Drawer> drawers = new EnumMap<>(Color.class) {{
    put(red, new Drawer() { @Override public void draw();});
    put(green, new Drawer() { @Override public void draw();})
    put(blue, new Drawer() { @Override public void draw();})
}}

The usage is simple:

drawers.get(color).draw();

EnumMap is chosen here as a Map implementation for better performance.  Map guaranties that each enum element appears there only once. However, it does not guarantee that there is entry for each enum element. But it is enough to check that size of the map is equal to number of enum elements:


drawers.size() == Color.values().length

Enumus suggests convenient utility for this case also. The following code throws IllegalStateException with descriptive message if map does not fit Color:

EnumMapValidator.validateValues(Color.class, map, "Colors map");


It is important to call the validator from the code which is executed by unit test. In this case the map based solution is safe for future modifications of source enum.


EnumMap and Java 8 functional interface


In fact, we do not have to define special interface to extend enum functionality. We can use one of functional interfaces provided by JDK starting from version 8 (Function, BiFunction, Consumer, BiConsumer, Supplier etc.) The choice depends on parameters that have to be sent to the function. For example, Supplier can be used instead of Drawable defined in the previous example:

Map<Color, Supplier<Void>> drawers = new EnumMap<>(Color.class) {{
    put(red, new Supplier<Void>() { @Override public void get();});
    put(green, new Supplier<Void>() { @Override public void get();})
    put(blue, new Supplier<Void>() { @Override public void get();})
}}

Usage of this map is pretty similar to one from the previous example:

drawers.get(color).get();

This map can be validated exactly as the map that stores instances of Drawable



Conclusions


This article shows how powerful can be Java enums if we put some logic inside. It also demonstrates two ways to expand the functionality of enums that work despite the language limitations. The article introduces to user the open source library named enumus that provides several useful utilities that help to operate enums easier. 


Featured enum instead of switch

Problem and  its solution

Switch/case is the common control structure implemented in most imperative programming languages. Switch is considered more readable than series of if/else.

Here is a simple example:
// Switch with int literal
switch (c) {
  case 1: one(); break;
  case 2: two(); break;
  case 3: three(); break;
  default: throw new UnsupportedOperationException(String.format("Operation %d is not supported", c));
}


Here is the list of the main problems in this code:

  1. Relationship between int literals (1, 2, 3) and executed code is not obvious.
  2. If one of the values (e.g. 2) becomes not supported anymore and this switch is not updated accordingly it will contain  forever the unused code.
  3. If new possible value of c (e.g. 4) is introduced and the switch is not updated accordingly the code will probably throw UnsupportedOperationException at runtime without any compile time notifications.
  4. Such switch structure tends to be duplicated several times in code that makes problems 2 and 3 even more complicated. 
The first simplest fix can be done by using int constants instead of literals. First, let's define constants:

private static int ONE = 1;
private static int TWO = 2;
private static int THREE = 3;

Now the code will look like this:

switch (c) {
  case ONE: one(); break;
  case TWO: two(); break;
  case THREE: three(); break;
  default: throw new UnsupportedOperationException(String.format("Operation %d is not supported", c));
}


(Obviously in real life the names of the constants must be self descriptive)
This snippet is more readable but all other disadvantages are still relevant. The next attempt to improve the initial code snippet uses enums introduced to Java language in version 5 in 2004. Let's define the following enum:

enum Action {ONE, TWO, THREE}


Now the switch snippet will be slightly changed:

Action a = ...
switch (a) {
  case ONE: one(); break;
  case TWO: two(); break;
  case THREE: three(); break;
  default: throw new UnsupportedOperationException(String.format("Operation %s is not supported", a));
}


This code is a little bit better: it will produce compilation error if one of the elements is removed from enum Action. However, it will not cause compilation error if additional element is added to enum Action. Some IDEs or static code analysis tools may produce warning in this case, but who is paying attention to warnings? Fortunately enum can declare abstract method that has to be implemented by each element:


enum Action {
  ONE { @Override public void action() { } }, 
  TWO { @Override public void action() { } }, 
  THREE { @Override public void action() { } }, 
  public abstract void action();
}


Now the switch statement can be replaced by single line:


Action a = ...
a.action();


This solution does not have any of disadvantages enumerated above:

  1. It is readable. The method is "attached" to enum element; one can write as many javadoc as it is needed if method meaning is unclear. The code that calls method is trivial: what can be simpler than method invocation?
  2. There is no way to remove enum constant without removing the implementation, so no unused code will remain if some functionality is no longer relevant.
  3. New enum element cannot be added without implementation of method action(). Code without implementation can't be compiled. 
  4. If several actions are required they all can be implemented in enum. As we already mentioned the code that calls specific function is trivial, so now there is no code duplication. 

Conclusion

Although switch/case structure is well known and widely used in various programming languages its usage may cause a lot of problems. Solution that uses  java enums and described above does not have these disadvantages. The next article from this series shows how to extend functionality of existing enum.

Saturday, February 2, 2019

Syntax highlighting

I have written a lot of blog posts that contain code snippets  in several programming languages (mostly Java). I separated each code snippet by empty line using monospace font to improve readability. Changing font type for code snippets is annoying and does not create the best results I want: I prefer highlighted code.

So, I searched  for tools that can do this work for me and found 2 types of tools:

  1. Tools that take your code snippet and produce HTML that can be embedded into any blog post
  2. Tools that do this transformation at runtime, so the code snippet remains clear text.

The tools of the first type are often very flexible and support various color themes but have a serious disadvantage: they generate almost not editable HTML. If  you want to change your code snippet you mostly have to regenerate its HTML representation. This also mean that you have to store your original snippet for future use, for example as a GitHub gist. It is not a show stopper but an obvious disadvantage. 

The tools of the second type do their magic at runtime. The code snippet remains human readable. The injected java script runs when page is loaded and changes color of reserved words of the programming language used for the embedded code snippet. 

The most popular and good looking syntax highlighter that I found is one created by Alex Gorbabchev.

Here is an example of code snippet highlighted by this tool:
public class MyTest {
    @Test
    public void multiply() {
        assertEquals(4, 2* 2);
    }
}

There are 2 things I had to do to make this magic happen:

  1. Include several scripts and CSS files into HTML header
  2. Write the code snippet into <pre> tag with specific style:
public class MyTest {
    @Test
    public void multiply() {
        assertEquals(4, 2* 2);
    }
}
Typically external resources (either scripts or CSS) are included by reference, i.e.
<script src='http://domain.com/path/script.js' type='text/javascript'></script> 
<link href='http://domain.com/path/style.css' rel='stylesheet' type='text/css'/> 
This works perfectly with Syntax highlighter scripts in stand alone HTML document but did not work when I added the scripts to the themes of my blog. Discovery showed that blogger.com for some reason changed absolute resource references to relative once, so they did not work. Instead of src="http://domain.com/path/script.js" that I have written the following appeared: src="//domain.com/path/script.js", i.e. the http is omitted.


So, I have downloaded all scripts to be able to put their source code directly as a body of tag <script>. For convenience and better performance I have minimized the scripts using one of online tools available in web. The code is available here. This code should be added to <head> of the HTML page.

Now I can enjoy the great syntax highlighter.