A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 小蜀哥哥 于 2019-6-12 21:32 编辑

一、观察者模式的定义:
简单地说,观察者模式定义了一个一对多的依赖关系,让一个或多个观察者对象监听一个主题对象。这样一来,当被观察者状态发生改变时,需要通知相应的观察者,使这些观察者对象能够自动更新。例如:GUI中的事件处理机制采用的就是观察者模式。

二、观察者模式的实现:
  • Subject(被观察的对象接口):规定ConcreteSubject的统一接口 ; 每个Subject可以有多个Observer;
  • ConcreteSubject(具体被观察对象):维护对所有具体观察者的引用的列表 ;–状态发生变化时会发送通知给所有注册的观察者。
  • Observer(观察者接口):规定ConcreteObserver的统一接口;定义了一个update()方法,在被观察对象状态改变时会被调用。
  • ConcreteObserver(具体观察者):维护一个对ConcreteSubject的引用;特定状态与ConcreteSubject同步; 实现Observer接口,update()方法的作用:一旦检测到Subject有变动,就更新信息。
  • 注:在被观察者类中需要有一个集合维护所有观察者。

    三、举例说明:
    【方案一】:自己定义接口或者类来实现观察者模式。
    步骤如下:
    (1)定义被观察者所具有的接口:
    [Java] 纯文本查看 复制代码
    package com.vince.observer;
    public interface Observable {
        //注册为一个观察者    
        public void registerObserver(Observer observer);
        
        //取消观察者    
        public void removeObserver(Observer observer);
        
        //通知所有观察者更新信息    
        public void notifyObservers();
    }

    (2)定义具体的被观察者:杯子

    [Java] 纯文本查看 复制代码
    package com.vince.observer;
    public interface Observable {
        //注册为一个观察者    
        public void registerObserver(Observer observer);
        
        //取消观察者    
        public void removeObserver(Observer observer);
        
        //通知所有观察者更新信息    
        public void notifyObservers();
    }


    (3)定义观察者所具有的共同的接口:(更新数据最终当然是在观察者那里进行啦)
    [Java] 纯文本查看 复制代码
    package com.vince.observer;
     public interface Observer {
         public void update(float price);
     }

    (4)定义具体的观察者对象:
    [Java] 纯文本查看 复制代码
    package com.vince.observer;
    public class Person implements Observer{
        private String name;
        public Person(String name){
            this.name = name;
        }
        @Override
        public void update(float price) {
            System.out.println(name+"关注的杯子的价格已更新为:"+price);
        }
    }


    (5)测试:
    [Java] 纯文本查看 复制代码
    package com.vince.observer;
    public class Test {
        public static void main(String[] args) {
            //创建一个被观察者对象
            Cup doll  = new Cup(3000);
            //创建两个观察者对象
            Person p1 = new Person("生命壹号");
            Person p2 = new Person("生命贰号");
            //注册成为一个观察者
            doll.registerObserver(p1);
            doll.registerObserver(p2);
            
            System.out.println("第一轮促销:");
            doll.setPrice(2698);// 价格变动
            System.out.println("第二轮促销:");
            doll.setPrice(2299);//
            System.out.println("第三轮促销:");
            doll.setPrice(1998);
            
            doll.removeObserver(p2);    //将生命二号移除
            System.out.println("第四轮促销:");
            doll.setPrice(1098);        
            
        }
    }

    运行后,显示结果如下:

  • 【方案二】:直接调用JDK的API去实现。
    步骤如下:
    (1) 通过继承Observable类实现具体的被观察者对象:
    [Java] 纯文本查看 复制代码
    package com.vince.observer2;
    import java.util.Observable;
    
    public class Cup extends Observable{
        private float price;
        
        public Cup(float price){
            this.price = price;
        }
        public float getPrice() {
            return price;
        }
        public void setPrice(float price) {
            this.price = price;
            this.setChanged();//通知,数据已改变
            this.notifyObservers();
        }
        
        
    }

    (2)通过实现java.util.Observer接口实现具体的观察者对象:
    [Java] 纯文本查看 复制代码
    package com.vince.observer2;
    import java.util.Observable;
    import java.util.Observer;
    
    public class Person implements Observer{
        private String name;
        public Person(String name){
            this.name = name;
        }
        @Override
        public void update(Observable o, Object arg) {
            if(o instanceof Cup){
                Cup cup = (Cup)o;
                System.out.println(name+"关注的杯子价格已更新为:"+cup.getPrice());
            }
        }
    }

    (3)测试:
    [Java] 纯文本查看 复制代码
    package com.vince.observer2;
    public class Test {
        public static void main(String[] args) {
            Cup cup = new Cup(3000);
            Person p1 = new Person("生命壹号");
            Person p2 = new Person("生命贰号");
            cup.addObserver(p1);
            cup.addObserver(p2);
            System.out.println("第一轮促销");
            cup.setPrice(2988);
            System.out.println("第二轮促销");
            cup.setPrice(2698);
            
            cup.deleteObserver(p2);
            System.out.println("第三轮促销");
            cup.setPrice(1998);
        }
    }


    运行后,结果如下:
  • 四、总结:(观察者模式的作用)
  • 观察者模式在被观察者和观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体观察者列表。由于被观察者和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次。如果被观察者和观察者都被扔到一起,那么这个对象必然跨越抽象化和具体化层次。观察者模式支持广播通讯。被观察者会向所有的登记过的观察者发出通知。


原文链接:https://www.cnblogs.com/smyhvae/p/3899208.html

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马