java基础巩固-宇宙第一AiYWM:为了维持生计,观察者模式阅读总结~整起

本文探讨了观察者模式如何提升效率,通过实例说明了如何使用观察者模式管理宝宝睡眠和通知变化,以及在NIO、Netty和事件发布/订阅框架中的应用。涉及EventBus、WatchService和ChannelFuture#addListener等技术.
摘要由CSDN通过智能技术生成
  • 今天看了观察者模式,总体感觉就是,之前咱们会有这样一种思想,用个if语句,switch+case语句,while等来判断一下,当……就……。
    • 但是举个例子,一个宝宝睡着了,如果按照之前的思路,就是让爸爸妈妈等一直蹲在宝宝床边,宝宝一哭,爸爸妈妈就要做出反应,这样一来爸爸妈妈啥都干不了效率太低。并且有很多孩子怎么办,花钱请保姆【加需求是不是违反了开闭原则啦】…
    • 可以使用观察者模式优化,用观察者模式后,我找一个大管家(名为注册中心)统一管理所有观察者(爸爸妈妈)和被观察者(宝宝),这会就灵活了,当宝宝(被观察者)一哭,注册中心立即给爸爸妈妈(观察者)发实时通知让赶紧来,当爸爸不想待家里管小孩了,只需给注册中心说一下,注册中心会取消他的观察者身份,他以后也不会收到实时通知;要是狗狗想加进来作为一个观察者,那么他只需要给注册中心说一声,注册中心以后就会给他也发实时通知。
  • 观察者模式
    • 观察者模式 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被完成业务的更新。观察者模式属于行为模式,一个对象(被观察者)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知它的主要成员就是观察者【观察者(observer):接受被观察者的状态变化通知,执行预先定义的业务】和被观察者【被观察者(Observerable):目标对象,状态发生变化时,将通知所有的观察者。】
      在这里插入图片描述
    • 观察者模式使用场景: 完成某件事情后,异步通知场景。如,登陆成功,发个IM消息等等。
    • 观察者模式实现的话得需要一个被观察者的类Observerable、一个或多个观察者Observer 、观察者的差异化实现【经典观察者模式封装:EventBus实战】
      • 一个被观察者的类Observerable 和 多个观察者Observer
        public class Observerable {
           
           private List<Observer> observers 
              = new ArrayList<Observer>();
           private int state;
         
           public int getState() {
              return state;
           }
         
           public void setState(int state) {
              notifyAllObservers();
           }
         
           //添加观察者
           public void addServer(Observer observer){
              observers.add(observer);      
           }
           
           //移除观察者
           public void removeServer(Observer observer){
              observers.remove(observer);      
           }
           //通知
           public void notifyAllObservers(int state){
              if(state!=1){
                  System.out.println(“不是通知的状态”);
                 return ;
              }
           
              for (Observer observer : observers) {
                 observer.doEvent();
              }
           }  
        }
        
      • 观察者的差异化实现
         //观察者
         interface Observer {  
            void doEvent();  
        }  
        //Im消息
        IMMessageObserver implements Observer{
            void doEvent(){
               System.out.println("发送IM消息");
            }
        }
        
        //手机短信
        MobileNoObserver implements Observer{
            void doEvent(){
               System.out.println("发送短信消息");
            }
        }
        //EmailNo
        EmailObserver implements Observer{
            void doEvent(){
               System.out.println("发送email消息");
            }
        }
        
      • 观察者模式有一个经典的封装好的:Guava EventBus【它提供一套基于注解的事件总线,api可以灵活的使用】
        • 被观察者角色:
          //声明一个EventBusCenter类,它类似于被观察者那种角色Observerable。
          public class EventBusCenter {
          
              private static EventBus eventBus = new EventBus();
          
              private EventBusCenter() {
              }
          
              public static EventBus getInstance() {
                  return eventBus;
              }
               //添加观察者
              public static void register(Object obj) {
                  eventBus.register(obj);
              }
              //移除观察者
              public static void unregister(Object obj) {
                  eventBus.unregister(obj);
              }
              //把消息推给观察者
              public static void post(Object obj) {
                  eventBus.post(obj);
              }
          }
          
        • 观察者角色:EventListener
          public class EventListener {
          
              @Subscribe //加了订阅,这里标记这个方法是事件处理方法  
              public void handle(NotifyEvent notifyEvent) {
                  System.out.println("发送IM消息" + notifyEvent.getImNo());
                  System.out.println("发送短信消息" + notifyEvent.getMobileNo());
                  System.out.println("发送Email消息" + notifyEvent.getEmailNo());
              }
          }
          
          //通知事件类
          public class NotifyEvent  {
          
              private String mobileNo;
          
              private String emailNo;
          
              private String imNo;
          
              public NotifyEvent(String mobileNo, String emailNo, String imNo) {
                  this.mobileNo = mobileNo;
                  this.emailNo = emailNo;
                  this.imNo = imNo;
              }
           }
          
        • 可以在main方法中使用
          ...
          public static void main(String[] args) {
          
                  EventListener eventListener = new EventListener();
                  EventBusCenter.register(eventListener);
                  EventBusCenter.post(new NotifyEvent("13372817283", "123@qq.com", "666"));
          }
          ...
          
    • 除了上面举得例子,还有NIO 中的文件目录监听服务也使用到了观察者模式。
      • NIO 中的文件目录监听服务基于 WatchService 接口和 Watchable 接口。WatchService 属于观察者,Watchable 属于被观察者。
        • Watchable 接口定义了一个用于将对象注册到 WatchService(监控服务) 并绑定监听事件的方法 register
          public interface Path
              extends Comparable<Path>, Iterable<Path>, Watchable{
          }
          
          public interface Watchable {
              WatchKey register(WatchService watcher,
                                WatchEvent.Kind<?>[] events,
                                WatchEvent.Modifier... modifiers)
                  throws IOException;
          }
          
        • WatchService 用于监听文件目录的变化,同一个 WatchService 对象能够监听多个文件目录。
          // 创建 WatchService 对象
          WatchService watchService = FileSystems.getDefault().newWatchService();
          
          // 初始化一个被监控文件夹的 Path 类:
          Path path = Paths.get("workingDirectory");
          // 将这个 path 对象注册到 WatchService(监控服务) 中去
          //register 方法返回 WatchKey 对象,通过WatchKey 对象可以获取事件的具体信息比如文件目录下是创建、删除还是修改了文件、创建、删除或者修改的文件的具体名称是什么
          WatchKey watchKey = path.register(
          watchService, StandardWatchEventKinds...);//Path 类 register 方法的第二个参数 events (需要监听的事件)为可变长参数,也就是说我们可以同时监听多种事件:WatchKey register(WatchService watcher, WatchEvent.Kind<?>... events) throws IOException;
          //WatchService 内部是通过一个 daemon thread(守护线程)采用定期轮询的方式来检测文件的变化
          
          • 常用的监听事件有 3 种:
            • StandardWatchEventKinds.ENTRY_CREATE :文件创建
            • StandardWatchEventKinds.ENTRY_DELETE : 文件删除
            • StandardWatchEventKinds.ENTRY_MODIFY : 文件修改
      • Netty 中观察者模式的运用非常多,我们平时经常使用的ChannelFuture#addListener 接口就是观察者模式的实现
        在这里插入图片描述

巨人的肩膀:
moon聊技术
设计模式之禅
head first设计模式
程序员田螺的设计模式文章
半码博客老师的关于手写一个简单的事件发布/订阅框架【首先创建一个事件类继承,所有的事件都继承该类、然后定义事件监听器接口EventListener、通过initEventMap()方法在项目启动后,利用反射注册所有的事件监听器,但是notifyListener()方法是串行执行,如果想要异步执行增加一个标记注解@AsyncExecute就行了、EventManager、一个发布事件的工具类EventPublisher、测试】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值