设为首页 加入收藏

TOP

JavaScript设计模式之观察者模式(学习笔记)(一)
2015-11-10 13:46:15 来源: 作者: 【 】 浏览:37
Tags:JavaScript 设计模式 观察者 模式 学习 笔记

设计模式(Design Pattern)对于软件开发来说其重要性不言而喻,代码可复用、可维护、可扩展一直都是软件工程中的追求!对于我一个学java script的人来说,理解设计模式似乎有些困难,对仅切图、做少量交互效果的FE甚至可能不会用到,但是当你开始使用Angular/Backbone等框架的时候,就无法避免设计模式、MVC/MVVM这些东西了(反正我是伤脑筋)。


我学设计模式是刚开始接触编程大概三个月的时候,看一本书《大话设计模式》,里面用C#语言来写,我很无语,因为强类型的编程语言对于我这种写弱类型的毛头小子来说,似乎又有困难啊,于是我就学C#基础语法规则去了。。。今年年初我又学了JAVA的基础语法规则。。。然而我的初衷已经被抛弃在一旁,落上了厚厚的灰层。对于自学编程的我来说,不知道学习编程的先后顺序似乎吃亏不少,但是总要有开头的!


以上可直接跳过


本文相关文件下载


--------------------------------------------------------------------------------


先来说一下我对“观察者模式”的个人理解:观察者模式又称“发布-订阅(Publish/Subscribe)模式”,发布与订阅显然是两个不同对象的功能,比如RSS。知乎是一个发布者(发布一些对某方面问题的高赞同解答),我作为一个订阅者(在我的邮箱里面订阅了知乎的相关发布内容),我的同事以及我的老板都订阅了知乎,所以在这个模型中,有一个发布者,有三个订阅者。


在具体编程中,发布者有了新的内容,需要向订阅者推送数据,那么新的内容(state)、订阅者有哪些(observers)就是发布者需要包含的东西,谁订阅了、谁退订了则要对发布者中的订阅者列表进行更新。以下是发布者的相关信息代码解读:


//发布者
? ? ? ? function Publisher(){
? ? ? ? ? ? this.observers = [];
? ? ? ? ? ? this.state = "";


? ? ? ? }
? ? ? ? Publisher.prototype.addOb=function(observer){
? ? ? ? ? ? var flag = false;
? ? ? ? ? ? for (var i = this.observers.length - 1; i >= 0; i--) {
? ? ? ? ? ? ? ? if(this.observers[i]===observer){
? ? ? ? ? ? ? ? ? ? flag=true;? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? }
? ? ? ? ? ? };
? ? ? ? ? ? if(!flag){
? ? ? ? ? ? ? ? this.observers.push(observer);
? ? ? ? ? ? }
? ? ? ? ? ? return this;
? ? ? ? }
? ? ? ? Publisher.prototype.removeOb=function(observer){
? ? ? ? ? ? var observers = this.observers;
? ? ? ? ? ? for (var i = 0; i < observers.length; i++) {
? ? ? ? ? ? ? ? if(observers[i]===observer){
? ? ? ? ? ? ? ? ? ? observers.splice(i,1);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? };
? ? ? ? ? ? return this;
? ? ? ? }
? ? ? ? Publisher.prototype.notice=function(){
? ? ? ? ? ? var observers = this.observers;
? ? ? ? ? ? for (var i = 0; i < observers.length; i++) {
? ? ? ? ? ? ? ? ? ? observers[i].update(this.state);
? ? ? ? ? ? };
? ? ? ? }


以上在遍历observers数组的时候,可以使用数组类的filter、forEach等新特性来处理。第三个notice函数表示发布者有了新东西,然后对订阅者列表中的所有人通知他们我有新内容(state)了,你们拿去更新你们的邮箱吧。这里把内容传递给了每一个订阅者的update更新功能。


那么订阅者呢?订阅者很简单,只需要具有一个update功能即可(每一个订阅者update可能不一样,比如我是放进邮箱了,我的同事则将订阅的拿来,并且顺便把旧的删掉了,我的上司则将数据转发到Gmail去了)。下面是订阅者相关信息代码解读:


//订阅者
? ? ? ? function Subscribe(){
? ? ? ? ? ? this.update = function(data){
? ? ? ? ? ? ? ? ? console.log(data);
? ? ? ? ? ? };
? ? ? ? }


实际上,因为每一个订阅者都有这个update,所以我们通常应该将其添加到构造器的原型上面,当对这个默认的update功能不满足要求的时候,可以为每一个订阅者的实例设置单独的update,比如将这个data发送给别人。最后咱们看看怎么应用。


//实际应用
? ? ? ? var oba = new Subscribe(),
? ? ? ? ? ? obb = new Subscribe();


? ? ? ? var pba = new Publisher();


? ? ? ? pba.addOb(oba);
? ? ? ? pba.addOb(obb);


? ? ? ? oba.update = function(state){
? ? ? ? ? ? console.log(state+"hello!");
? ? ? ? }
? ? ? ? obb.update = function(state){
? ? ? ? ? ? console.log(state+"world!");
? ? ? ? }
? ? ? ? pba.state = "open ";
? ? ? ? pba.notice();


大家看到,我们在最后对发布者手动设置了它的内容(state)并且要求他发出通知(notice)。在实际项目中,发布者的内容可能是从后台获取的也可能是从前台某地方输入的。然而发布者每次更新内容后又要手动调用通知是不是有点多余呢?既然更新了内容那就肯定要通知别人了啊。那我们就把内容的更新与发出通知进行绑定好了,看下面的代码:





? ?
? ? Document


? ? <script type="text/java script">
? ? ? ? //发布者
? ? ? ? function Publisher(){
? ? ? ? ? ? this.observers = [];
? ? ? ? ? ? var state = "";? ? //让该内容不能直接访问


? ? ? ? ? ? //新增两个对于state的操作 获取/更新
? ? ? ? ? ? this.getState=function(){
? ? ? ? ? ? ? ? return state;
? ? ? ? ? ? }
? ? ? ? ? ? this.setState=function(value){
? ? ? ? ? ? ? ? state = value;
? ? ? ? ? ? ? ? this.notice();
? ? ? ? ? ? }


? ? ? ? }
? ? ? ? Publisher.prototype.addOb=function(observer){
? ? ? ? ? ? var flag = false;
? ? ? ? ? ? for (var i = this.observers.length - 1; i >= 0; i--) {
? ? ? ? ? ? ? ? if(this.observers[i]===observer){
? ? ? ? ? ? ? ? ? ? flag=true;? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? }
? ? ? ? ? ? };
? ? ? ? ? ? if(!flag){
? ? ? ? ? ? ? ? this.observers.push(observer);
? ? ?

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C语言实现快速排序 下一篇快速排序和三向快速排序

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: