数学角度看设计模式之观察者模式

观察者模式之授人与柄

   拟人化一点的说法就是两个人互相拿着一根连着对方的线,这跟线就是对方的引用,引用就是句柄,所以叫授人与柄.

  用不拟人的说法就是两个对象想互相操作, 就互相持有对方的柄(引用或者指针,类似于链表),双方进行通信的基础就是共同知道的一套规范(接口)

  个人理解的设计模式就是将需要达到的功能,用恰当的数据结构来表示出来,同时加上一些约定,让双方或多方协同工作。

  就是将数学的映射用代码表达出来。比如SQL=集合运算,SQL写不好的可以看看高等数学第一章,换个数学的角度看编程,也许世界就不一样了呢。

java定义一个接口为了让双方对disaplay有共同的理解,调用方说 你给我显示一下与被调用放的显示一下拥有同样的语义。

public interface DisaplayElement {
    void disaplay();
}
public class source{
        private List<DisaplayElement> list;
        private String msg;
        public void reg(DisaplayElement disaplay){
            this.list.add(disaplay);
        }
        public void notice(String msg){
            for(DisaplayElement disaplay:list){
                disaplay.disaplay(msg);
            }
        }
    }

然后下面是JS写的一个小DEMO,在木有接口类型的世界里简直是随心所欲


var source ={//数据源对象
  regList:[],//存放柄对象的数据结构
/**
注册列表数据结构如果是数组,只能做到全体通知执行。
如果是键值对结构

{

  {type1:[组件1,组件2...]},

  {type2:[组件n1,组件n2...]}

},可以分类型进行通知,观察者模式的灵活性在于注册列表的数据结构,根据自身业务建立不同的数据模型。
**/
  msg:'',//双方进行传递的消息对象,根据业务构建,Demo中定义为字符串演示
  isChange:false,//消息改变标记,消息改变时作为接收方进行拉取数据的标记
  reg:function(obj){
    regList.add(obj);
  },
  setMsg:function(msg){//设置改变 同时通知观察者
    isChange=true;//设置状态改变
    for(var i in regList){
      regList[i].callBack(this,msg);
    }
    isChange=false;//执行完毕清除状态标记
  },
  getMsg:function(){//提供拉取消息操作
    return this.msg;
  }
}
var disaplay ={//显示器 可以改成prototype的方式 把通用方法写到原型上 然后把各实例对象重写show方法。
  source:null,
  show:function(msg){//这里写获取通知的后业务逻辑,可以抽离到各自的新观察者对象上,原型上保存空实现或者默认实现
    alert(msg);
  },
  callBack:function(obj,msg){//约定的回调接口,观察者对象的引用 可以在此处主动获取数据

    show(msg);//推的方式
  },
  getChange:function(){
    if(source.change){
    var msg = source.getMsg();
  alert('拉过来的消息'+msg);
  }
},
Make:function(source){//构造函数 将源对象的柄拿过来
  var obj = new watcher();
  obj.source = source;
  source.reg(this)
  return obj;
  }
}
//以上类已经构造完毕
//下面写注册调用

var disaplay1 = watcher.Make(source);
disaplay1.show=function(msg){
  alert("开心的告诉你们哇"+msg);
  }
var disaplay2 = watcher.Make(source);
disaplay2.show=function(msg){
  alert("生气的告诉你们哇"+msg);
  }
source.setMsg('通知你们去食堂吃饭');

 
原文地址:https://www.cnblogs.com/xiaolong1985/p/6437739.html