我是靠谱客的博主 小巧皮带,最近开发中收集的这篇文章主要介绍web 观察者模式,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

 介绍一种观察者模式其实观察者模式是一个比较简单的 Publish,Subscribe过程,整个过程概括起来说就是对
对订阅者这个数组的操作,而消息的发布其实就是 遍历订阅者对象调用订阅者本身方法的一个过程,在实际中的应用的话,还需要用setter 方法做一下数据劫持

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);
};
}

一个构造函数,外加原型上的几个方法即可简单解决

在对 观察者进行遍历的时候, 可以用过滤器等进行下拦截

订阅者需要一个Update的方法 由于不同对象对这个update 方法行为表现不同 , 每个对象可以有不同的实现 :


function Subscribe(){
this.update = function(data){
console.log(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)。在实际项目中,发布者的内容可能是从后台获取的也可能是从前台某地方输入的。然而发布者每次更新内容后又要手动调用通知是不是有点多余呢?既然更新了内容那就肯定要通知别人了啊。那我们就把内容的更新与发出通知进行绑定好了,看下面的代码

对于以上的内容,或许并没有跟我们的项目中实际出现的问题有关,那我们就来代入这种设计模式,做一个例子:三个文本框ABC,其中A可编辑,B与C不可编辑且B的值是A的值加上后缀”@w3c.com”,C的值是A的值加上前缀”ID-“。


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div>
<label>用户名称:<input type="text" id="pba" placeholder="请输入用户名称" /></label><br /><br />
<label>生成邮箱:<input type="text" id="oba" readonly /></label>
<label>生成ID:<input type="text" id="obb" readonly /></label>
</div>
<script type="text/javascript">
//发布者
function Publisher(obj){
this.observers = [];
var state = obj.value;
//让该内容不能直接访问
//新增两个对于state的操作 获取/更新
this.getState=function(){
return state;
}
this.setState=function(value){
state = value;
this.notice();
}
this.obj = obj;
}
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.getState());
};
}
//订阅者
function Subscribe(obj){
this.obj = obj;
this.update = function(data){
this.obj.value = data;
};
}
//实际应用
var oba = new Subscribe(document.querySelector("#oba")),
obb = new Subscribe(document.querySelector("#obb"));
var pba = new Publisher(document.querySelector("#pba"));
pba.addOb(oba);
pba.addOb(obb);
oba.update = function(state){
this.obj.value = state+"@w3c.com";
}
obb.update = function(state){
this.obj.value = "ID-"+state;
}
pba.obj.addEventListener('keyup',function(){
pba.setState(this.value);
});
</script>
</body>
</html>

在《大话设计模式》一书中,提到类似的情况:如果针对发布者内容而订阅者要做不同的事情呢?比如一个按钮和三个矩形,点击按钮的时候,第一个矩形增加宽度,第二个矩形增加高度,第三个矩形则变成圆角矩形又该怎么做呢?当然我们可以在三个矩形的update内部写具体的实现代码,但是这update岂不是没有一个具体的功能描述了吗?该书中用“事件委托”解决了这个问题(此处事件委托和DOM中的事件委托应该是两码事),我个人理解这个“事件委托”在javascript中可以用一个数组表示,然后里面放各个订阅者的不同名字的update,然后一一调用。

在《javascript设计模式》一书中,关于观察者模式的实现也是采用”推“这种方式,章节的最后反问到如何实现”拉“这种方式呢?

我个人理解:发布者推送数据的时候有强制性,促使订阅者更新(update),然而在”拉“这种模式中,发布者本身仅仅包含最新的内容,没有通知(notice)没有订阅者列表,当订阅者需要得到数据的时候在其对应的update方法里面传入发布者对象即可。小白之见,请对该模式有不同理解的道友多多指正。

Refer:http://www.alixixi.com/web/a/2015091595377.shtml

最后

以上就是小巧皮带为你收集整理的web 观察者模式的全部内容,希望文章能够帮你解决web 观察者模式所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(63)

评论列表共有 0 条评论

立即
投稿
返回
顶部