Follow treslines by email clicking Here!

Friday, August 22, 2014

Programming Design Pattern - Interpreter Pattern Applied - Best Practise

Hi there!

Today i'm gonna show the Interpreter design pattern in action. The Interpreter design pattern is a very useful programming design pattern while dealing with transformations, language issues, changing from one system to another and so on.

I'm assuming here you already know the concepts and i'll be focusing on practise. The example i will provide is a nice way to show it how it could looks like. You can always come back here, take it, adapt it and use it in your applictions as you may need. So be sure you bookmark it or join the group here on the right side of this post subscribing it.

First of all, let's take a look at the UML diagram of it. After that we will take the analogy for our example.

The UML Diagram of the Interpreter Pattern


Pay close attention, because once you understand that, everything will become clear and simple to understand. That's the reason I'm putting always the UML first. That way you'll get an eye for it with the time.





The example

In our example we will see, how we could interpret different number systems like decimal to octal or binary and so on.

The Context of the interpretation

This is one of the core concept of interpretation. It must define the context. It is in the nature of the thing. Without a context, no interpretation. So let's define our context first. We want to implement a number system interpretation. For this reason I'm defining the types of number system. After that I'm able to define the Interpreter itself and the NumberSystemInterpreter.

public enum InterpreterContext {INTEGER_TO_BIN,INTEGER_TO_HEX,INTEGER_TO_OCTAL;}

public interface Interpreter < T, V > {
    T interpret(V toInterpret, InterpreterContext context);
}

public class NumberSystemInterpreter implements Interpreter < String, Integer > {
    @Override
    public String interpret(Integer toInterpret, InterpreterContext context) {
        switch (context) {
        case INTEGER_TO_BIN:
            return Integer.toBinaryString(toInterpret);
        case INTEGER_TO_HEX:
            return Integer.toHexString(toInterpret);
        case INTEGER_TO_OCTAL:
            return Integer.toOctalString(toInterpret);
        default:return "No grammar available";
        }
    }
}

The Expressions

That's also typical for Interpreter pattern. We need some expressions to be interpreted. In our case we will be defining three Expressions. One for each number system to be interpreted.

public interface Expression < T, V > {
    String interpret(Interpreter < T, V > interpreter);
}
public class OctalExpression implements Expression < String, Integer > {
    private int toInterpret;
    public OctalExpression(int integer){this.toInterpret=integer;}
    @Override
    public String interpret(Interpreter < String, Integer > numberSystem) {
        return numberSystem.interpret(toInterpret, InterpreterContext.INTEGER_TO_OCTAL);
    }
}
public class HexExpression implements Expression < String, Integer > {
    private int toInterpret;
    public HexExpression(int integer){this.toInterpret=integer;}
    @Override
    public String interpret(Interpreter < String, Integer > numberSystem) {
        return numberSystem.interpret(toInterpret, InterpreterContext.INTEGER_TO_HEX);
    }
}
public class BinaryExpression implements Expression < String, Integer > {
    private int toInterpret;
    public BinaryExpression(int integer){
        this.toInterpret=integer;
    }
    @Override
    public String interpret(Interpreter < String, Integer > interpreter) {
        return interpreter.interpret(toInterpret, InterpreterContext.INTEGER_TO_BIN);
    }
}

The Test

Finally, let's see the interpreter in action. ;)

public class Client {
    public static void main(String[] args) {
        Interpreter < String, Integer > numberSystem = new NumberSystemInterpreter();
        Expression < String, Integer > decimalToBin = new BinaryExpression(23);
        System.out.println(decimalToBin.interpret(numberSystem));
        Expression < String, Integer > decimalToHex = new HexExpression(23);
        System.out.println(decimalToHex.interpret(numberSystem));
        Expression < String, Integer > decimalToOctal = new OctalExpression(23);
        System.out.println(decimalToOctal.interpret(numberSystem));
    }
}

That's all! Hope you like it!

No comments:

Post a Comment