Analysis of JavaScript Design Pattern
The earliest origin of the design pattern is actually from architecture, a solution proposed for a certain problem
01 Preface
We have heard a lot about design patterns, but when someone asks what they are or what design patterns are available, we may not know or answer incompletely. In fact, we may rarely use design patterns in the development process, because many things have been encapsulated by us, we can just use them directly.
The development of the front end becomes extremely easy after being encapsulated again. We are handy in the process of application, and we will only see it in the process of reading the source code. I have probably browsed the book of JavaScript Design Patterns, so to summarize some commonly used patterns, the interview may also ask.
02 Design mode
Factory mode
As the name implies, we can literally see that it is conceivable that a factory continuously produces the same products and works in assembly lines. That's right, the factory model is like this.
class Person {
constructor(name) {
this.name = name
}
getName() {
console.log(this.name)
}
}
class Factory {
static create(name) {
return new Person(name)
}
}
Factory.create('alanwu').getName() //alanwu
We first create a factory, we just pass in the parameters, we don't need to care about the specific process, and finally return an object.
Singleton pattern
The singleton pattern is to ensure that there is only one instance of a class and provide a global access point to access it. In fact, this is a bit like the implementation in our vuex, it is also a global state management, and provides an interface access.
var Singleton = function (name) {
this.name = name;
}
Singleton.prototype.getName = function () {
console.log(this.name);
}
Singleton.getInstance = (function(){
var instance = null;
return function(name){
if(!instance){
instance = new Singleton(name);
}
return instance;
}
}
)()
var a = Singleton.getInstance('alan1');
var b = Singleton.getInstance('alan2');
console.log(a===b); //true
Adapter mode
The adapter mode is equivalent to a conversion interface. Everyone thinks that our mobile phone chargers are usually two forks, but the power supply is only three forks. At this time, an adapter is needed to convert the three-branch to the two-branch.
Its role is actually to solve the problem of incompatible interface between two software entities, and it can work together after use.
var googleMap = {
show: function () {
console.log('googleMap show!');
}
}
var baiduMap = {
show: function () {
console.log('baiduMap show!');
}
}
var renderMap = function (map) {
if (map.show instanceof Function) {
map.show()
}
}
renderMap(googleMap);
renderMap(baiduMap);
The above program can run because the same show method used by Baidu Maps and Google Maps, but when we do n’t know the function interface used by the other side, we ca n’t use it like this (maybe Baidu uses the display method to display) . The baiduMapAdapter below is the adapter we use.
var googleMap = {
show: function () {
console.log('googleMap show!');
}
}
var baiduMap = {
display: function () {
console.log('baiduMap show!');
}
}
var renderMap = function (map) {
if (map.show instanceof Function) {
map.show()
}
}
var baiduMapAdapter = {
show:function(){
return baiduMap.display()
}
}
renderMap(googleMap);
renderMap(baiduMapAdapter);
Proxy mode
We actually use the proxy mode when we are proxying the event. By handing over all listening events to the parent node for monitoring, you do n’t have to change the monitoring code when you add or delete nodes.
<ul id="ul">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script>
let ul = document.querySelector('#ul')
ul.addEventListener('click', (event) => {
console.log(event.target);
})
</script>
Publish-subscribe model
This pattern can be seen everywhere in life. For example, if you subscribe to an online class, you will be reminded to go to the class 10 minutes before the start. This is actually a publish-subscribe model. You subscribe to its course information, but you will not receive another course information because you have no subscription.
document.addEventListener('click', () => {
console.log("You click me!");
},false)
document.addEventListener('wheel', () => {
console.log("Your wheel!");
},false)
The first one is to listen to the click event, and the other is to listen to the scroll wheel event, which will print out different content.
Strategy Mode
Carry out different programs according to the situation, for example, if you want to travel, specify how much money you have and then choose the travel method.
- No money, walk
- Rich, plane
- OK, train
Here comes the strategy model.
var strategies = {
"rich": function () {
console.log("You can go with plane!");
},
"poor": function () {
console.log("OH, You can go with your feet!");
},
"middle": function () {
console.log("You can go with train!");
}
}
var howShouldGo = function (money) {
return strategies[money]();
}
console.log(howShouldGo("rich"));
Iterator pattern
Iterator mode refers to providing a method of sequential access. For example, the forEach method we often use is through sequential access mode. We can write the forEach method by ourselves.
var myForEach = function (arr, callback) {
for (var i = 0, l = arr.length; i < l; i++) {
callback.call(arr[i], i, arr[i]) //把元素以及下标传递出去
}
}f
myForEach([1, 2, 3], function (item, n) {
console.log([item, n]);
})
//[ 0, 1 ]
//[ 1, 2 ]
//[ 2, 3 ]
03 Summary
In fact, there are some places where we use design patterns, but we didn't pay attention. Above we said that they are all common design patterns, and there are many things we have not impressed, such as command mode, flyweight mode, combination mode, intermediary mode, etc.
If you are interested, you can take a look at the book JavaScript Design Patterns, which are all more detailed. I probably read it again, some of the above examples are also in the book.