Issue
In my Spring Boot app I have a notion of Stage and StageProcessor which processes the Stage. Stage has a StageType enum property. I have different implementations of StageProcessor interface, and these implementations are Spring beans. Now, I have another Spring bean, WorkflowProcessor, which needs to invoke appropriate StageProcessor depending on StageType of the Stage. So far I have come up with the following:
@Service
public class StageConfig {
@Autowired
private StageProcessorA stageProcessorA;
@Autowired
private StageProcessorB stageProcessorB;
public StageProcessor getProcessor(Stage stage) {
switch(stage.getType()) {
case A:
return stageProcessorA;
break;
case B:
return stageProcessorB;
break;
}
}
}
I wonder if I am missing any design pattern, or Spring mechanism. Any ideas of a better design?
Solution
This is totally based on @chrylis idea just there's no need for the processors to change their API for this, you can just do it with an annotation. Also, there's the case when you have multiple processors for one type.
interface StageProcessor {
OutputType process(Stage stage);
}
@Component
@Processes(StageType.A)
class StageProcessorA implements StageProcessor{
OutputType process(Stage stage){
//validate stage is StageType.A
}
}
@interface Processes{
StageType type;
StageType getType(){
return type;
}
}
@Component
@Processes(StageType.B)
class StageProcessorB implements StageProcessor{
}
@Service
class StageProcessors {
Map<StageType, List<StageProcessor>> stageProcessors;
StageProcessors(Collection<StageProcessor> processors) {
Map<StageType, List<StageProcessor>> map = new HashMap<>();
for (StageProcessor processor : processors) {
StageType stageType = processor.getClass().getAnnotation(Processes.class).getType();
map.computeIfAbsent(stageType, k -> new ArrayList<>()).add(processor);
}
stageProcessors = map;
assert stageProcessors.size() == expectedNumberOfProcessors;
}
List<StageProcessor> getProcessors(StageType stage) {
return stageProcessors.get(stage);
}
}
Answered By - wi2ard
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.