JavaScript 设计模式之观察者模式
观察者模式(Observer pattern)是一种软件设计模式,在这种模式中,一个称为subject的对象维护一个observer列表,在状态发生变化时自动通知它们,通常是调用它们的一个方法。
它定义了对象之间的一对多依赖关系,这样当一个对象改变状态时,它的所有依赖项都会被自动通知和更新。
此模式中主要构成是:
Subject – 它维护 observer 列表,多个observer可以监听一个 Subject;实现接口允许观察者对象订阅或者取消订阅;当状态发生变化时向观察者发送通知Observers – 它会提供一个函数,在Subject发生变化时可以被调用
<textarea id="mytext">
</textarea>
<p>你已经输入
<sapn id="textnum">0</sapn>个字符
</p>
<p>您输入的文字是:<span id="textcontent"></span></p>
<script type="text/javascript">
// subject对象,维护observe列表
// Subject构造函数用来创建特定类型的对象,在运行时会自动的出现在执行环境中,它可以用来创建对象,与普通函数的区别是函数名第一个字母得大写
function Subject() {
this.handlers = [];
}
// Subject函数代表了Subject对象,tapHandler和tapHandler2 是订阅的观察者。
// Subject定义了接口subscribe,unsubscribe和fire,分别用于订阅观察者,取消订阅观察者和通知观察者。
// 在test event触发之前,我们订阅了2个观察者。可以在控制台看到这两个观察者函数都分别执行了。
// 而在another event触发之前,我们取消订阅了tapHandler2观察者,所以只有tapHandler 观察者被通知。
Subject.prototype = {
constructor: Subject,
subscribe: function(fn) {
this.handlers.push(fn);
},
unsubscribe: function(fn) {
this.handlers = this.handlers.filter(
function(item) {
return item !== fn;
}
);
},
fire: function(data, thisArg) {
var scope = thisArg || window;
this.handlers.forEach(function(item) {
item.call(scope, data);
});
}
};
var subject = new Subject();
subject.subscribe(showInputLenght); //订阅
subject.subscribe(showInputContent); //订阅
// observe1
function showInputContent(str) {
contentElement.innerText = str;
}
// observe2
function showInputLenght(str) {
lenghtElement.innerText = str.length;
console.log(str.length);
}
var inputControl = document.getElementById('mytext');
var lenghtElement = document.getElementById('textnum');
var contentElement = document.getElementById('textcontent');
inputControl.addEventListener('keyup', function() {
subject.fire(inputControl.value); //触发通知
});
// 我们首先新建了 subject对象和观察者,然后调用subscribe方法订阅了观察者,
// 最后在 keyup的事件监听器中调用fire()方法,
// 会通知所有的观察者作出响应。
</script>