Search code examples
javadesign-patternsenumsinterface-implementation

Java implementing business logic based on EnumType given as field of Object


I know my question title is not relevant to what I'm asking, but not getting any better title. But feel free to suggest title. (So it will be helpful for others as well)

Here is the scenario I'm having:

I've enum class as below

public enum CalendarBasis {
    FISCAL_YEAR,
    CALENDAR
}

This enum is used in multiple objects in project.

I want to know the best practice/design pattern to follow which will be helpful for having functionality based on value of enum. Today there are only two values in CalendarBasis but tomorrow there can be multiple values.

This is what I'm doing currently: Consider I've Object SpecificElement which has CalendarBasis enum parameter.

public class SpecificElement {
  private SpecificValue specificValue; //some object
  // few more Objects defined
  private CalendarBasis calendarBasis;

  //getters & setters
}

Following function do some operations on SpecificElement based on type of calendarBasis.

public Foo doCalculations(SpecificElement specificElement)
{

  if(specificElement.getCalendarBasis().equals(CalendarBasis.FISCAL_YEAR)){
    //do something based on fiscal & return.
  }
  if(specificElement.getCalendarBasis().equals(CalendarBasis.CALENDAR)){
    //do something based on CALENDAR & return.
  }

}

I want to know if I can have something like multiple class Implementations based on Enum values & do operations related to that enum inside implementation class. There are around 8-10 different functions as doCalculations which has business logic based on enum type.

The code structure I'm following doesn't seems to be good practice.

So it will be helpful if someone can give me light on structuring this kind of scenario.


Solution

  • I think you can use EnumMap. If your strategies are stateless (as appears to be the case in your examples), then you simply initialize a map with all of your strategies and use StrategyType to retrieve the one you want.

        enum CalendarBasisStrategyType { FISCAL_YEAR, CALENDAR }
    
        static EnumMap<CalendarBasisStrategyType, CalendarBasisStrategy> lookupStrategy = new EnumMap();
        {
            lookupStrategy.put(FISCAL_YEAR, new FiscalYearStrategyObject());
            lookupStrategy.put(CALENDAR, new CalenderBasisStrategyObject());
        }
    
    
        CalendarBasisStrategy toStrategy(CalendarBasisStrategyType type) {
            return lookupStrategy.get(type);
        }
    
    If it is not stateless then you can use Factory for Creating Objects.
    
        enum CalendarBasisStrategyType { FISCAL_YEAR, CALENDAR }
    
        static EnumMap<CalendarBasisStrategyType, CalendarBasisFactory> lookupFactory = new EnumMap();
        {
            ...
        }
    
    
        CalendarBasisStrategy toStrategy(CalendarBasisStrategyType type) {
            return lookupFactory.get(type).newInstance();
        }