The transformer instances all extend a common interface/base class:
public interface DomainTransformer<T extends CommonDomain> { String getSupportedMessageType(); Class<T> getDomainClass(); boolean isSupported(String messageType); } public abstract class AbstractDomainTransformer<T extends CommonDomain> implements DomainTransformer<T> { public boolean isSupported(String messageType) { return getSupportedMessageType().equalsIgnoreCase(messageType); } } @Service public class FloodTransformer extends AbstractDomainTransformer<Flood> { @Override public String getSupportedMessageType() { return "flood"; } @Override public Class getDomainClass() { return Flood.class; } }
The service can have injected all the instances of DomainTransformer that are registered with the ApplicationContext. This is the "secret sauce" that makes it easy:
@Service("domainTransformationService") @Transactional public class DomainTransformationServiceImpl implements DomainTransformationService { @Autowired private List<DomainTransformer> transformerList = Collections.emptyList();
And then, we delegate decision making to the autowired instances:
private DomainTransformer getTransformerForMessageType(String messageType) throws NoSuchFieldException { for (DomainTransformer transformer : transformerList) { if (transformer.isSupported(messageType)) { return transformer; } } // TODO throw better exception throw new NoSuchFieldException("unknown message type: " + messageType); }
Simple enough! The service code will not need to be modified if a new type of transformer is added to the system. New transformers merely needs to adhere to the DomainTransformer interface and be published to the same ApplicationContext. Once that's done, it will be injected into the List<> along with the other DomainTransformer instances.
This has a lot of uses, especially around your framework where you want to allow the business layer to add features without the framework having to change. Bulk injection is a great way to keep classes from having to know every class they will be dispatching to.
No comments:
Post a Comment