I am learning stuff and have made 2 microservices, Listener and MyApp. Listener is a jms listener (consumer of messages) and MyApp is the app sending messages to queue.
I have 2 type of events CREATE and UPDATE and I want to maintain a single queue. So, my initial solution looked like below, here the Event class represent the objects to be sent to queue.
public class Event{ private String eventType; private DomainObjectA a; private DomainObjectB b; private DomainObjectC c; private DomainObjectD d; }
The initial solution was as shown below and it worked:
if("CREATE".equals(eventType) build DomainObjectA; build DomainObjectB; build DomainObjectC; build DomainObjectD; set above objects in Event object send Event object to queue else if("UPDATE".equals(eventType) build DomainObjectC; set above objects in Event object send Event object to queue
Then I thought to refactor my code in a way that depending on the event type,the MyApp will be forced to build the correct objects for type saftey. I want to prescribe my client to build the appropriate objects rather then let the client make a decision. So, I came up with below thought:
public class Event{ private String eventType; //marker interface which will be implemented by the 2 type //of payload objects (create and update), so that I can //program to interface and same idea can be extended to future // types of event payloads private EventPayload payload; } public interface EventPayload{} public class CreateEvent implements EventPayload { private DomainObjectA a; private DomainObjectB b; private DomainObjectC c; private DomainObjectD d; } public class UpdateEvent implements EventPayload { private DomainObjectC c; }
Now depending on the type of event(create or update) in my MyApp project, I want to use the corresponding EventPayload type to set data i.e. if event type is create i want to build CreateEvent object while when event type is update i want to build UpdateEvent object.
public enum EventEnum { CREATE("CREATE", new CreateEvent()), UPDATE("UPDATE", new UpdateEvent()); private final String type; private final EventPayload payload; //interface for the event types private EventEnum(String type, EventPayload payload) { this.type = type; this.payload = payload; } public String getType() { return type; } public EventPayload getPayload() { return payload; } }
So for create event in my MyApp project, I want something like
//trying to program to interface here so that I can handle diff type of payloads for same property EventPayload payload = EventEnum.CREATE.getPayload();
For update event in my MyApp project, I want something like
EventPayload payload = EventEnum.UPDATE.getPayload();
In my Listener project I want to check the type of event and based on whether its CREATE or UPDATE I want to do something like below:
@JmsListener(destination = "event-queue", containerFactory = "myFactory") public void receiveMessage(AlertEvent alertEvent) { recordStoreService.save(alertEvent); } public void save(AlertEvent alertEvent){ String event = alertEvent.getType(); EventPayload payload = alertEvent.getPayload(); if(null == event || null == payload){ LOGGER.error("Either Event or Payload is null"); return; } if("CREATE".equals(EventEnum.CREATE)) insert(payload); else update(payload); } private void insert(CreateEvent payload){ objetAMapper.insert(payload.getDomainObjectA()); objetBMapper.insert(payload.getDomainObjectB()); objetCMapper.insert(payload.getDomainObjectC()); objetDMapper.insert(payload.getDomainObjectD()); } private void update(UpdateEvent payload){ objetCMapper.insert(payload.getDomainObjectC()); }
I have 2 questions:
Is my design i.e. using enum in this way a naive idea and not a good one. If not what will be a good way to handle things in this scenario.
Programming to interfcae idea backfired as I realized I am not using it in the right way. Please can you guide me as to where am I making mistake.
Please go easy on me as I am learning things and just beginning to think about proper design. Thank you.
CREATE
andUPDATE
). This means you cannot have differentUPDATE
instances with different payloads, and that's most likely not what you want.payload
should not be a member variable of the enum.