Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java侦听器实现_Java_Oop_Design Patterns - Fatal编程技术网

Java侦听器实现

Java侦听器实现,java,oop,design-patterns,Java,Oop,Design Patterns,为以下用例寻找最佳设计 用例: 在我的应用程序中,我有一个每小时运行一次的调度程序,并公开一个服务 调度程序每一小时运行一次,从特定表中检索记录,并在任何记录处理失败时发送通知。通知可以是电子邮件或短信 此外,此服务还可以由其他服务调用,用于记录处理失败通知(电子邮件或SMS) 故障类型将为batchFailure或serviceFailure 此外,还有一些道具设置类用于启用或禁用SMS和电子邮件通知 public class Settings { private boolean emai

为以下用例寻找最佳设计

用例: 在我的应用程序中,我有一个每小时运行一次的调度程序,并公开一个服务

调度程序每一小时运行一次,从特定表中检索记录,并在任何记录处理失败时发送通知。通知可以是电子邮件或短信

此外,此服务还可以由其他服务调用,用于记录处理失败通知(电子邮件或SMS)

故障类型将为batchFailure或serviceFailure

此外,还有一些道具设置类用于启用或禁用SMS和电子邮件通知

public class Settings {
  private boolean emailEnabled;
  private boolean smsEnabled;
}
根据类型,电子邮件主题应包含“批量失败”或“服务失败”主题。对于批处理作业和服务失败,其他内容保持不变

我创建了以下类:-

  • 主题-我为两者创建了一个共同的主题

    public class Notification {
    
          private int recordId;
    
          private String recordName;
    
          private String email;  // Related to email
    
          private String smsNumber; // Related to sms
    
    }
    
  • 侦听器类

    public interface RecordFailureListener {
    
      void sendNotification(Notification notification);
    
    }
    
  • 电子邮件侦听器

    public class EmailListener implements RecordFailureListener {
    
       void sendNotification(Notification notification) {
        // Code to send email here
       }
    }
    
  • 斯姆斯林纳

    public class SMSListener implements RecordFailureListener {
    
       void sendNotification(Notification notification) {
        // Code to send SMS here
       }
    }
    
    public class SmsListener implements  RecordFailureListener {
        @Override
        public void sendNotification(Notification notification) {
            //code to sms notification
        }
    }
    
  • 服务等级

    public class NotificationService {
       List<RecordFailureListener> listeners = new ArrayList(); // This list has emailListener and smsListener
    
       void sendNotification(Notification notification) {
           listeners.forEach(listener -> listener.sendNotification(notification));
       }
    }
    
    公共类通知服务{
    List listeners=new ArrayList();//此列表包含emailListener和smsListener
    无效发送通知(通知通知){
    forEach(listener->listener.sendNotification(通知));
    }
    }
    
  • 正在从计划程序调用此通知服务以处理任何故障。此外,从正在公开的故障服务

    问题:

    1) 在这里,主题似乎具有电子邮件和sms所需的属性。有没有其他更好的方法使电子邮件通知具有电子邮件所需的属性,而sms通知具有sms所需的属性?还有一些共同的性质

    2) 在调用send email和sms listener之前,请检查电子邮件侦听器中是否已启用电子邮件。这是正确的地方吗

    还有其他更好的设计吗


    谢谢

    您的问题是典型的通知程序/侦听器问题。 我还建议使用事件总线,将lisetner和通知程序解耦。其思想是通知程序将通知事件总线,事件总线将检查侦听器并在通知时更新它们。设计如下: (这是一个简单的框架,有一些方便的捷径,例如在EventBus中使用enum单例。具体细节由您决定)

    公共接口事件{
    //一般事件信息-日期、消息、元数据等。。。。
    }
    公共接口侦听器{
    公共无效监听(事件);
    }
    公共枚举事件总线{
    实例;
    私有列表侦听器=新的ArrayList;
    public void addListener(Listener newListener){
    添加(newListener);
    }
    公共无效通知(事件){
    for(侦听器:侦听器){
    listener.listen(事件);
    }
    }
    }
    公共类通知程序{
    公共无效handlePointOfInterest(…){
    //对参数等做一些有趣的事情。。。
    Event=//根据需要创建一个新事件
    EventBus.INSTANCE.notify(事件);
    ...
    }
    }
    
    您的事件接口还可以使用泛型来支持特定的元数据类型,例如您的设置。 侦听器实现可以使用泛型来处理特定类型的事件


    希望这能有所帮助,请随意要求澄清。

    只是分享一下我的设计模式,尽管这是一个老问题

    可以在NotificationService本身中验证设置,因为这是我们开始通知流的地方。假设正在从调度程序调用NotificationService进行故障通知

    public class NotificationService {
    
        Notification notification;
    
       static List<RecordFailureListener> listenerList = new ArrayList<>(); // holds email & sms listeners
    
        public NotificationService (Notification notification){
            this.notification=notification;
        }
    
        public void sendNotification(){
    
            if(Settings.emailEnabled){
                listenerList.stream().filter(i-> i instanceof EmailListener).forEach(i->i.sendNotification(notification));
            }
            if(Settings.smsEnabled){
                listenerList.stream().filter(i-> i instanceof SmsListener).forEach(i->i.sendNotification(notification));
            }
    
        }
    }
    
    EmailListener(可以在此处验证FailureType以分配电子邮件的相应主题行)

    斯姆斯林纳

    public class SMSListener implements RecordFailureListener {
    
       void sendNotification(Notification notification) {
        // Code to send SMS here
       }
    }
    
    public class SmsListener implements  RecordFailureListener {
        @Override
        public void sendNotification(Notification notification) {
            //code to sms notification
        }
    }
    
    背景

    public class Settings {
    
         public static boolean emailEnabled;
         public static boolean smsEnabled;
    }
    
    通知模型(已将failureType添加为通知属性)


    这是已经实施的吗?由于在for循环中调用了侦听器,但是电子邮件侦听器需要与电子邮件相关的属性,而票证侦听器需要与票证相关的属性,因此我如何拥有不同的主题。@user1578872:这些属性应该是事件的一个属性。此外,如果在事件接口中使用泛型,还可以将特定事件绑定到特定侦听器。正如我所写的,这里发布的设计是一个框架,为了微调和处理特定的需求,可以添加很多内容。我对使用泛型为不同的侦听器发送事件感到困惑。你能把这部分说清楚吗?@user1578872:当然。其思想是通过YourSpecificEvent类实现特定事件。然后,您可以创建一个专用的侦听器系列,该系列设计为仅处理此类事件特定的EventListener和SubhandlingEventListener侦听器,例如。使用泛型背后的想法是将侦听器绑定到特定的事件类型。事件侦听器的实现对于每个侦听器都是唯一的。这只是处理事件到监听器绑定问题的一种方法,它不是必须的。
    public class Settings {
    
         public static boolean emailEnabled;
         public static boolean smsEnabled;
    }
    
     public class Notification {
    
        private int recordId;
        private String recordName;
        private String email;
        private String smsnumber;
        private String failureType;
    }