Multilingual command handler using inheritance My problem is that you have a lot of ifconditions to be checked and inside that if condition you have multiple lines of code. I want to eliminate it and use inheritance instead. For every if statement I will be using a separate class to handle it. This is more like a derivative of the command pattern but not command pattern itself.

I have an interface which contains only one method which defines the task I want it to be implemented. I have an abstract class implementing that interface and contains a static map and static methods to add values and retrieves the task. The classes I specified will be extending this Handler class.

This is my scenario: 

I am sending a string as parameter to get a specific translator. Let's say Sinhala or Tamil or English. On each implementation of those translators, I will be adding the necessary values to the map in the Handler class in a static block. Basically adding them in the class load time.

Command Interface

public interface Command {
    LanguageTranslator getLangTranslator();
}


Handler Abstract class

public abstract class Handler implements Command {

    private static Map&lt;String, Command&gt; map = new HashMap&lt;&gt;();


    public static void AddToMap(String key, Command command){

        map.put(key,command);
    }
    public static LanguageTranslator getTranslator(String value) throws Exception {
        if (!(map.containsKey(value))){
            throw new LanguageNotFoundException("Translator not found");
        }else {
            return map.get(value).getLangTranslator();
        }
    }


 }


Sinhala Translator 

public class SiCommand extends Handler {
    static {
        Handler.AddToMap("1",new SiCommand());
    }

    @Override
    public LanguageTranslator getLangTranslator() {
        return new SiTranslator();
    }
}


Tamil Translator

public class TiCommand extends Handler {
    static {
        Handler.AddToMap("2",new TiCommand());
    }

    @Override
    public LanguageTranslator getLangTranslator() {
        return new TiTranslator();
    }
}


English Translator 

public class EnCommand extends Handler {
    static {
        Handler.AddToMap("3",new EnCommand());
    }

@Override
    public LanguageTranslator getLangTranslator() {
        return new EnTranslator();
    }
}


Demo 

 RowTranslator rowTranslator = Handler.getTranslator("2");


Questions

Since all values are assigned to the map during the class loading time these are my questions:


Is using static blocks like this a good practice?
I want to eliminate the use of if conditions as I mentioned before. By using this method, whenever someone wants to add a new if condition, you just only have to create a new class extending handler and implement it. Therefore the outside user doesn't need to know the internal handling of the Command's subclasses. The output is just gonna be a translator. Is this a good way of doing it? What are the better alternatives? What should be adjusted?


Note: I will also be focusing strictly on Open/Close principle as well.
Static registration should be avoided. Not only because it is global code, burdening start-up and the class must be loaded (!), but also for unit-testing and diversification (proposing Tamil+English and Sinhala+Tamil as two configurable choices).

This is almost something for declarative extensions, say in XML with class loading with Class.forName.

You also might opt for loading by convention or configuration: instead of 1, 2, 3 use "si", "ti", "en" checked by a config properties "translators=si,ti,en" or "si=mypackage.SiTranslator".

Or a discovery system: java SPI (Service Provider Interface): in META-INF/services/ a text file mypackage.Command containing the class name(s). You can have several jars.

A map held in a singleton object is not bad, with a small, not very dynamic domain, like languages.

Map&lt;String, Command&gt; commandsMap = new HashMap&lt;&gt;();


But you might consider the overhead of 3 or more languages, when only 2 are used on average. Say if they load a dictionary. In that case: register first
producers of those classes, which you then place in the map with a java 8 Supplier&lt;Command&gt;:

register("si", SiTranslator::new);
register("ta", TaTranslator::new);
register("en", EnTransleightour::new);


A special factory class as your Handlers does not seem needed, or can in java 8 be defined as interface annotated with @FunctionalInterface and written as anonymous lambda.



Open/Close would imply using the java SPI, where you plug-in a new language, possibly in a separate jar. You still better use "si" (best the Locale key) instead of a number "1". One interface method would be String getKey().

However I would not say that a declarative or map registry at one place would be a sin. A specified orchestrated system behavior (at one point) is just as worthwile as independent extendibility. Only if you want to plug-in new languages, say separate jars, then it matters.

The Open/Close Principle is important for multitudes, maybe fine grained business rules. Open domains of a large magnitude.