Swift设计模式: 观察者模式(发布-订阅模式)

定义

观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。

观察者模式结构图
在这里插入图片描述
在观察者模式中有如下角色:

  • Observer:抽象观察者,是观察者者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。
  • ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。
  • Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。
  • ConcreteSubject:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。

2.观察者模式简单实现

观察者模式这种发布-订阅的形式我们可以拿微信公众号来举例,假设微信用户就是观察者,微信公众号是被观察者,有多个的微信用户关注了程序猿这个公众号,当这个公众号更新时就会通知这些订阅的微信用户。好了我们来看看用代码如何实现:

2.1 抽象观察者(Observer)

里面定义了一个更新的方法:

protocol Observer {
    var id : Int { get } // property to get an id
    func update<T>(with newValue: T)
}

2.2 具体观察者(ConcrereObserver)

微信用户是观察者,里面实现了更新的方法:

class ConcreteObserver: Observer {
    private var _id: Int = 0
    
    var id: Int {
        get {
            return self._id
        }
    }
    
    init(id: Int) {
        self._id = id
    }
    
    func update<T>(with newValue: T) {
        print("Whoaa, observer #\(self.id) update with new value : ", newValue)
    }
}

2.3 抽象被观察者(Subject)

抽象主题,提供了attach、detach、notify三个方法:

protocol Subject {
    
    func addObserver(observer: Observer)
    func removeObserver(observer: Observer)
    func notifyAllObservers<T>(with newValue: T)
}

2.4 具体被观察者(ConcreteSubject)

微信公众号是具体主题(具体被观察者),里面存储了订阅该公众号的微信用户,并实现了抽象主题中的方法:

class ConcreteSubject<T>: Subject {
//    private var _value: T! = nil
//    private var _observers: [Observer] = []
    var _value: T! = nil
    var _observers: [Observer] = []
    
    var value : T {
        get {
            return self._value
        }
        
        set {
            self._value = newValue
//            self.notifyAllObservers(with: newValue)
        }
    }
    
    var observers: [Observer] {
        get {
            return self._observers
        }
        
        set {
            self._observers = newValue
        }
    }
    
    func addObserver(observer: Observer) {
        observers.append(observer)
    }
    
    func removeObserver(observer: Observer) {
        observers = observers.filter({ $0.id != observer.id })
    }
    
    func notifyAllObservers<T>(with newValue: T) {
        for observer in observers {
            observer.update(with: newValue)
        }
    }
}

2.5 客户端调用

var obs1 = ConcreteObserver(id: 1)
var obs2 = ConcreteObserver(id: 2)
var subject = ConcreteSubject<String>()
subject.addObserver(observer: obs1)
subject.addObserver(observer: obs2)
subject.value = "Surprise! New Feeds update."
subject.notifyAllObservers(with: subject.value)
subject.removeObserver(observer: obs1)
subject.value = "Obs1 removed, yey"
subject.notifyAllObservers(with: subject.value)

结果

Whoaa, observer #1 update with new value :  Surprise! New Feeds update.
Whoaa, observer #2 update with new value :  Surprise! New Feeds update.
Whoaa, observer #2 update with new value :  Obs1 removed, yey

代码下载

https://gist.github.com/zgpeace/4b83c0efef771770169654f051401bea

参考

https://medium.com/99ridho/swift-design-pattern-observer-pattern-fc009b783d19

https://medium.com/swift-coding/the-observer-pattern-in-swift-97a0e6fafa58

http://liuwangshu.cn/tags/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/

发布了167 篇原创文章 · 获赞 17 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/zgpeace/article/details/105157142