【设计模式】观察者模式

参考的优秀文章:

设计模式之—观察者模式

《JAVA与模式》之观察者模式

假设,Pay是指收入,Tax是指个人所得税,SocialSecurity是社保,而后两者是以Pay为基数计算所得的。

所以,Tax、SocialSecurity依赖于Pay,Pay一旦变动,其他两者也随之变动。

> 没使用观察者模式

没有使用观察者模式的代码,可以这么写:

package No002没有观察者模式的时候;

public class Pay {

    private Integer userId;
    private Integer pay;

    public Pay(Integer userId, Integer pay) {
        super();
        this.userId = userId;
        this.pay = pay;
    }
    
    public void update(Integer pay) {
        this.pay = pay;
        System.out.println("Update the user " + this.userId + "'s pay to " + this.pay);
    }

    public Integer getUserId() {
        return userId;
    }

    public Integer getPay() {
        return pay;
    }
    
}
View Code
package No002没有观察者模式的时候;

public class Tax {
    
    public void update(Pay pay) {
        System.out.println("Update the user " + pay.getUserId() + "'s tax to " + pay.getPay());
    }

}
View Code
package No002没有观察者模式的时候;

import No002没有观察者模式的时候.Pay;

public class SocialSecurity {

    public void update(Pay pay) {
        System.out.println("Update the user " + pay.getUserId() + "'s social securoty to " + pay.getPay());
    }

}
View Code
package No002没有观察者模式的时候;

public class PayService {
    
    public void payChange(Pay pay) {
        Tax tax = new Tax();
        SocialSecurity ss = new SocialSecurity();
        
        pay.update(pay.getPay());
        tax.update(pay);
        ss.update(pay);
    }

}
View Code
package No002没有观察者模式的时候;

public class Client {

    public static void main(String[] args) {
        Pay pay = new Pay(001, 12000);
        PayService ps = new PayService();
        ps.payChange(pay);
    }

}
View Code

> 基于java api提供的基类实现观察者模式

而使用观察者模式,代码可以这么写。(这里并没有从零开始写观察者模式,而是使用java.util下观察者模式的基础包)

java.util.Observer是观察者的接口,java.util.Observable是被观察者(发生变动的根源)的父类。

package No002使用Java的观察者类;

public class Pay {

    private Integer userId;
    private Integer pay;

    public Pay(Integer userId, Integer pay) {
        super();
        this.userId = userId;
        this.pay = pay;
    }
    
    public void update(Integer pay) {
        this.pay = pay;
        System.out.println("Update the user " + this.userId + "'s pay to " + this.pay);
    }

    public Integer getUserId() {
        return userId;
    }

    public Integer getPay() {
        return pay;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("Pay [userId=").append(userId).append(", pay=")
                .append(pay).append("]");
        return builder.toString();
    }
    
}
View Code
package No002使用Java的观察者类.observer;

import java.util.Observable;
import java.util.Observer;

import No002使用Java的观察者类.Pay;

public class Tax implements Observer {

    public void update(Observable o, Object obj) {
        if (obj == null || !(obj instanceof Pay)) {
            return;
        }
        
        Pay pay = (Pay)obj;

        System.out.println("Update the user " + pay.getUserId() + "'s tax to " + pay.getPay());
    }

}
View Code
package No002使用Java的观察者类.observer;

import java.util.Observable;
import java.util.Observer;

import No002没有观察者模式的时候.Pay;

public class SocialSecurity implements Observer {

    public void update(Observable o, Object obj) {
        if (obj == null || !(obj instanceof Pay)) {
            return;
        }
        
        Pay pay = (Pay)obj;

        System.out.println("Update the user " + pay.getUserId() + "'s social securoty to " + pay.getPay());
    }

}
View Code
package No002使用Java的观察者类;

import java.util.Observable;

public class PayService extends Observable {
    
    public void payChange(Pay pay) {
        pay.update(pay.getPay());
        this.setChanged();
        
        this.notifyObservers(pay);
    }

}
View Code
package No002使用Java的观察者类;

import No002使用Java的观察者类.observer.SocialSecurity;
import No002使用Java的观察者类.observer.Tax;

public class Client {

    public static void main(String[] args) {
        PayService p = new PayService();
        
        p.addObserver(new Tax());
        p.addObserver(new SocialSecurity());
        System.out.println("countObservers -> " + p.countObservers());
        
        Pay pay = new Pay(001, 12000);
        p.payChange(pay);
    }

}
View Code

代码上传至github,见【观察者模式】,内容或者有改动。

JDK中Observer和Observable的实现

Observer接口很简单,纯粹声明了一个update(Observable o, Object arg)的方法。

Observable类有几个实现点:

  • boolean changed属性表示是否有改变,如果有改变可以调用setChanged()设置changed属性为true
  • 观察者则由Vector<Observer> obs装载
  • notifyObservers(Object arg)方法,则遍历obs的观察者,并调用各观察者的update(Observable o, Object arg)方法。往更细致地看,可以看到有个同步块,将obs的观察者列表拷贝到另外的数组中,然后才遍历该数组。
原文地址:https://www.cnblogs.com/nick-huang/p/5054757.html