The code should be written in a way that others cannot understand (12)

This article refers to the book "JavaScript Design Patterns"-Zhang Rongming

Preface

  After you come into contact with the web , you will definitely encounter a hard bone- IE browser. One of my seniors told me that if IE is not dead, society will not be able to progress. At that time, I was young and ignorant and didn't understand the meaning. Now the times have changed. Looking back, passers-by are watching, but they are the ones in the game~.
Insert picture description here
  Going off the topic, talking back to our topic today, everyone must have encountered it. After writing a part of the function, the debugging is complete, and sometimes it may have been deployed to the server. At this time, the project manager patted you on the shoulder. Said to you amiably, there is a small demand, and there is not much change, you can add it.

  At this time, you have to carefully consider the meaning of " not much change ". Generally speaking, it means that the result has not changed much. Then the specific implementation process has not changed much, so just digest it internally.

  In order to reduce the above situation, we will study a new design pattern together today, the visitor pattern.

Visitor mode

  For the elements in the object structure, define a new method to access the elements in the structure without changing the object .

  For example, in IE , when attachEvent is used to bind an event, this refers to window instead of the current element. Then when we use this , an error will be reported:

var bindEvent = function(dom, type, fn) {
    
    
	if(dom.addEventListener) {
    
    
		dom.addEventListener(type, fn, false);
	} else if(dom.attachEvent) {
    
    
		dom.attachEvent('on' + type, fn);
	} else{
    
    
		dom['on' + type] = fn;
	}
}
var demo = document.getElementById('demo');
bindEvent(demo. 'click', function() {
    
    
	this.style.background = 'red'; //IE中会报this.style为空或不为对象
});

  Now there are two ways to modify, one is to replace all this with demo , this method obviously will modify the internal parameters of the method, subsequent modification and maintenance may be more costly, then there is another way to add new operations to the operation elements Methods as below:

function bindIEEvent(dom, type, fn, data) {
    
    
	var data = data || {
    
    };
	dom.attachEvent('on' + type, function(e) {
    
    
		fn.call(dom, e, data);
	});
};

  The core method is to call the call method once . We know that call and apply change the scope of the function execution. This is the essence of the visitor pattern. Through this method, we can make an object run in other scopes.

  Another advantage is that call and apply allow us to add additional parameters. This is very important because sometimes the data obtained through the event parameter e is not enough.

function $(id) {
    
    return document.getElementById(id)};
bindIEEvent($('btn'), 'click', function(e, d) {
    
    
	$('test').innerHTML = e.type + d.text + this.tagName;
}, {
    
    text: 'test demo'});

  The above code, click id for the btn buttons, id to test paragraphs of content will become the Click test Demo BUTTON .

  The visitor pattern application is not only that, but the JS native object constructor is designed as a visitor. For example, when judging the data type, we use Object.prototype.toString.call . Here we can extend it. When we add properties to objects, there is usually no order, so it is difficult to find the last added properties. If we can handle the object like an array, it will be fine. We add data through push , Delete the last member through pop .

  Here we need to create an accessor and encapsulate the necessary methods in it for easy use.

//访问器
var Vistor = (function() {
    
    
	return {
    
    
		//截取方法
		splice: function() {
    
    
			//splice 方法参数,从原参数的第二个参数开始算起
			var args = Array.prototype.splice.call(arguments, 1);
			//对第一个参数对象执行 splice 方法
			return Array.prototype.splice.apply(arguments[0], args);
		},
		//追加数据方法
		push: function() {
    
    
			//强化数组对象,使它拥有 length 属性
			var len = arguments[0].length || 0;
			//添加的数据从原参数的第二个参数算起
			var args = this.splice(arguments, 1);
			//校正 length 属性
			arguments[0].length = len + arguments.length - 1;
			//对第一个参数对象执行 push 方法
			return Array.prototype.push.apply(arguments[0], args);
		},
		//弹出最后一次添加的元素
		pop: function() {
    
    
			//对第一个参数对象执行 pop 方法
			return Array.prototype.pop.apply(arguments[0]);
		}
	}
})();

  With this accessor, we can manipulate array objects.

var a = new Object();
console.log(a.length);   //undefined
Visitor.push(a, 1,2,3,4);
console.log(a.length);  //4
Visitor.push(a, 4,5,6);
console.log(a);         //Object {0: 1, 1: 2, 2: 3, 3: 4, 4: 4, 5: 5, 6: 6, lenght: 7}
Visitor.splice(a, 2);
console.log(a);         //Obkect {0: 1, 1: 2, length: 2}

  The visitor mode can solve the coupling between data and data operation methods, and make the data operation method independent of data, so that it can evolve freely. Therefore, the visitor mode is suitable for those environments where the data is stable but the operation method is volatile.

Intermediary model

   The intermediary object encapsulates the interaction between a series of objects, so that the objects no longer refer to each other and reduce the coupling between them.

  The intermediary mode is similar to the observer mode we mentioned earlier. They are all implemented through the message sending and receiving mechanism. The difference is that in the observer mode, an object can be either the sender or the receiver of the message. , The exchange of information between them relies on the decoupling of the message system.

  In the intermediary mode, message sending can only be done through intermediary objects. Objects cannot subscribe to messages. Only those active objects (subscribers) can subscribe to the intermediary's messages. In addition, the observer mode also needs to write a message system. Will increase development costs. Below we write an intermediary object:

//中介者对象
var Mediator = function() {
    
    
	//消息对象
	var _msg = {
    
    };
	return {
    
    
		/**
		* 订阅消息方法
		* 参数 type    消息名称
		* 参数 action  消息回调函数
		*/
		register: function(type, action) {
    
    
			//如果该消息存在
			if(_msg[type]) {
    
    
				//存入回调函数
				msg[type].push(action);
			} else {
    
    
				//不存在则建立消息容器
				_msg[type] = [];
				//存入新消息回调函数
				_msg[type].push(action);
			}
		},
		/**
		* 发布消息方法
		* 参数 type    消息名称
		*/
		send: function(type) {
    
    
			//如果该消息已经被订阅
			if(_msg[type]) {
    
    
				//遍历已经存储的消息回调函数
				for(var i = 0, len = _msg[type].length; i < len; i++) {
    
    
					//执行该回调函数
					_msg[type][i] && _msg[type][i]();
				}
			}
		}
	}
} ();

  The intermediary is created. To be on the safe side, try it out with test cases first.

//单元测试
//订阅demo消息,执行回调函数--输出 first
Mediator.register('demo', function() {
    
    
	console.log('first');
})
//订阅demo消息,执行回调函数--输出 second
Mediator.register('demo', function() {
    
    
	console.log('second');
})
//发布 demo 消息
Mediator.send('demo');
//输出结果以此为
//first
//second

  Students who are familiar with the appearance mode may think this is a bit similar to the appearance mode. The intermediary mode encapsulates the interaction of multiple objects, and these objects are generally on the same level, and the encapsulated interaction is inside the intermediary, and the purpose of the appearance mode To provide a simpler and easier-to-use interface.

  The two design patterns in this section are relatively easy to understand. When you use a design pattern, you may become more and more messy. It feels a bit like other design patterns that you have contacted before, but you forget which one it is. There is a feeling that a bear breaks a stick, and it will be this one now.

  In fact, this feeling is similar to normal. Knowledge is inherently similar. If you feel chaotic, it means you know a lot. At this time, it is a process of quantitative change and qualitative change. Everyone, hold on, read it a few times, use it a few times, and you will be able to learn the next time. Empowerment.



Guess you like

Origin blog.csdn.net/EcbJS/article/details/109814904