zoukankan      html  css  js  c++  java
  • 模式的秘密-观察者模式(一)

    学习观察者模式通用代码:

    1,目标对象的定义

    2,具体的目标对象定义。

    3,再来看看观察者的接口定义

    4,看看观察者的具体实现。

     先来一个通用的观察者模式实例:

    1:定义一个目标对象:包含观察者的添加,删除,以及最重要的通知观察者方法(观察者对象调用自己的方法,方法参数是目标对象)

    package com.ObserverPatternCommon;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /*
     * 目标对象,他知道观察它的观察者,并提高注册(添加)和删除观察者的接口
     * */
    public class Subject {
        //保存注册的观察者对象
        private List<Observer> observers=new ArrayList<Observer>();
        
        //attach  detach  notifyObserver
        //添加观察者到集合中
        public void attach(Observer observer)
        {
            observers.add(observer);
        }
        //删除集合中的指定观察者
        public void detach(Observer observer)
        {
            observers.remove(observer);
        }
        
        //通知所有注册的观察者对象
        protected void notifyObservers()
        {
            for(Observer observer:observers)
            {
                observer.update(this);
            }
        }
    
    }

    2,建立一个具体的目标对象:继承目标对象,并且加上具体目标对象所需的方法:一个目标对象状态的设置和获取,在设置状态的时候,通知观察者。

    package com.ObserverPatternCommon;
    
    /*
     * 具体的目标对象,负责把有关状态存入到相应的观察者对象中
     * */
    public class ConcreteSubject extends Subject {
    
        //保存目标对象的状态
        private String subjectState;
    
        public String getSubjectState() {
            return subjectState;
        }
    
        public void setSubjectState(String subjectState) {
            this.subjectState = subjectState;
            this.notifyObservers();//状态发生改变了,就通知所有的观察者
        }
    }

    3,建立观察者接口:

    package com.ObserverPatternCommon;
    
    /*
     * 这是一个观察者接口,定义一个更新的接口给哪些在目标发生改变的时候被通知的对象
     * */
    public interface Observer {
    
        //更新的接口,subject表示传入目标对象,方便获取相应的目标对象状态
        public void update(Subject subject);
        
    }

    4,建立具体的观察者接口:因为观察者被目标对象通知的时候,需要观察者调用自己的方法,这里的update。

    package com.ObserverPatternCommon;
    
    /*
     * 具体的观察者对象,实现更新的方法,使自身和目标的状态保持一致
     * */
    public class ConcreteObserver implements Observer {
    
        //观察者的状态
        private String observerState;
        
        /*
         * 获取目标类的状态,同步到观察者的状态中
         * */
        @Override
        public void update(Subject subject) {
            observerState=((ConcreteSubject)subject).getSubjectState();
        }
    
    }

    上面就是观察者模式通用的结构。

    下面以一个具体例子来说:当天气变化的时候,需要通知所有注册的观察者用户(如这里的女朋友和老妈)。

    第一步:建立天气目标对象类:包括用户注册方法,用户注销方法,用户通知方法

    package WeatherObserverPattern;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /*
     * 目标对象,他知道观察它的观察者,并提高注册(添加)和删除观察者的接口
     * */
    public class WeatherSubject {
        //保存注册的观察者对象
        private List<Observer> observers=new ArrayList<Observer>();
        
        //attach  detach  notifyObserver
        //把订阅天气的人添加到订阅者列表中
        public void attach(Observer observer)
        {
            observers.add(observer);
        }
        //删除集合中的指定订阅天气的人
        public void detach(Observer observer)
        {
            observers.remove(observer);
        }
        
        //通知所有已经订阅天气的人
        protected void notifyObservers()
        {
            for(Observer observer:observers)
            {
                observer.update(this);
            }
        }
    
    }

    第二步:建立具体的天气目标对象类:包含天气信息方法,当改变天气信息的时候,调用通知用户方法。

    package WeatherObserverPattern;
    
    /*
     * 具体的目标对象,负责把有关状态存入到相应的观察者对象中
     * */
    public class ConcreteWeatherSubject extends WeatherSubject {
    
        //获取天气的内容信息
        private String weatherContent;
        
        public String getWeatherContent() {
            return weatherContent;
        }
    
        public void setWeatherContent(String weatherContent) {
            this.weatherContent = weatherContent;
            //内容有了,说明天气更新了,通知所有的订阅的人
            this.notifyObservers();
        }
    }

    第三步:定义用户观察者接口:包含一个更新接口

    package WeatherObserverPattern;
    
    /*
     * 这是一个观察者接口,定义一个更新的接口给那些在目标发生改变的时候被通知的对象
     * */
    public interface Observer {
    
        //更新的接口,subject表示传入目标对象,方便获取相应的目标对象状态
        public void update(WeatherSubject subject);
        
    }

    第四步:定义用户观察者具体类:包含变量:用户名字,不同用户的提醒信息,以及用来接收天气信息的变量。当天气类通知用户,用户会调用update方法,并且传入

    天气类对象,通过天气类对象获取天气信息。

    package WeatherObserverPattern;
    
    /*
     * 具体的观察者对象,实现更新的方法,使自身和目标的状态保持一致
     * */
    public class ConcreteObserver implements Observer {
        
        //观察者的名字,是谁收到了这个讯息,黄明的女朋友海事他老妈
        private String observerName;
        //天气的内容情况,这个消息从目标处获取
        private String weatherContent;
        //提醒的内容,黄明的女朋友提醒约会,而他老妈则提醒购物
        private  String remindThing;
        
        public String getObserverName() {
            return observerName;
        }
        public void setObserverName(String observerName) {
            this.observerName = observerName;
        }
        public String getWeatherContent() {
            return weatherContent;
        }
        public void setWeatherContent(String weatherContent) {
            this.weatherContent = weatherContent;
        }
        public String getRemindThing() {
            return remindThing;
        }
        public void setRemindThing(String remindThing) {
            this.remindThing = remindThing;
        }    
        /*
         * 获取目标类的状态,同步到观察者的状态中
         * */
        @Override
        public void update(WeatherSubject subject) {
            weatherContent=((ConcreteWeatherSubject)subject).getWeatherContent();
            System.out.println(observerName+"收到了:"+weatherContent+","+remindThing);
        }
    
    }

    最后:实现该天气信息通知用户的调用。

    package WeatherObserverPattern;
    
    public class Client {
    
        public static void main(String[] args) {
    
            //1,创建目标
            ConcreteWeatherSubject weather=new ConcreteWeatherSubject();
            //2,创建观察者
            ConcreteObserver observerGirl=new ConcreteObserver();
            observerGirl.setObserverName("黄明的女朋友");
            observerGirl.setRemindThing("是我们的第一次约会,地点街心公园");
            
            ConcreteObserver observerMum=new ConcreteObserver();
            observerMum.setObserverName("老妈");
            observerMum.setRemindThing("是一个购物的好日子,明天去天虹扫货");
            
            //3,注册观察者
            weather.attach(observerGirl);
            weather.attach(observerMum);
            //4,目标发布天气
            weather.setWeatherContent("明天 天气晴朗,蓝天白云,气温28度");
        }
    
    }

    执行结果:

    黄明的女朋友收到了:明天 天气晴朗,蓝天白云,气温28度,是我们的第一次约会,地点街心公园
    老妈收到了:明天 天气晴朗,蓝天白云,气温28度,是一个购物的好日子,明天去天虹扫货
  • 相关阅读:
    根据用户输入的工资计算所得税
    ATM取款机数据库设计
    ExecuteNonQuery()
    ExecuteReader()获得数据
    ExecuteScalar ()
    面试题汇总(三)
    面试题汇总(一)
    2019-8最新面试题汇总
    linux下vim 选择文本,删除,复制,粘贴
    TCP和UDP的优缺点及区别
  • 原文地址:https://www.cnblogs.com/alsf/p/8939647.html
Copyright © 2011-2022 走看看