zoukankan      html  css  js  c++  java
  • 【设计模式】观察者模式

    参考的优秀文章:

    设计模式之—观察者模式

    《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的观察者列表拷贝到另外的数组中,然后才遍历该数组。
  • 相关阅读:
    Linux指令集
    [日记]贝鲁特煎熬第32天
    2019南京区域赛ABCHJK题解 & KMbfs(O(n^3))板子
    欧拉筛质数以及四大积性数论函数(欧拉函数、莫比乌斯函数、约数个数函数、约数和函数)
    简短的自我介绍
    BSTTreap名次树数组&指针实现板子 Ver1.0
    2019银川区域赛BDFGHIKN题解
    安装vs2010
    SPEmailEventReceiver 之导入附件EXCEL
    为incoming mail绑定事件,SPEmailEventReceiver
  • 原文地址:https://www.cnblogs.com/nick-huang/p/5054757.html
Copyright © 2011-2022 走看看