zoukankan      html  css  js  c++  java
  • GoF--观察者模式

      观察者模式定义了对象间的一对多依赖关系,让一个或多个观察者对象观察一个主题对象。当主题对象的状态发生变化时,系统恩那个通知所有的依赖于此对象观察者对象,从而使得观察者对象能够自动更新。

      在观察者模式中,被观察的对象尝尝被称为目标或主题(Subject),依赖的对象被称为观察者(Observer)。

      Interface:Observer

    package edu.pri.lime._9_3_9.bean;
    
    
    //观察者接口,程序中所有观察者都应该实现该接口
    public interface Observer {
    
    //    Observable:代表被观察对象,即目标或主题
    //    Observable:是一个抽象基类,程序中被观察者应该继承该抽象基类。
    //    arg:
        void update(Observable o,Object arg);
    
    }

      Class:Observable

    package edu.pri.lime._9_3_9.bean;
    
    import java.util.ArrayList;
    import java.util.List;
    /*
     * 该抽象类是所有被观察者(主题)的基类,
     * 它提供了registObserver()方法用于注册一个新的观察者;
     * 并提供了一个removeObserver()方法用于删除一个已注册的观察者;
     * 当具体被观察对象(主题)的状态发生改变时,具体被观察对象(主题)会调用notifyObservers()方法来通知所有观察者。
     */
    public abstract class Observable {
        
    //    用一个List来保存该对象上所有绑定的事件监听器
        List<Observer> observers = new ArrayList<Observer>();
    //    用于从该主题上注册观察者
        public void registObserver(Observer o){
            observers.add(o);
        }
    //    用于从该主题上注册观察者
        public void removeObserver(Observer o){
            observers.remove(o);
        }
    //    通知该主题上注册的所有观察者
        public void notifyObservers(Object value){
    //        遍历注册到该主题上的所有被观察者
            for(Observer o : observers){
    //            显式调用每个观察者的update()方法
                o.update(this, value);
            }
        }
    }

      Class:Product

    package edu.pri.lime._9_3_9.bean;
    
    public class Product extends Observable {
    
        private String name;
        private double price;
        public Product() {
            super();
            // TODO Auto-generated constructor stub
        }
        public Product(String name, double price) {
            super();
            this.name = name;
            this.price = price;
        }
    //    当程序调用name的setter方法来修改Product的name成员变量时,
    //    程序自然触发该对象上注册的所有观察者
        public void setName(String name) {
            this.name = name;
            notifyObservers(name);
        }
    //    当程序调用price的setter方法来修改Product的price成员变量时,
    //    程序自然触发该对象上注册的所有观察者
        public void setPrice(double price) {
            this.price = price;
            notifyObservers(price);
        }
        public String getName() {
            return name;
        }
        public double getPrice() {
            return price;
        }
        
    }

      Class:NameObserver

    package edu.pri.lime._9_3_9.bean;
    
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    
    public class NameObserver implements Observer {
    
    //    实现观察者必须实现的update方法
        public void update(Observable o, Object arg) {
            if(arg instanceof String){
                String name = (String) arg;
                JFrame f = new JFrame("观察者");
                JLabel l = new JLabel("名称改变为:" + name);
                f.add(l);
                f.pack();
                f.setVisible(true);
                System.out.println("名称观察者:" + o + "物品名称已改变为:" + name);
            }
        }
    }

      Class:PriceObserver

    package edu.pri.lime._9_3_9.bean;
    
    public class PriceObserver implements Observer {
    
    //    实现观察者必须实现的update()方法
        public void update(Observable o, Object arg) {
            if(arg instanceof Double){
                System.out.println("价格观察者:" + o + "物品价格已改变为:" + arg);
            }
        }
    
    }

      Class:Test

    package edu.pri.lime._9_3_9.main;
    
    import edu.pri.lime._9_3_9.bean.NameObserver;
    import edu.pri.lime._9_3_9.bean.PriceObserver;
    import edu.pri.lime._9_3_9.bean.Product;
    
    public class Test {
    
        public static void main(String[] args) throws InterruptedException{
    //        创建一个主题对象
            Product pro = new Product("桌子",300);
    //        创建两个观察者对象
            NameObserver nameObs = new NameObserver();
            PriceObserver priObs = new PriceObserver();
    //        向主题对象上注册两个观察者对象
            pro.registObserver(nameObs);
            pro.registObserver(priObs);
    //        程序调用setter方法来改变Product的name和price成员变量
            pro.setName("高级书桌");
            Thread.sleep(3000);
            pro.setPrice(321d);
        }
    }

      观察者模式通常包含如下4个角色:

        ⊙ 被观察者(主题)的抽象基类:它通常会持有多个观察者对象的引用。Java提供了java.util.Observable基类来代表被观察者(主题)的抽象基类,所以实际开发中无须自己开发这个角色。

        ⊙ 观察者接口:该接口是所有观察者对象应该实现的接口,通常它只包含一个抽象方法update()。Java同样提供了java.util.Observer接口来代表观察者接口,实际开发中也无须开发该角色。

        ⊙ 被观察者实现类(主题):该类继承Observable基类。

        ⊙ 观察者实现类:实现Observer接口,实现update()抽象方法。

      实际上,完全额可以把观察者借口理解成时间监听接口,而被观察者对象(主题)也可当成事件源来处理。Java事件机制的底层实现,本身就是通过观察者模式来实现的。

      除此之外,观察者模式在Java EE应用中也有广泛的应用,主题/订阅模式下的JMS(Java Message Service,Java消息服务)本身就是观察者模式的应用。

  • 相关阅读:
    linux下聊天工具的安装
    Linux上OpenLDAP集群
    Linux下python基础调试
    曾仕强主讲:易经的奥秘(全文讲义)
    Linux单网卡多个IP(或者多个网卡多个IP)设置
    单播、广播、组播的区别和特点
    谷歌招聘 变态15题你会做几道?
    Gartner再评RSA为网络欺诈检测领导者 狼人:
    云安全 安全领域的最大热点之一 狼人:
    金山毒霸专业版高调上线 宣称杀毒速度增3倍 狼人:
  • 原文地址:https://www.cnblogs.com/ClassNotFoundException/p/6240216.html
Copyright © 2011-2022 走看看