I want to use this type of service class in my Spring application as a "factory" to return the correct implementation of DocumentProcessor in response to a supplied enum value.
I'm doing this because I want to set up each processor itself as a component and take advantage of autowiring vs just creating new instances when each processor is needed.
I haven't really seen this done anywhere else - Can anyone tell me if this is a bad idea?
All "TypeXYZDocumentProcessor" classes are extensions of an abstract "DocumentProcessor" base class.
@Service
public class DocumentProcessorService {
@Autowired
TypeXDocumentProcessor typeXDocumentProcessor;
@Autowired
TypeYDocumentProcessor typeYDocumentProcessor;
@Autowired
TypeZDocumentProcessor typeZDocumentProcessor;
public DocumentProcessor getDocumentProcessor(DocumentType docType) {
switch (docType) {
case TYPE_X:
return typeXDocumentProcessor;
case TYPE_Y:
return typeYDocumentProcessor;
case TYPE_Z:
return typeZDocumentProcessor;
default:
return null;
}
}
}
@Component
public class TypeXDocumentProcessor extends DocumentProcessor {
...
}
public abstract class DocumentProcessor {
...
}
This is my proposition, I used Interface instead of abstract class, but if you really need an abstract class you can return on it.
@Service
public class DocumentProcessorService {
@Autowired
// you can add here for examlpe a @Qualifier("typeXDocumentProcessor"),
// then name your variable whatever you want.
DocumentProcessor typeXDocumentProcessor;
@Autowired
DocumentProcessor typeYDocumentProcessor;
@Autowired
DocumentProcessor typeZDocumentProcessor;
public DocumentProcessor getDocumentProcessor(DocumentType docType) {
switch (docType) {
case TYPE_X:
return typeXDocumentProcessor;
case TYPE_Y:
return typeYDocumentProcessor;
case TYPE_Z:
return typeZDocumentProcessor;
default:
return null;
}
}
}
@Component
public class TypeXDocumentProcessor implements DocumentProcessor {
...
}
@Component
public class TypeYDocumentProcessor implements DocumentProcessor {
...
}
@Component
public class TypeZDocumentProcessor implements DocumentProcessor {
...
}
public interface class DocumentProcessor {
...
}
You may also do something like this. I've modified your abstract class DocumentProcessor to include the DocumentType.
Code is not tested or compiled.
This way, you can keep introducing more processors types and not touch the processor service at all.
@Service
public class DocumentProcessorService {
@Autowired
List<DocumentProcessor> documentProcessors;
public DocumentProcessor getDocumentProcessor(DocumentType docType) {
return documentProcessors.stream().filter(e -> e.getDocType().equals(docType)).findFirst().get();
}
}
@Component
public class TypeXDocumentProcessor extends DocumentProcessor {
public TypeXDocumentProcessor() {
super(TYPE_X);
}
}
// More Types...
public abstract class DocumentProcessor {
...
DocumentType docType;
public DocumentProcessor(DocumentType docType) {
this.docType = docType;
}
DocumentType getDocType() {
return docType;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With