你。。你在我身上裝了監視器

                                                                                                   引子,如圖:

圖片.png

劉鵬經理在王芳姑娘身上安裝了監視器,那麼能不能在代碼裏給變量安裝監視器呢?比如實現這樣的功能:

int i = 100

watch(i, log(old, new) { print old, new})  給變量I 安裝一個監視器

i += 100  當i 變化時候,會調用log函數。

怎麼實現呢?函數式語言貌似不倡導可變變量,那麼用支持可變對象的Scala試試看吧。

我首先想到的就是 SET屬性, 然後在屬性裏調用註冊好的函數,代碼如下:

/*
  你。。你在我身上安裝了監視器 代碼版本
*/
class Watch[T] (var value: T) {
  type F = (T, T) => Unit
  val dict = new scala.collection.mutable.HashMap[String, F]()
  def setValue(t: T) {
    for ((_,f1) <- dict) {
      f1(value, t)
    }
    value = t
  }
  def addWatch(k:String)(f:F) {
      dict(k) = f
  }
  
  def removeWatch(k:String){
      dict.remove(k)
  }
}
object Watch {
  def apply[T](t: T) = new Watch(t)
  
}
object Hi {
  def main(args: Array[String]) {
    //聲明一個watch變量
    val w1 = new Watch("Hello")  
    
    //添加一個監視器
    w1.addWatch("key1") {
      (oldValue: String , newValue: String) => 
        println(s"w1 Old Value: $oldValue => New Value: $newValue")
    }
    //通過setValue改變值
    w1.setValue("123")
 
    var w2 =  Watch(111111)
    w2.addWatch("key1") {
      (oldValue: Int , newValue: Int) => 
        println(s"w2 Old Value: $oldValue => New Value: $newValue")
    }
    w2.setValue(2222222)
    //移除監視器
    w2.removeWatch("key1")
    //下面的沒有監視器了
    w2.setValue(3333333)
    
    
    implicit def i2Watch(a: Int) = Watch(a)
    var i = 10;
    i.addWatch("key1"){
      (oldValue: Int , newValue: Int) => 
        println(s"w2 Old Value: $oldValue => New Value: $newValue")
    }
    //這裏每次都會 重新 new 一個Watch,所以不起作用的
    //
    i.setValue(100);
  }      
}

結果如下:

圖片.png


不知道還有沒有更優雅的實現方式呢。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章