define

The Observer pattern (also known as Publish/Subscribe) is one of the behavioral patterns that defines a one-to-many dependency that allows multiple observer objects to listen on a subject object at the same time. The topic object notifies all observer objects of state changes so that they can update themselves automatically

Observer pattern structure diagram

Observer mode role

  • Observer: Abstract Observer, an abstract class for the Observer that defines an update interface to update itself when notified of a topic change.
  • ConcrereObserver: A concrete observer that implements an update interface defined by an abstract observer to update its own state when notified of a topic change.
  • Abstract topic roles store all observer objects in a collection. Each topic can have any number of observers. Abstract topics provide an interface to add and remove observer objects.
  • ConcreteSubject: Concrete topic (concrete observed). This role stores the state in the concrete observer object and notifies all registered observers when the internal state of the concrete topic changes.

Observer mode simple code implementation

  • The observer
   /// Observer mode

// An abstract Observer
protocol Observer {
    var id: Int { get }
    func update<T> (with newValue: T)
}

// Specific observer
class ConcreateObserver: Observer {
    var id: Int {
        get {
            return self._id
        }
    }
    private var _id: Int = 0
    
    init(id: Int) {
        self._id = id
    }
    
    func update<T> (with newValue: T) {
        print("Whoaa , observer \ [self.id) update with new value :",newValue)
    }
}
Copy the code
  • The observed
// Abstract the observed (Subject)
protocol Subject {
    func addObserver(observer: Observer)
    func removeObserver(observer: Observer)
    func notifyAllObservers<T> (with newValue: T)
}
// ConcrereObserver
class ConCreateSubject<T> :Subject {
   
    
    var _value: T! = nil
    
    var _observers: [Observer] = []
    
    var value: T {
        get {
            return self._value
        }
        
        set {
            self._value = newValue
        }
    }
    
    var observers: [Observer] {
        set {
            self._observers = newValue
        }
        get {
            return self._observers
        }
    }
    
    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)
        }
    }
    
}
Copy the code
  • call
class ViewController: UIViewController {

    override func viewDidLoad(a) {
        super.viewDidLoad()
        
        let obs1 = ConcreateObserver(id: 1)
        let obs2 = ConcreateObserver(id: 2)
        let subject = ConCreateSubject<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)

    }

}
Copy the code
  • Print the result
  1. Whoaa , observer 1 update with new value : Surprise! New Feeds update.
  2. Whoaa , observer 2 update with new value : Surprise! New Feeds update.
  3. Whoaa , observer 2 update with new value : Obs1 removed, yey

It can be seen that there are two observers with ID 1 and 2 respectively, the observed subject of a subject, and then the observed subject adds the listener addObserver. These two observers id=1, ID =2, and then the observed subject notifies the observer that my status has changed, and all the added listeners can receive the notification. Update closure (id = 2); update closure (id = 2); update closure (id = 2)