• 观察者模式


    观察者模式

          定义了对象之间的一对多的关系,当一个对象状态改变,它的所有依赖的对象都会收到通知并且相应改变。

    定义观察者模式的类图:

                      由主题和一个或多个观察者构成

        

    可以看到,主题(subject)应该具有的方法有:

                addObserver()              //为主题添加观察者             deleteObserver()    //删除观察者             notifyObserver()     //通知观察者数据变化

        观察者(Observer)应该具有的方法:

                  update()      //接收更新,并作出响应

    以最常见的订报服务为例:

      1.报社的业务就是出版报纸

      2.向某家报社订阅报纸,只要他们有新的报纸出版,就会发送到客户,客户也就会收到新报纸。

      3.当客户不想再看报纸的时候,取消订阅,报社就不会送新报纸来。

      4.只要报社还在运营,就一定会提供订阅和取消订阅服务。

    下面用一个简单的例子模拟:

      先列出核心类图:

        此实例定义了3个用户(Observer),并为用户提供了订报服务。通过用户注册报社(Subject)的订报服务,报社推送订报和用户取消订报服务来学习观察者模式的使用方法。

          

    核心代码:

      Subject接口:

    public interface Subject {
        public void deleteObserver(Observer obj);
    
        public void notifyObservers();
    
        void addObserver(Observer obj);
    
    }

    NewSbuject类:

    public class NewsSubject implements Subject {
        private ArrayList<Observer> objs;
        private String chinese, english, math;
        
        
        public NewsSubject(){
            objs=new ArrayList<Observer>();
        }
        
        @Override
        public void addObserver(Observer obj) {
            // TODO Auto-generated method stub
            objs.add(obj);
            
        }
    
        @Override
        public void deleteObserver(Observer obj) {
            // TODO Auto-generated method stub
            objs.remove(obj);
    
        }
    
        @Override
        public void notifyObservers() {
            // TODO Auto-generated method stub
            System.out.println("报社有新内容更新了,发送更新");
            for(Observer temp:objs)
                    temp.update( chinese, english, math);
    
        }
        //动态设置报纸内容
        public void setData(String chinese,String english,String math){
            this.chinese=chinese;
            this.english=english;
            this.math=math;
            notifyObservers();
            
        }
    
    }

    Observe接口:

    public interface Observer {
            public void update(String chinese,String english,String math);
    //这里添加了cancle()方法,用来模拟客户取消订报服务
            public void cancle();
    }

    ChineseObserver类:

      

     

    public class ChineseObserver implements Observer, Preform {
        private String content;
        private Subject sub;
    
        public ChineseObserver(NewsSubject sub) {
            // 为观察者注册
            this.sub = sub;
            sub.addObserver(this);
    
        }
    
        @Override
        public void update(String chinese, String english, String math) {
            // TODO Auto-generated method stub
            content = chinese;
            display();
    
        }
    
        @Override
        public void display() {
            // TODO Auto-generated method stub
            System.out.println("B订的是语文报,新一期报纸的内容:" + content);
        }
    
        @Override
        public void cancle() {
            // TODO Auto-generated method stub
            sub.deleteObserver(this);
            System.out.println("B取消订报");
        }
    
    }

    其他的MathObserver,EnglishObserver与之类似。

    主程序:

    public class Main {
        static NewsSubject sub;
        static EnglishObserver eng;
        static ChineseObserver chi;
        static MathObserver mat;
        public static void main(String[] arg) {
            sub=new NewsSubject();
            eng=new EnglishObserver(sub);
            chi=new ChineseObserver(sub);
            mat=new MathObserver(sub);
            sub.setData("今天星期日", "stay hungry ,stay foolish!", "1+2=3");
            
            new  Thread(){
                public void run() {
                    try {
                        sleep(4000);
                        System.out.println("一天过去了。");
                        mat.cancle();
                        sleep(4000);
                        System.out.println("一天过去了。");
                        sub.setData("今天要上学了!", "keep moving!", "10+10=20");
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    
                };
            }.start();
            
        }
    
    }

    运行可以看到结果:

    报社有新内容更新了,发送更新
    A订的是英语报,新一期报纸的内容:stay hungry ,stay foolish!
    B订的是语文报,新一期报纸的内容:今天星期日
    C订的是数学报报,新一期报纸的内容:1+2=3
    一天过去了。
    C取消订报
    一天过去了。
    报社有新内容更新了,发送更新
    A订的是英语报,新一期报纸的内容:keep moving!
    B订的是语文报,新一期报纸的内容:今天要上学了!

      通过这样就可以看到观察者模式的使用方法和运行形式,另外这个例子中只是实现报社主动推送报纸服务,可另外扩展为用户主动请求更新,这里不做实现,读者另行实现。同时Java有内置的观察者模式,通过java.util包内的Observer接口和Observable类来实现。不过只要你掌握的观察者模式,哪一种方法来实现也是易如反掌的。

  • 相关阅读:
    区间dp体会
    P1083借教室 noip提高组复赛2012
    P2678跳石头体会 noip2015提高组
    tarjan求LCA的体会
    P1006 传纸条
    P1140 相似基因 详解
    UVA1025 城市里的间谍 A Spy in the Metro 题解
    DAG上的动规嵌套矩形问题(含思考题)
    洛谷P1030c++递归求解先序排列
    Test 2019.7.22
  • 原文地址:https://www.cnblogs.com/hellocsl/p/3727972.html
Copyright © 2020-2023  润新知