美文网首页
设计模式之观察者模式(typescript,dart,golan

设计模式之观察者模式(typescript,dart,golan

作者: mudssky | 来源:发表于2021-07-10 09:35 被阅读0次

    现实例子

    也叫做发布订阅模式,这里给出的例子是,求职者订阅了招聘网站的服务,如果有匹配的工作信息,招聘网站会进行推送

    说人话

    建立对象间的依赖关系,使得一个对象的状态发生改变时,所有依赖它的对象都能被通知到。

    维基百科的描述

    观察者模式是一种软件设计模式,在这种模式中,一个称为主体的对象维护一个称为观察者的依赖项列表,并在任何状态更改时自动通知它们(通常通过调用它们的一个方法)。

    typescript example

    interface Subject {
      registerObserver(o: Observer): void
      removeObserver(o: Observer): void
      notifyObservers(info: any): void
    }
    
    interface Observer {
      update(s: Subject, arg: Object): void
    }
    
    class JobInfo {
      protected info: string
      constructor(info: string) {
        this.info = info
      }
      getInfo() {
        return this.info
      }
    }
    
    class JobSite implements Subject {
      protected observers: Array<Observer>
      constructor() {
        this.observers = Array<Observer>()
      }
      registerObserver(o: Observer): void {
        this.observers.push(o)
      }
      removeObserver(o: Observer): void {
        const index = this.observers.indexOf(o)
        this.observers.splice(index, 1)
      }
      notifyObservers(info: JobInfo): void {
        for (const o of this.observers) {
          o.update(this, info)
        }
      }
    
      AddJob(info: JobInfo) {
        console.log('招聘网站有新的工作追加了')
    
        this.notifyObservers(info)
      }
    }
    
    class Jiucai implements Observer {
      name: string
      constructor(name: string) {
        this.name = name
      }
      update(s: Subject, arg: JobInfo): void {
        console.log(`${this.name}收到新工作推送,职位是${arg.getInfo()}`)
      }
    }
    
    const zibenjia = new JobSite()
    
    const jiucai1 = new Jiucai('生命1号')
    const jiucai2 = new Jiucai('脑白金')
    
    zibenjia.registerObserver(jiucai1)
    zibenjia.registerObserver(jiucai2)
    
    zibenjia.AddJob(new JobInfo('web前端'))
    zibenjia.AddJob(new JobInfo('算法工程师'))
    
    

    下面是head first设计模式这本书里面关于气象站和告示板的typescript代码实现

    interface Subject {
      registerObserver(o: Observer): void
      removeObserver(o: Observer): void
      notifyObservers(): void
    }
    
    interface Observer {
      update(temp: number, humidity: number, pressure: number): void
    }
    
    interface DisplayElement {
      display(): void
    }
    
    class WeatherData implements Subject {
      private observers: Array<Observer>
      private temperature!: number
      private humidity!: number
      private pressure!: number
      constructor() {
        this.observers = Array<Observer>()
      }
      registerObserver(o: Observer): void {
        this.observers.push(o)
      }
      removeObserver(o: Observer): void {
        const index = this.observers.indexOf(o)
        this.observers.splice(index, 1)
      }
      notifyObservers(): void {
        for (const o of this.observers) {
          o.update(this.temperature, this.humidity, this.pressure)
        }
      }
    
      measurementsChanged() {
        this.notifyObservers()
      }
      setMeasurements(temperature: number, humidity: number, pressure: number) {
        this.temperature = temperature
        this.humidity = humidity
        this.pressure = pressure
        this.measurementsChanged()
      }
    }
    
    class CurrentConditionDisplay implements Observer, DisplayElement {
      private temperature!: number
      private humidity!: number
      private weatherData: Subject
      constructor(weatherData: Subject) {
        this.weatherData = weatherData
        this.weatherData.registerObserver(this)
      }
      update(temp: number, humidity: number, pressure: number): void {
        this.temperature = temp
        this.humidity = humidity
        this.display()
      }
    
      display(): void {
        console.log(
          `Current conditionsc: ${this.temperature} F degrees and ${this.humidity}% humidity`
        )
      }
    }
    
    class StatisticsConditionDisplay implements Observer, DisplayElement {
      private pressure!: number
      private weatherData: Subject
      constructor(weatherData: Subject) {
        this.weatherData = weatherData
        this.weatherData.registerObserver(this)
      }
      update(temp: number, humidity: number, pressure: number): void {
        this.pressure = pressure
        this.display()
      }
    
      display(): void {
        console.log(`Statistics conditionsc: ${this.pressure} pressure`)
      }
    }
    const wd = new WeatherData()
    const ccd = new CurrentConditionDisplay(wd)
    const scd = new StatisticsConditionDisplay(wd)
    wd.setMeasurements(80, 65, 30.4)
    wd.setMeasurements(82, 75, 28.3)
    wd.setMeasurements(78, 90, 36.4)
    
    export {}
    
    

    dart example

    dart中Object不想typescript一样可以接受任何其他类。

    所以我这里对observer 用了泛型。

    abstract class Observer<T> {
      void update(Subject s, T o);
    }
    
    abstract class Subject {
      void registerObserver(Observer o);
      void removeObserver(Observer o);
      void notifyObservers(Object o);
    }
    
    class JobInfo {
      late String info;
      JobInfo(this.info);
    }
    
    class JobSite implements Subject {
      final List<Observer> observers = [];
    
      @override
      void registerObserver(Observer o) {
        this.observers.add(o);
      }
    
      @override
      void removeObserver(Observer o) {
        this.observers.remove(o);
      }
    
      @override
      void notifyObservers(Object o) {
        for (var item in this.observers) {
          item.update(this, o);
        }
      }
    
      void addJobInfo(JobInfo j) {
        print('有新的工作信息');
        this.notifyObservers(j);
      }
    }
    
    class Jiucai implements Observer<JobInfo> {
      final String name;
    
      Jiucai(this.name);
      @override
      void update(Subject s, JobInfo o) {
        print("$name收到新的工作推送,职位是${o.info}");
      }
    }
    
    main(List<String> args) {
      var zibenjia = JobSite();
    
      var jiucai1 = Jiucai('李白');
      var jiucai2 = Jiucai('白居易');
    
      zibenjia.registerObserver(jiucai1);
      zibenjia.registerObserver(jiucai2);
      zibenjia.addJobInfo(JobInfo('AI工程师'));
    }
    
    

    golang example

    package main
    
    import "fmt"
    
    type Subject interface {
        registerObserver(o Observer)
        removeObserver(o Observer)
        notifyObservers(s Subject, o interface{})
    }
    
    type Observer interface {
        update(s Subject, o interface{})
    }
    
    type JobSite struct {
        observers []Observer
    }
    
    func (j *JobSite) registerObserver(o Observer) {
        j.observers = append(j.observers, o)
    }
    
    func (j *JobSite) removeObserver(o Observer) {
        for i := 0; i < len(j.observers); i++ {
            if o == j.observers[i] {
                j.observers = append(j.observers[:i], j.observers[i+1:]...)
                return
            }
        }
    }
    func (j *JobSite) notifyObservers(s Subject, o interface{}) {
        for i := 0; i < len(j.observers); i++ {
            j.observers[i].update(s, o)
        }
    }
    func (j *JobSite) addJobInfo(info string) {
        fmt.Println("新工作信息入库")
        j.notifyObservers(j, info)
    }
    
    type Jiucai struct {
        name string
    }
    
    func (j *Jiucai) update(s Subject, o interface{}) {
        fmt.Printf("%s收到新的工作推送,职位是%v\n", j.name, o)
    }
    func main() {
        zibenjia := JobSite{observers: []Observer{}}
        jiucai1 := Jiucai{name: "张三"}
        jiucai2 := Jiucai{name: "李四"}
        zibenjia.registerObserver(&jiucai1)
        zibenjia.registerObserver(&jiucai2)
        zibenjia.addJobInfo("喝牛奶")
    
    }
    
    

    相关文章

      网友评论

          本文标题:设计模式之观察者模式(typescript,dart,golan

          本文链接:https://www.haomeiwen.com/subject/sfccpltx.html