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

    今天回家做饭,时间就很紧张了,待会儿还要去洗澡,我有一个想法,就是买一个耳麦,这样在公司也能旁若无人的看书了,戴个耳机总是感觉不到那种隔离。

    1.1 定义

    观察者模式

    在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖他的对象都会受到通知,并且自动更新。

    OO原则

    为交互对象之间的松耦合设计而努力。

    ps

    大量的GUI框架都使用了这个设计模式。

    2.1 需求

    1. 有一个WeatherData对象,是一个气象站提供的气象数据对象。里面包括温度属性,压力属性等等
    2. 需要对外展示几种不同的布告板,包括温度类的,压力类的等等。
    3. WeatherData更新后,需要及时更新布告,同时,布告版可以随时增加和取消,也可能在现有基础上添加新的布告板。

    2.2 分析

    1.这个模式所体现出的设计原则就是为了交互对象的松耦合而努力,最主要耦合的地方,就是WeatherData和观察者Obererve之间的耦合。
    2.解决办法就是用接口,就是面向抽象编程而不是面对实现编程,把Subject主题和Observer都抽象为接口,使用通用的方法来进行注册,更新等等一致的行为。
    3.这也是动态类型的一种思想吧,像什么比是什么好用

    3.1实现

    首先是接口的构造:

      public interface IObserver
        {
            //主题为变量是方便观察者知道是哪个主题更新的他
            void update(ISubject sub, string temp, string pressure);
        }
        public interface IDisplayElement
        {
            void display();
        }
        public interface ISubject
        {
            void registerObserver(IObserver observer);
            void removeObserver(IObserver observer);
            void notifyObserver();
        }
    

    显示功能和观察监视是两个功能,虽然在这个具体的业务场景里面他们是一同出现的,但是还是要用两个接口分别表示,不然无法复用,而且强耦合了。

    然后就是Observer的具体类的实现:

     public class Temperature : IObserver, IDisplayElement
        {
            private string temp;
            private string pressure;
            private WeatherData weatherData;
            public Temperature(WeatherData w)
            {
                weatherData = w;
                weatherData.registerObserver(this);
            }
            public void display()
            {
                Console.WriteLine(" i am temperatureObserver,now temp is {0} and pressure is {1}", temp, pressure);
            }
    
            public void update(ISubject sub, string temp, string pressure)
            {
                this.temp = temp;
                this.pressure = pressure;
                display();
            }
        }
    

    这里就放了一个,其他的结构基本一致。
    然后就是最复杂的WeatherData,Subject的具体实现

       public class WeatherData : ISubject
        {
            private bool ischanged = false;
            private List<IObserver> ObserverList;
            private string temp;
            private string pressure;
            public WeatherData()
            {
                ObserverList = new List<IObserver>();
            }
            public void setMeasurement(string temp, string pressure)
            {
                this.temp = temp;
                this.pressure = pressure;
                this.changed();
            }
            private void setChanged()
            {
                ischanged = true;
            }
            public string getTemperature()
            {
                Random r = new Random();
                return r.Next(0, 100) + "℃";
            }
            public string getPressure()
            {
                Random r = new Random();
                return r.Next(0, 100) + "p";
            }
            public void changed()
            {
                setChanged();
                notifyObserver();
            }
            public void notifyObserver()
            {
                if (ischanged == true)
                {
                    foreach (var item in ObserverList)
                    {
                        item.update(this, this.temp, this.pressure);
                    }
                }
                ischanged = false;
            }
    
            public void registerObserver(IObserver observer)
            {
                if (ObserverList.IndexOf(observer) < 0)
                {
                    ObserverList.Add(observer);
                }
                else
                {
                    Console.WriteLine("不可以重复注册");
                }
            }
    
            public void removeObserver(IObserver observer)
            {
                if (ObserverList.IndexOf(observer) >= 0)
                {
                    ObserverList.Remove(observer);
                }
            }
        }
    

    其中ischanged 属性是后加上去的,为了框架可以更加灵活,比如WeatherData更新非常频繁,而布告板不需要如此频繁和精度的更新,我们就可以在ischanged 属性上做文章,把不需要更新情况过滤掉就可以了。

    在Java的内置支持的观察者模式中,数据的更新其实有两种,一种是push推,一种是pull拉,就是Oberver对象自己去按需get数据,而不是被动的等待推送,这也是一个思路。

  • 相关阅读:
    Log4J日志配置详解
    Linux:ssh端口转发详解
    Android数据存储五种方式总结
    Nginx学习记录
    简单通用JDBC辅助类封装
    PBR.理论
    PBR.工作流贴图
    不设置readable,读取图片数据
    直接打开指定的目录
    Compute Shader基础
  • 原文地址:https://www.cnblogs.com/codersun/p/6965088.html
Copyright © 2011-2022 走看看