• 2、观察者模式


    观察者模式定义:定义了对象之间一对多的依赖,这样一来,当一个对象状态发生变化时,它所有的依赖者都会收到通知并自动更新。
    个人理解:主题发生变化时,把变化情况及时通知到订阅了主题的各个观察者(订阅者)
    观察者模式设计方式让主题 与 观察者 之间实现了松耦合,能够适应变化。
     
    • 观察者模式定义了对象之间一对多的关系
    • 主题使用一个共同接口来更新观察者
    • 主题与观察者之间用松耦合方式结合
    • 主题可以被观察者模式用push或者pull数据
    • 有多个观察者时不能依赖特定的通知顺序
    • Java有多种观察者模式,例如通用的java.util.Observable
    • Swing大量使用观察者模式
    • 此模式也被使用在JavaBeans、RMI应用中。
      定义主题接口,提供主题必须实现三个方法:注册、删除、通知

    public
    interface Subject { void registerObserver(Observer observer); void removeObserver(Observer observer); void notifyObservers(); }
    实现具体的天气主题:
    实现Subject接口,实现注册、删除、通知方法;
    定义观察者集合用于观察者注册时使用;
    定义更新天气数据setMeasurements方法,该方法内默认调用measurementsChanaged方法(调用notifyObservers,循环观察者集合,调用每个观察者的update更新方法)
    public class WeatherDataSubject implements Subject{
        List<Observer> observers;
        private float temp;
        private float humidity;
        private float pressure;
    
        public WeatherDataSubject() {
            observers = new ArrayList<>();
        }
    
        public void registerObserver(Observer observer) {
            observers.add(observer);
        }
    
        public void removeObserver(Observer observer) {
            observers.remove(observer);
        }
    
        public void notifyObservers() {
            for(Observer observer:observers) {
                observer.update(temp, humidity , pressure);
            }
        }
    
        public void measurementsChanaged() {
            notifyObservers();
        }
    
        public void setMeasurements(float temp, float humidity , float pressure) {
            this.temp = temp;
            this.humidity = humidity;
            this.pressure = pressure;
            measurementsChanaged();
        }
    }
    定义观察者接口:
    每个观察者必须实现的update方法,用于被主题调用,实现通知功能
    public interface Observer {
        void update(float temp,float humidity ,float pressure);
    }
    定义观察者显示方法:
    public interface DisplayElement {
        void display();
    }
    以下三个观察者实现了Observer接口、DisplayElement 显示接口:
    在update方法中,默认调用display显示方法;
    在具体的观察者中定义了个性化的显示方式;
    public class CurrentConditionsDisplay implements Observer,DisplayElement {
        private float temp;
        private float humidity;
        private float pressure;
    
        @Override
        public void display() {
            System.out.println("CurrentConditionsDisplay:temp="+temp+";humidity="+humidity+";pressure="+pressure);
        }
    
        @Override
        public void update(float temp, float humidity, float pressure) {
            this.temp = temp;
            this.humidity = humidity;
            this.pressure = pressure;
            display();
        }
    }
    public class StatisticsDisplay implements Observer,DisplayElement {
        private float temp;
        private float humidity;
        private float pressure;
        
        @Override
        public void display() {
            System.out.println("StatisticsDisplay:temp="+temp+";humidity="+humidity+";pressure="+pressure);
        }
    
        @Override
        public void update(float temp, float humidity, float pressure) {
            this.temp = temp;
            this.humidity = humidity;
            this.pressure = pressure;
            display();
        }
    }
    public class ThirdPartyDisplay implements Observer,DisplayElement {
        private float temp;
        private float humidity;
        private float pressure;
    
        @Override
        public void display() {
            System.out.println("ThirdPartyDisplay:temp="+temp+";humidity="+humidity+";pressure="+pressure);
        }
    
        @Override
        public void update(float temp, float humidity, float pressure) {
            this.temp = temp;
            this.humidity = humidity;
            this.pressure = pressure;
            display();
        }
    }
    测试类:
    public class Test {
        public static void main(String[] args) {
            //观察者
            CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay();
            StatisticsDisplay statisticsDisplay = new StatisticsDisplay();
            ThirdPartyDisplay thirdPartyDisplay = new ThirdPartyDisplay();
            //主题
            WeatherDataSubject subject = new WeatherDataSubject();
            //把观察者注册到主题中
            subject.registerObserver(currentConditionsDisplay);
            subject.registerObserver(statisticsDisplay);
            subject.registerObserver(thirdPartyDisplay);
    
            subject.setMeasurements(1,1,1);
            subject.setMeasurements(2,3,4);
        }
    }

    输出结果:

    CurrentConditionsDisplay:temp=1.0;humidity=1.0;pressure=1.0
    StatisticsDisplay:temp=1.0;humidity=1.0;pressure=1.0
    ThirdPartyDisplay:temp=1.0;humidity=1.0;pressure=1.0


    CurrentConditionsDisplay:temp=2.0;humidity=3.0;pressure=4.0
    StatisticsDisplay:temp=2.0;humidity=3.0;pressure=4.0
    ThirdPartyDisplay:temp=2.0;humidity=3.0;pressure=4.0

    收藏文章数量从多到少与“把书读薄”是一个道理
  • 相关阅读:
    ACM/ICPC 之 一道不太简单的DP面试题(Geeksforgeeks)
    ACM/ICPC 之 简单DP-记忆化搜索与递推(POJ1088-滑雪)
    ACM/ICPC 之 递归(POJ2663-完全覆盖+POJ1057(百练2775)-旧式文件结构图)
    ACM/ICPC 之 枚举(POJ1681-画家问题+POJ1166-拨钟问题+POJ1054-讨厌的青蛙)
    JAVA手记 JAVA入门(安装+Dos下运行)
    ACM/ICPC 之 BFS(离线)+康拓展开(TSH OJ-玩具(Toy))
    ACM/ICPC 之 优先级队列+设置IO缓存区(TSH OJ-Schedule(任务调度))
    ACM/ICPC 之 BFS(离线)+康拓展开 (HDU1430-魔板)
    JAVA中的数据结构——集合类(序):枚举器、拷贝、集合类的排序
    JAVA中的数据结构——集合类(线性表:Vector、Stack、LinkedList、set接口;键值对:Hashtable、Map接口<HashMap类、TreeMap类>)
  • 原文地址:https://www.cnblogs.com/use-D/p/9748761.html
Copyright © 2020-2023  润新知