Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java listener implementation

Looking for a best design for the following use case.

Use case: In my application, I have a scheduler running every one hour and exposing a service.

The scheduler runs every one hour and retrieves records from a particular table and sends notification if any record processing fails. The notification could be of email or SMS.

Also, this service could be invoked by other services for record processing failure notification( Email or SMS).

The failure type will be of batchFailure or serviceFailure.

Also, there are some prop settings class to enable or disable SMS & Email notification.

public class Settings {
  private boolean emailEnabled;
  private boolean smsEnabled;
}

The email subject should contain Subject as "Batch failure" or "Service failure" based on the type. The other content remains same for both batch job and service failure.

I created the following classes:-

  1. Subject - I created a common subject for both.

    public class Notification {
    
          private int recordId;
    
          private String recordName;
    
          private String email;  // Related to email
    
          private String smsNumber; // Related to sms
    
    }
    
  2. Listener class

    public interface RecordFailureListener {
    
      void sendNotification(Notification notification);
    
    }
    
  3. EmailListener

    public class EmailListener implements RecordFailureListener {
    
       void sendNotification(Notification notification) {
        // Code to send email here
       }
    }
    
  4. SMSListener

    public class SMSListener implements RecordFailureListener {
    
       void sendNotification(Notification notification) {
        // Code to send SMS here
       }
    }
    
  5. Service class

    public class NotificationService {
       List<RecordFailureListener> listeners = new ArrayList(); // This list has emailListener and smsListener
    
       void sendNotification(Notification notification) {
           listeners.forEach(listener -> listener.sendNotification(notification));
       }
    }
    

This notification service is being invoked from scheduler for any failure. Also, from the failure service being exposed.

Question:

1) Here, the subject seems to be having the properties required for email and sms. Is there any other better way so that email notificaiton will have properties required for email and sms notification will have properties required for sms? and there are some common properties also.

2) Check if email is been enabled or not in the email listener before calling send email and same in sms listener. Is this the right place?

Any other better design?

Thanks

like image 553
user1578872 Avatar asked Feb 24 '26 18:02

user1578872


1 Answers

You problem is the classic notifier/listener problem. I would suggest using an event bus as well, as a means of decoupling the lisetner and the notifier. The idea is that the notifier will notify the event bus, and the event bus will go over the listeners and update them on notification. The design is as follows : (This is a bare skeleton, with some convenient short cuts, such as using an enum singleton for the EventBus. the fine details are up to you).

public interface Event {
    // general event information - date, message, meta data, etc....
}
public interface Listener { 
   public void listen(Event event);
}

public enum EventBus {
   INSTANCE;

   private List<Listener> listeners = new ArrayList<>;

   public void addListener(Listener newListener) {
       listeners.add(newListener);
   }

   public void notify(Event event) {
      for (Listener listener : listeners) {
         listener.listen(event);
      }
   }
}


public class Notifier {

    public void handlePointOfInterest(.....) {
        // do something interesting with the parameters, etc...
        Event event = // create a new event based on your needs
        EventBus.INSTANCE.notify(event);
        ...
    }
}

Your event interface can also use generics in order to support specific meta data types - such as your settings. You Listener implementations can use generics in order to handle specific types of events.

Hope this helps, feel free to ask for clarifications.

like image 176
Rann Lifshitz Avatar answered Feb 26 '26 09:02

Rann Lifshitz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!