16.ObserverPattern - QDDCoder/LZLearniOS GitHub Wiki

观察者模式

解释地址:https://www.runoob.com/design-pattern/observer-pattern.html

当对象间存在一对多关系时则使用观察者模式Observer Pattern)。比如当一个对象被修改时则会自动通知依赖它的对象观察者模式属于行为型模式意图定义对象间的一种一对多的依赖关系当一个对象的状态发生改变时所有依赖于它的对象都得到通知并被自动更新主要解决一个对象状态改变给其他对象通知的问题而且要考虑到易用和低耦合保证高度的协作何时使用一个对象目标对象的状态发生改变所有的依赖对象观察者对象都将得到通知进行广播通知如何解决使用面向对象技术可以将这种依赖关系弱化关键代码在抽象类里有一个 ArrayList 存放观察者们优点1观察者和被观察者是抽象耦合的2建立一套触发机制缺点1如果一个被观察者对象有很多的直接和间接的观察者的话将所有的观察者都通知到会花费很多时间2如果在观察者和观察目标之间有循环依赖的话观察目标会触发它们之间进行循环调用可能导致系统崩溃3观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的而仅仅只是知道观察目标发生了变化使用场景一个抽象模型有两个方面其中一个方面依赖于另一个方面将这些方面封装在独立的对象中使它们可以各自独立地改变和复用一个对象的改变将导致其他一个或多个对象也发生改变而不知道具体有多少对象将发生改变可以降低对象之间的耦合度一个对象必须通知其他对象而并不知道这些对象是谁需要在系统中创建一个触发链A对象的行为将影响B对象B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制注意事项1JAVA 中已经有了对观察者模式的支持类2避免循环引用3如果顺序执行某一观察者错误会导致系统卡壳一般采用异步方式

1.创建 Subject 类

class Subject: NSObject {
    private var observers:[Observer] = [Observer]()
    private var state:Int = 0
    
    func getState() -> Int {
        return state
    }
    
    func setState(with state:Int)  {
        self.state = state
        notifyAllObservers()
    }
    
    func attach(with observer:Observer)  {
        observers.append(observer)
    }
    
    func notifyAllObservers()  {
        observers.forEach { (observer) in
            observer.update()
        }
    }
        
}

2.创建 Observer 类

protocol Observer {
    var subject:Subject{get set}
    func update()
}

3.创建实体观察者类。

class BinaryObserver:NSObject,Observer {
    var subject: Subject
    init(with subject:Subject) {
        self.subject = subject
    }
    
    func update() {
        print("Binary String: \(subject.getState())")
    }
}

class OctalObserver:NSObject,Observer {
    var subject: Subject
    init(with subject:Subject) {
        self.subject = subject
    }
    
    func update() {
        print("Octal String: \(subject.getState())")
    }
}

class HexaObserver:NSObject,Observer {
    var subject: Subject
    init(with subject:Subject) {
        self.subject = subject
    }
    
    func update() {
        print("Hex String: \(subject.getState())")
    }
}
  • 测试

var subject = Subject()
let ho = HexaObserver(with: subject)
subject.attach(with: ho)
let oo = OctalObserver(with: subject)
subject.attach(with: oo)
let bo = BinaryObserver(with: subject)
subject.attach(with: bo)

print("第一次状态改变")
subject.setState(with: 15)
print("第二次状态改变")
subject.setState(with: 10)
  • 结果

第一次状态改变
Hex String: 15
Octal String: 15
Binary String: 15
第二次状态改变
Hex String: 10
Octal String: 10
Binary String: 10
⚠️ **GitHub.com Fallback** ⚠️