>>分享Java编程技术,对《Java面向对象编程》等书籍提供技术支持 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 22041 个阅读者 刷新本主题
 * 贴子主题:  Java设计模式:观察者模式 回复文章 点赞(0)  收藏  
作者:flybird    发表时间:2020-01-31 00:12:51     消息  查看  搜索  好友  邮件  复制  引用

  

观察者模式

      当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。    

介绍

         意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

         主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

         何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。

         如何解决:使用面向对象技术,可以将这种依赖关系弱化。

         关键代码:在抽象类里有一个 ArrayList 存放观察者们。

         应用实例:

1、拍卖的时候,拍卖师观察最高标价,然后通知给其他竞价者竞价。

2、西游记里面悟空请求菩萨降服红孩儿,菩萨洒了一地水招来一个老乌龟,这个乌龟就是观察者,他观察菩萨洒水这个动作。

                 优点:

1、观察者和被观察者是抽象耦合的。

2、建立一套触发机制。

                 缺点:

1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。

2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。

3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

                 使用场景:            
  • 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
  • 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
  • 一个对象必须通知其他对象,而并不知道这些对象是谁。
  • 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。
     注意事项:

1、JAVA 中已经有了对观察者模式的支持类。

2、避免循环引用。

3、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。    

实现

     观察者模式使用三个类 Subject、Observer 和 Client。Subject 对象带有绑定观察者到 Client 对象和从 Client 对象解绑观察者的方法。我们创建 Subject 类、Observer 抽象类和扩展了抽象类 Observer 的实体类。

     ObserverPatternDemo,我们的演示类使用Subject和实体类对象来演示观察者模式。

    点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

步骤 1

     创建 Subject 类。                      

Subject.java

import   java . util . ArrayList ;
import   java . util . List ;

public   class   Subject   {
  
    private   List < Observer >  observers  
      =  new   ArrayList < Observer > ( ) ;
    private   int   state ;

    public   int   getState ( )   {
       return   state ;
    }

    public   void   setState ( int   state )   {
       this . state  =  state ;
       notifyAllObservers ( ) ;
    }

    public   void   attach ( Observer   observer ) {
       observers . add ( observer ) ;      
    }

    public   void   notifyAllObservers ( ) {
       for   ( Observer   observer  :  observers )   {
          observer . update ( ) ;
       }
    }  
}

步骤 2

     创建 Observer 类。                      

Observer.java

public   abstract   class   Observer   {
    protected   Subject   subject ;
    public   abstract   void   update ( ) ;
}

步骤 3

     创建实体观察者类。                      

BinaryObserver.java

public   class   BinaryObserver   extends   Observer {

    public   BinaryObserver ( Subject   subject ) {
       this . subject  =  subject ;
       this . subject . attach ( this ) ;
    }

   @ Override
    public   void   update ( )   {
       System . out . println (   " Binary String:  "  
      +  Integer . toBinaryString (   subject . getState ( )   )   ) ;
    }
}

OctalObserver.java

public   class   OctalObserver   extends   Observer {

    public   OctalObserver ( Subject   subject ) {
       this . subject  =  subject ;
       this . subject . attach ( this ) ;
    }

   @ Override
    public   void   update ( )   {
      System . out . println (   " Octal String:  "  
     +  Integer . toOctalString (   subject . getState ( )   )   ) ;
    }
}

HexaObserver.java

public   class   HexaObserver   extends   Observer {

    public   HexaObserver ( Subject   subject ) {
       this . subject  =  subject ;
       this . subject . attach ( this ) ;
    }

   @ Override
    public   void   update ( )   {
       System . out . println (   " Hex String:  "  
      +  Integer . toHexString (   subject . getState ( )   ) . toUpperCase ( )   ) ;
    }
}

步骤 4

     使用 Subject 和实体观察者对象。                      

ObserverPatternDemo.java

public   class   ObserverPatternDemo   {
    public   static   void   main ( String [ ]   args )   {
       Subject   subject  =  new   Subject ( ) ;

       new   HexaObserver ( subject ) ;
       new   OctalObserver ( subject ) ;
       new   BinaryObserver ( subject ) ;

       System . out . println ( " First state change: 15 " ) ;  
       subject . setState ( 15 ) ;
       System . out . println ( " Second state change: 10 " ) ;  
       subject . setState ( 10 ) ;
    }
}

步骤 5

     执行程序,输出结果:

First state change: 15

Hex String: F

Octal String: 17

Binary String: 1111

Second state change: 10

Hex String: A

Octal String: 12

Binary String: 1010




程序猿的技术大观园:www.javathinker.net



[这个贴子最后由 flybird 在 2020-01-31 18:39:53 重新编辑]
  Java面向对象编程-->泛型
  JavaWeb开发-->开发JavaMail Web应用
  JSP与Hibernate开发-->持久化层的映射类型
  Java网络编程-->客户端协议处理框架
  精通Spring-->CSS过渡和动画
  Vue3开发-->创建综合购物网站应用
  BIO模型的缺陷
  观察者模式和发布订阅模式的区别
  我是如何把一个15分钟的程序优化到了10秒的
  面试官问:如何排除Java虚拟机的GC引起的CPU飙高?
  18 张图弄懂面试官必问的一致性哈希
  用注解去代替if-else的技巧
  编程语言搜索量排行:用十年数据告诉你什么最受欢迎
  java常见的几种调用机制:同步调用,异步调用,回调
  Java设计模式:备忘录模式
  Java入门实用代码:线程状态监测
  Java入门实用代码:获取当前线程名称
  Java入门实用代码:格式化时间(SimpleDateFormat)
  Java 入门实用代码: 数组差集
  通过Java读取Excel数据
  Java线程实现龟兔赛跑
  更多...
 IPIP: 已设置保密
楼主      
1页 1条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。