Search code examples
javalombokbuilder

Better approaches to use lombok builder + Switch statement for cleaner code


I am trying to build an object based on a type of an input parameter. The problem with the below code is that it becomes more verbose as I add more functions to it. Is there any way to simplify this using a Hashmap or are there any other lombok annotations which can help in this mapping between a string and a Lombok builder object ?

        switch (functionType) {
            case "ABS":
                function = Abs.builder().argument(args).build();
                break;
            case "SUM":
                function = Sum.builder().argument(args).build();
                break;
            case "IF":
                function = IfThen.builder().argument(args).build();
                break;
            case "IFNA":
                function = IfNa.builder().argument(args).build();
                break;

        }

Solution

  • You need essentially is a factory class. On top of that, I do not think there is a need for you to use lombok for this case. Assuming that your objects only require the args parameter to be passed in, have a look at the following:

    public class FunctionFactory {
    
        private static final Map<String, Function<List<String>, BaseFunction>> SUPPLIER_MAP = Map.of(
            "ABS", Abs::new,
            "SUM", Sum::new,
            "IF", IfThen::new,
            "IFNA", IfNa::new
        );
    
        public static BaseFunction getImplementation(String functionType, List<String> args) {
            return SUPPLIER_MAP
                .entrySet()
                .stream()
                .filter(entrySet -> entrySet.getKey().equals(functionType))
                .findAny()
                .map(Map.Entry::getValue)
                .map(function -> function.apply(args))
                .orElseThrow(() -> new IllegalStateException(String.format("Cannot find suitable implementation for type %s", functionType)));
        }
    
    }
    

    What this does essentially is to create a static map of mappings, mapping your functionType (which should have been an Enum to a constructor of each concrete implementation of the abstract BaseFunction class. Having that place, you need only to call getImplementation in order to iterate through the map, test the keys against the input value and retrieve the appropriate constructor.

    I hope this is something that could help you in order to get under way refactoring your code.