引子,如图:
刘鹏经理在王芳姑娘身上安装了监视器,那么能不能在代码里给变量安装监视器呢?比如实现这样的功能:
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); } }
结果如下:
不知道还有没有更优雅的实现方式呢。