• 设计模式学习


    观察者模式:

        定义了对象之间的一对多依赖,这样一来,当一个对象改变的时候,它的所有依赖者就会自动更新。
        // 而这个对象 就称之为 主题,这些依赖者就称之为 观察者

     

    该模式的组成部分:

    •   主题    部分: 主题 的协议, 各个负责 具体实现 的主题;
    •   观察者 部分: 观察者协议,  各个观察者的具体实现类;

    OO原则:

    1.   封装变化
    2.   多用组合,少用继承
    3.   针对接口编程,不针对实现编程
    4.   为交互对象之间的松耦合而设计 

    UML 类图:

    代码具体实现:

    1、主题部分:

    // 主题 协议
    protocol WeatherDataSubject {
        //  提供 接口 给 观察者,以便他们 进行订阅、退订 和 获取数据
        func registerObserver(observer: WeatherDataObserverInterface)
        func removeObserver(observer: WeatherDataObserverInterface)
        
        
        // 获取数据, 将各个数据分开,以便不同的 观察者 获取自己所需要的不同数据
        func gainTemperature() -> Float
        func gainHumidity() -> Float
        func gainPressure() -> Float
    }
    
    // 一个 具体实现 的主题
    class WeatherData: NSObject, WeatherDataSubject {
        var observers: NSMutableArray = NSMutableArray()
        private var temperature: Float = 0.0
        private var humidity: Float = 0.0
        private var pressure: Float = 0.0
        
        // 用来表示 主题进行了数据更新
        var changeState: Bool = true
        
        // 观察者 注册/订阅
        func registerObserver(observer: WeatherDataObserverInterface) {
            observers.addObject(observer as! AnyObject)
        }
        
        // 观察者 退订
        func removeObserver(observer: WeatherDataObserverInterface) {
            observers.removeObject(observer as! AnyObject)
        }
        
        // 当主题进行了数据更新, 就将 更新消息 发送给各订阅者(通过 调用观察者协议的 获取更新数据 方法)
        func notificationObservers() {
            if changeState {
                for observer in observers {
                    (observer as! WeatherDataObserverInterface).updateWeather()
                }
                
                changeState = false
            }
        }
        
        // 提供数据接口 给观察者
        func gainHumidity() -> Float {
            return self.humidity
        }
        
        func gainPressure() -> Float {
            return self.pressure
        }
        
        func gainTemperature() -> Float {
            return self.temperature
        }
        
        // 各个主题 自带的更新数据 方法
        func changeWeatherData(t: Float, h: Float, p: Float) {
            self.temperature = t
            self.pressure = p
            self.humidity = h
    
            changeState = true
            self.notificationObservers()
        }
    }

    2、 观察者部分:

    // 观察者协议类
    protocol WeatherDataObserverInterface {
        // 本协议比较简单, 只有一个获取 主题更新消息 的方法/接口 和 退订接口
        func updateWeather()
        func removeSubject()
    }
    
    // 一个具体的观察者类
    class CurrentConditionsDisplay:NSObject, WeatherDataObserverInterface {
        private var temperature: Float = 0.0
        private var humidity: Float = 0.0
        // 一个 主题协议对象
        var weatherDataSubject: WeatherDataSubject?
        
        // 在生成 观察者对象的时候,需要传入一个主题,以便该观察者在生成的时候就去注册该主题
        init(weatherData: WeatherData) {
            super.init()
            weatherDataSubject = weatherData
            weatherDataSubject?.registerObserver(self)  // 注册
        }
        
        // 接受 主题更新 的消息,接受到后,就去 所注册的主题处获取所需的数据
        func updateWeather() {
            self.temperature = weatherDataSubject!.gainTemperature()
            self.humidity = weatherDataSubject!.gainHumidity()
            self.display()
        }
        
        // 展示数据
        func display() {
            println("I'm Current Conditions Panel Display")
            println("current temperature is (self.temperature). And humidity is (self.humidity)")
            println()
        }
        
        // 实现 退订
        func removeSubject() {
            weatherDataSubject?.removeObserver(self)
        }
        
    }

    3、具体实现(测试):

    // 生成一个具体 的主题
    var weatherData = WeatherData()
    
    // 生成一个具体 的观察者
    var curentConditon: CurrentConditionsDisplay = CurrentConditionsDisplay(weatherData: weatherData)
    
    // 主题 更新数据
    weatherData.changeWeatherData(1, h: 1, p: 1)
    
    // 观察者退订主题
    curentConditon.removeSubject()
    
    // 主题 再次更新数据
    weatherData.changeWeatherData(2, h: 2, p: 2)

    4、测试结果:

      只输出了一次结果,即:主题第一个更新的结果,因为主题进行第二次更新的时候,观察者已经退订了,所以不能接受到主题更新后的数据,也就不能输出。

    I'm Current Conditions Panel Display
    current temperature is 1.0. And humidity is 1.0
  • 相关阅读:
    strcpy ,strncpy ,strlcpy(转载)
    窗口刷新时的问题(转)
    Linux下的实时流媒体编程(RTP,RTCP,RTSP)
    YUV色彩空间(转自百度百科)
    VC++2005快速构建安全的应用程序
    Linux多线程编程
    C++ PASCAL关键字(转)
    SkinMagic 进行皮肤设置
    .h和.cpp文件的区别
    strcpy_s与strcpy安全性的比较(转载)
  • 原文地址:https://www.cnblogs.com/ziyeSky/p/4432096.html
Copyright © 2020-2023  润新知