zoukankan      html  css  js  c++  java
  • 设计模式(一)观察者模式

    观察者模式 定义了对象之间的一对多的依赖,这样一来,当一个对象状态改变时,他的

    多有依赖都会受到通知并自动更新。

    本例为一个温度基站,和三个终端。温度基站为广播类WeatherData,三个终端监听者类分别为:TVDispaly,FactoryDisplay,MobileDisplay

    其中,Observable为广播类父类,含有基本的方法。

    Observer类为监听者接口,监听者需实现updata方法。

    Display为显示接口,需实现display方法。

    ObserverDemo为测试类。

    下面直接上代码,注释很清晰。基本上很容易理解。

    Observable.java

    package observer;
    /*
     * @author trojan
     * 广播类的父类
     * 
     */
    public class Observable {
        protected boolean change = false;
        
        public void setChanged() {
            change = true;
        }
        
        public void notifyObservers(Object arg) {}
        public void notifyObservers(){ notifyObservers(null);}
        public void addObserver(Observer observer){}
    }

    WeatherData.java

    package observer;
    /*
     * @author trojan
     * 该类为广播类
     */
    import java.util.ArrayList;
    
    public class WeatherData extends Observable {
        //温度
        private float temperature;
        //湿度
        private float humidity;
        //污染指数
        private float pollution_index;
        ArrayList<Observer> observers = new ArrayList<Observer>();
        
        public WeatherData(){ }
        
        //增加监听者
        public void addObserver(Observer observer){
            observers.add(observer);
        }
        
        //将更改广播给所有监听者
        public void notifyObservers(Object arg) {
            if(change){
                for(Observer observer : observers){
                    observer.update(this,arg);
                }
            }
            change = false;
        }
        
        public void notifyObservers() { notifyObservers(null);}
        
        public void stateChange() {
            //调用notifyObservers之前应调用状态改变标志函数
            setChanged();
            notifyObservers();
        }
        
        //设置状态后,将调用stateChange函数,通知监听者
        public void setState(float temperature, float humidity, float pollution_index) {
            this.temperature = temperature;
            this.humidity = humidity;
            this.pollution_index = pollution_index;
            stateChange();
        }
        
        
        public float getTemperature() {
            return temperature;
        }
        public void setTemperature(float temperature) {
            this.temperature = temperature;
        }
        public float getHumidity() {
            return humidity;
        }
        public void setHumidity(float humidity) {
            this.humidity = humidity;
        }
        public float getPollution_index() {
            return pollution_index;
        }
        public void setPollution_index(float pollution_index) {
            this.pollution_index = pollution_index;
        }
        
        
    }

    Display.java

    package observer;
    /*
     * @author
     * 显示接口
     */
    public interface Display {
        public void display();
    }

    Observer.java

    package observer;
    /*
     * @author trojan
     * 这是一个监听者的接口,需要实现updata方法
     * 该方法可以被广播者调用,向监听者广播数据,或者说是一种推的方式
     * 监听者可以可以调用该方法主动更新数据,就像是一种拉的方式
     * 当然,对于每一个实现的监听者可能会有不同的数据需求
     * 所以,他们可以实现对自己感兴趣的那部分数据更新
     * 
     */
    public interface Observer {
        public void update(Object obj,Object arg);;
    }

    TVDisplay.java

    package observer;
    /*
     * @author trojan
     * 对于电视台来说可能需要的气象数据要比其他的设备多
     * 所以updata需要更新更多的数据
     */
    public class TVDisplay implements Observer, Display{
        Observable observable;
        private float temperature;
        private float humidity;
        private float pollution_index; 
        
        //变成一个监听者
        public void becomeOberser(Observable observable) {
            this.observable = observable;
            observable.addObserver(this);;
        }
    
        @Override
        public void update(Object obj, Object arg) {
            if(obj instanceof WeatherData){
                WeatherData weatherData = (WeatherData)obj;
                this.temperature = weatherData.getTemperature();
                this.humidity = weatherData.getHumidity();
                this.pollution_index = weatherData.getPollution_index();
            }
            
        }
        
        @Override
        public void display() {
            System.out.println("WeatherData:
    "
                    + "temperature: "+temperature +"
    "
                    +"humidity"+humidity+"
    "
                    +"pollution_index:"+pollution_index);
                
        }
    
    
    }

    FactoryDisplay.java

    package observer;
    /*
     * @author torjan
     * 工厂显示平台所需要的广播数据
     * 
     */
    public class FactoryDisplay implements Observer, Display{
    
        Observable observable;
        private float temperature;
        private float pollution_index; 
        
        //变成一个监听者
        public void becomeOberser(Observable observable) {
            this.observable = observable;
            observable.addObserver(this);;
        }
    
        @Override
        public void update(Object obj, Object arg) {
            if(obj instanceof WeatherData){
                WeatherData weatherData = (WeatherData)obj;
                this.temperature = weatherData.getTemperature();
                this.pollution_index = weatherData.getPollution_index();
            }
            
        }
    
        @Override
        public void display() {
            System.out.println("WeatherData:
    "
                    + "temperature: "+temperature +"
    "
                    +"pollution_index"+pollution_index);
            
            
        }
    
    }

    MobileDisplay.java

    package observer;
    /*
     * @author
     * 手机平台所需要的广播数据
     * 
     */
    public class MobileDisplay implements Observer, Display {
    
        Observable observable;
        private float temperature;
        private float humidity;
        
        //变成一个监听者
        public void becomeOberser(Observable observable) {
            this.observable = observable;
            observable.addObserver(this);;
        }
    
        @Override
        public void update(Object obj, Object arg) {
            if(obj instanceof WeatherData){
                WeatherData weatherData = (WeatherData)obj;
                this.temperature = weatherData.getTemperature();
                this.humidity = weatherData.getHumidity();
            }
            
        }
        
        @Override
        public void display() {
            System.out.println("WeatherData:
    "
                    + "temperature: "+temperature +"
    "
                    +"humidity"+humidity);
                
        }
    
    
    }

    测试类:

    ObserverDemo.java

    package observer;
    
    public class ObserverDemo {
        public static void main(String[] args) {
            WeatherData weatherData = new WeatherData();
            FactoryDisplay factoryDisplay = new FactoryDisplay();
            MobileDisplay mobileDisplay = new MobileDisplay();
            TVDisplay tvDisplay = new TVDisplay();
            
            weatherData.addObserver(factoryDisplay);
            weatherData.addObserver(mobileDisplay);;
            tvDisplay.becomeOberser(weatherData);
            
            weatherData.setState(23, 70, 120);
            
            factoryDisplay.display();
            mobileDisplay.display();
            tvDisplay.display();
        }
    }

    测试结果:

    WeatherData:
    temperature: 23.0
    pollution_index120.0
    WeatherData:
    temperature: 23.0
    humidity70.0
    WeatherData:
    temperature: 23.0
    humidity70.0
    pollution_index:120.0

    总结:

    设计原则:找出程序中会变化的方面,然后根据其和固定不变的方面相分离

    在观察者模式中,会改变的是主题的状态,以及观察者的数目和种类。用这个模式,可以改变依赖于主题状态的对象,却不必改变主题。

    设计原则:针对接口编程,不针对实现编程

    设计原则:多用组合,少用继承

  • 相关阅读:
    HDU 4278 Faulty Odometer 8进制转10进制
    hdu 4740 The Donkey of Gui Zhou bfs
    hdu 4739 Zhuge Liang's Mines 随机化
    hdu 4738 Caocao's Bridges tarjan
    Codeforces Gym 100187M M. Heaviside Function two pointer
    codeforces Gym 100187L L. Ministry of Truth 水题
    Codeforces Gym 100187K K. Perpetuum Mobile 构造
    codeforces Gym 100187J J. Deck Shuffling dfs
    codeforces Gym 100187H H. Mysterious Photos 水题
    windows服务名称不是单个单词的如何启动?
  • 原文地址:https://www.cnblogs.com/justenjoy/p/7021778.html
Copyright © 2011-2022 走看看