设计模式23篇之 观察者模式详解

观察者模式:

对象之间多对一依赖的一种设计方案,被依赖的对象为 Subject,依赖的对象为 Observer,Subject 通知 Observer 变化,比如这里的奶站是 Subject,是 1 的一方。用户时 Observer, 是 n 的一方。

观察者模式类似订牛奶业务

  1. 奶站/气象局:Subject
  2. 用户/第三方网站:Observer

Subject:登记注册、移除和通知

  1. registerObserver 注册
  2. removeObserver 移除
  3. notifyObservers() 通知所有的注册的用户,根据不同需求,可以是更新数据,让用户来取, 也可能是实施推送,看具体需求定

Observer:接收输入

自己实现观察者模式代码示例:

Observer 抽象类

trait Observer {
  //抽象方法,等待其它的观察者实现
  def update(mTemperatrue: Float, mPressure: Float, mHumidity: Float)

}

subject抽象类

//这个是Subject 是一个trait(接口)
trait Subject {

  //注册
  def registerObserver(o: ObServer)

  //remove
  def removeObserver(o: ObServer)

  //通知
  def notifyObservers()

}

观察者实现类1

class SinaCurrentConditions extends Observer {

  private var mTemperature: Float = _
  private var mPressure: Float = _
  private var mHumidity: Float = _

  def display() = {
    if (this.mTemperature > 40) {
      println("***新浪的天气公告板 Today mTemperature: " + mTemperature + "*** 赶紧离开地球")
    } else if (mTemperature > 16 && mTemperature < 28) {
      println("***新浪的天气公告板 Today mTemperature: " + mTemperature + "*** 赶紧回到地球")
    }

    println("***新浪的天气公告板 Today mPressure: " + mPressure + "***")
    println("***新浪的天气公告板 Today mHumidity: " + mHumidity + "***")
  }

  override def update(mTemperature: Float, mPressure: Float, mHumidity: Float) = {
    //更新天气公告板
    this.mTemperature = mTemperature
    this.mPressure = mPressure
    this.mHumidity = mHumidity
    //显示
    display()
  }
}

观察者实现类2

//气象局的公告板
class CurrentConditions extends Observer {

  private var mTemperature: Float = _
  private var mPressure: Float = _
  private var mHumidity: Float = _

  def display() = {
    println("***气象局的天气公告板 Today mTemperature: " + mTemperature + "***")
    println("***气象局的天气公告板 Today mPressure: " + mPressure + "***")
    println("***气象局的天气公告板 Today mHumidity: " + mHumidity + "***")
  }

  override def update(mTemperature: Float, mPressure: Float, mHumidity: Float) = {
    //更新天气公告板
    this.mTemperature = mTemperature
    this.mPressure = mPressure
    this.mHumidity = mHumidity
    //显示
    display()
  }
}

Subject实现类: 实现订阅, 取消订阅, 推送, 通知等功能
从中我们可以看出, 可以动态引入, 删除观察者, 在调用观察者的observer.update()时, 有点抽象工厂的影子

class WeatherDataSt extends Subject {

  private var mTemperature: Float = _
  private var mPressure: Float = _
  private var mHumidity: Float = _
  //集合,用于管理所有的观察者
  private val mObservers: ListBuffer[ObServer] = ListBuffer()

  def getTemperature() = {
    mTemperature
  }

  def getPressure() = {
    mPressure
  }

  def getHumidity() = {
    mHumidity
  }

  def dataChange() = {
    //一旦天气变化,就通知所有观察者
    notifyObservers()
  }

  //天气变化
  def setData(mTemperature: Float, mPressure: Float, mHumidity: Float) = {
    this.mTemperature = mTemperature
    this.mPressure = mPressure
    this.mHumidity = mHumidity
    dataChange()
  }

  //注册
  override def registerObserver(o: ObServer): Unit = {
    //加入到mObservers
    mObservers.append(o)
  }

  //移除,比如某个第三方不想接入
  override def removeObserver(o: ObServer): Unit = {
    if (mObservers.contains(o)) {
      mObservers -= o
    }
  }

  //通知,天气情况变化了,我们就通知所有的观察者
  override def notifyObservers(): Unit = {
    for (observer <- mObservers) {
      observer.update(mTemperature, mPressure, mHumidity)
    }
  }
}

main

object InternetWeather {
  def main(args: Array[String]): Unit = {

    //创建个月气象局的天气公告板
    val mCurrentConditions = new CurrentConditions()

    val mWeatherDataSt = new WeatherDataSt
    //mCurrentConditions 注册
    mWeatherDataSt.registerObserver(mCurrentConditions)

    //创建一个新浪的天气公告板
    val sinaCurrentConditions = new SinaCurrentConditions
    mWeatherDataSt.registerObserver(sinaCurrentConditions)


    //比如天气情况变化,这里设置最新数据
    mWeatherDataSt.setData(20, 150, 40)

   
  }
}

JDK内置了观察者模式的实现方案:

  1. java.util.Observable类比本文Subject
  2. java.util.Observer类比本文Observer
发布了125 篇原创文章 · 获赞 236 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_33709508/article/details/103627265