Java内部实现的观察者模式小记

假如Admin要观察User的工资变化,当User的工资增加或者减少时,都会引起Admin输出相应的信息。

定义观察者接口:MyObserver.java

package cn.liuning.watch;


public interface MyObserver {
    void update(MyObservable o, Object arg);
}
View Code

定义被观察者父类(Admin类需要继承这个类):MyObservable.java

package cn.liuning.watch;

import java.util.Observer;
import java.util.Vector;

/**
 * 观察者模式,Java源码
 * @author liuning
 *
 */
public class MyObservable {
    /**
     * 标记是否被观察这改变
     */
    private boolean changed = false;
    
    /**
     * 保存所有的观察者
     */
    private Vector<MyObserver> all;
    
    /**
     * 观察者构造函数
     */
    public MyObservable(){
        all = new Vector<MyObserver>();
    }
    
    /**
     * 增加一个观察者
     * @param o
     */
    public synchronized void addObserver(MyObserver o){
        if(o == null){
            throw new NullPointerException();
        }
        if(!all.contains(o)){
            all.addElement(o);
        }
    }
    
    /**
     * 删除一个观察者
     * @param o
     */
    public synchronized void deleteObserver(Observer o) {
            all.removeElement(o);
    }
    
    /**
     * 被观察这通知观察者做出相应的变化
     */
    public void notifyObservers() {
        notifyObservers(null);
    }
    
    /**
     * 被观察这通知观察者做出相应的变化
     */
    public void notifyObservers(Object arg) {
       
        Object[] arrLocal;
        synchronized (this) {
            if (!changed){
                return ;
            }
            arrLocal = all.toArray();
            clearChanged();
        }
        for (int i = arrLocal.length-1; i>=0; i--){
            ((MyObserver)arrLocal[i]).update(this, arg);
        }
     }
    
    /**
     * 删除所有观察者
     */
     public synchronized void deleteObservers() {
            all.removeAllElements();
     }
     
     /**
      * 设置被观察这发生变化
      */
     protected synchronized void setChanged() {
            changed = true;
     }
     
     /**
      * 清除变化
      */
     protected synchronized void clearChanged() {
            changed = false;
     }
     
     /**
      * 判断是否有变化
      * @return boolean
      */
     public synchronized boolean hasChanged() {
            return changed;
     }
     
     /**
      * 计数,获取观察者个数
      * @return
      */
     public synchronized int countObservers() {
            return all.size();
     }
    
}
View Code

定义观察者(需要实现MyObservable接口):Admin.java

package cn.liuning.watch;

public class Admin implements MyObserver{

    @Override
    public void update(MyObservable o, Object arg) {
        
        User user = (User) o;
        
        System.out.println(arg+"钱改变了");
        
        System.out.println(user.toString());
    }
    
}
View Code

定义被观察者(需要继承MyObserver):User.java

package cn.liuning.watch;

public class User extends MyObservable{
    private int price = 0;
    private String name = "张三";
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getPrice() {
        return price;
    }
    
    
    @Override
    public String toString() {
        return "User [price=" + price + ", name=" + name + "]";
    }
    public void setPrice(int price) {
        
        this.price = price;
        
        //设置工资发生变化
        this.setChanged();

        //通知观察者执行,内部就是调用所有观察者的update方法,通过接口实现。
        this.notifyObservers(this.name);//可午餐也可有参
    }
    
}
View Code

测试Main方法:Test.java

package cn.liuning.watch;

public class Test {
    public static void main(String[] args) {
        
        //被观察者初始化
        User user = new User();
        
        //增加一个观察者
        user.addObserver(new Admin());
        
        user.setName("李四");
        //当价格改变时就会观察者就会执行update方法。
        user.setPrice(100);
        
    }
}
View Code
原文地址:https://www.cnblogs.com/liun1994/p/4227176.html