JavaScript 设计模式之观察者模式

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>

posted @ 2021-05-25 18:14  一星一辰  阅读(101)  评论(0编辑  收藏  举报