I haven't programmed in Java for a long time, the question can be stupid (But the advantages are hard) There is a simple Map based Rule Engine:

 public class TaskSuspenderActions { private static final Map<String, Supplier<TaskSuspenderAction>> actions; // TaskSuspenderAction - просто интерфейс, реализация в данном случае не важна static { final Map<String, Supplier<TaskSuspenderAction>> actions_t = new HashMap<>(); actions_t.put("SUCCESS", TaskSuspenderSuccessAction::new); actions_t.put("SETTING_UP", TaskSuspenderSettingUpAction::new); actions_t.put("NOT_FOUND", TaskSuspenderNotFountAction::new); actions_t.put("INTERNAL_ERROR", TaskSuspenderInternalError::new); actions = Collections.unmodifiableMap(actions_t); } @NotNull public static TaskSuspenderAction get(@NotNull final String internalStatus) { return actions.getOrDefault(internalStatus, TaskSuspenderDefault::new).get(); } } 

The catch is that when I want to unify this class, to create a new engine (Suppose: TaskSuspenderActions<SomeInterface> ), firstly: I cannot substitute the template parameter in Supplier<SomeInterface> because, if I understood correctly, erasure etc. Secondly: how can I pass a link to new in Supplier, taking into account the type erasure, to add a new action?

    1 answer 1

    I suggest you do something like this, and pass it outside as an option:

      public class TaskSuspenderActions<T> { private final Map<String, Supplier<T>> actions; // TaskSuspenderAction - просто интерфейс, реализация в данном случае не важна private Supplier<T> defaultAction; //Конструктор с пустой мапой public TaskSuspenderActions(Supplier<T> defaultAction) { this.defaultAction = defaultAction; this.actions = new HashMap<>(); } // Конструктор принимающий мапу с экшенами public TaskSuspenderActions(Supplier<T> defaultAction, Map<String, Supplier<T>> actions){ this.actions = actions; this.defaultAction = defaultAction; } // Конструктор заполняющий мапу с помощью переданного кансюмера public TaskSuspenderActions(Supplier<T> defaultAction, Consumer<Map<String, Supplier<T>>> actionMapper) { this(defaultAction); actionMapper.accept(actions); } // Этот сетер нужен если мапа не имутабл public void setActionForInternalStatus(String internalStatus, Supplier<T>action){ actions.put(internalStatus, action); } @NotNull public T get(@NotNull final String internalStatus) { return actions.getOrDefault(internalStatus, defaultAction).get(); } } 
    • Please note your RE works as an instance, I do not recommend using static - ActivX
    • Those. is the best option to make a map on the side? I understood correctly? I know about statics, it was an option for one class. - MrBin 3:16 pm
    • Yes, in this case, you can customize the behavior. Although the public TaskSuspenderActions (Supplier <T> defaultAction, Consumer <Map <String, Supplier <T >>> actionMapper) can not be done in the case of the client, you simply fill it out with the help of the outside user, then you will not have access in general - ActivX
    • That is, in the case of such a constructor, your map will be imtable because direct access to it will not be - ActivX
    • This implementation is quite working. You can choose how you will transfer the map: 1-map is created and the set outside occurs; 2-you transfer the finished map; 3-filling with the help of a konsyumer (in this case, you do not need a designer with a map and a setter for action games) - ActivX