最近在看网易的公开课,有一节课有讲到设计模式在js中的应用,觉得把之前一直不太理解的这块内容讲得还挺直白的,现在就把课上的内容整理下来,当个笔记。
老师把二十多种设计模式分成了四个大类,分别是:创建型设计模式、结构型设计模式、行为型设计模式、技巧型设计模式。
创建型设计模式
创建型设计模式包括工厂模式、建造者模式、原型模式、单例模式。主要都是在创建一个对象时候需要考虑的。
工厂模式
工厂模式主要用于批量创建对象,当需要创建的对象的一些特性相对固定的时候,工厂模式是一种非常合适的模式。
function ballFactor(type){
if(typeof type!='string'){
throw new Error('type must be a string');
}
//第一,不要遗漏防错处理
//第二,定义一个方法或者一个类,你得这样写保证安全
if(this instanceof ballFactor){
var s = new this[type]();
return s;
}else{
return new ballFactor(type);
}
}
//定义球的类型
ballFactor.prototype = {
basketball : function(){
this.name='basketball';
},
tennis : function(){
this.name='tennis';
}
};
//新创建一个球
var a = new ballFactor('tennis');
建造者模式
建造者模式用于定制化的创建对象,当需要对一个对象的所有属性进行配置的时候,可以考虑建造者模式。
//建造模式
//需要关心如何组装对象
function hand(size){
console.log(size)
}
function foot(size){
console.log(size);
}
function face(status){
console.log(status);
}
function person(){
this.hand = new hand(100);
this.foot = new foot(180);
this.face =new face('good');
}
原型模式
原型模式用于创建一系列共享原型的对象,由于js天生自带原型属性,这里就不具体举例了。
单例模式
单例模式用于创建独一无二的对象,我们只能从这个对想象中的方法拿到里面的属性、方法,而无法通过new去实例化。
//单例模式
//保证全局只有一个对象
var single = (function(){
//定义私有变量
function _a(){
this.a = 123;
};
var ob = new _a();
return {
get:function(name){
return ob[name];
}
}
})();
结构型设计模式
在创建完对象之后,要对对象进行结构设计,结构包含了内部结构和外部结构,内部结构就是指对象内部的结构规划,外部结构更多的是处理对象与对象间的关系。结构型设计模式主要包括:外观模式、适配器模式、装饰器模式、代理模式、享元模式。
外观模式
外观模式就是把零散的接口组合到一起供外部调用的一种模式,类似于快餐店的套餐组合。
适配器模式
适配器模式就好比是转接头,将不适合的接口调整成适合的接口。
//适配器模式
//把不合适的东西进行适配
//假设要把A框架的改为jquery框架,可以对A框架的实现进行重写
var A = {
on:function(){
}
}
//重写on方法,实质上是去调用jquery的on方法
A.on = function(dom,type,fn){
return $(dom).on(dom,type,fn)
}
A.on();
装饰器模式
装饰器模式就是一种不修改源码地扩展方法地思路。
//装饰器模式
//不去修改源码的去扩张方法。
var A = {
c:function(){
console.log(1)
};
}
function deco(fn1, fn2){
var _fn1 = fn1;
var _fn2 = fn2;
return function(){
_fn1();
_fn2();
}
}
var a = deco(A.c, function(){
console.log(2);
});
A.c = a;
享元模式
享元模式是一种优化程序性能的手段,通过共享公用数据来减少对象数量以达到优化程序的手段。享元模式适用于拥有大量类似对象并且对性能有要求的场景。dom中的事件委托就是享元模式的一种实际应用。
行为型设计模式
行为型设计模式主要是用来组织对象之间沟通的一种设计模式,主要包括:观察者模式、策略模式、状态模式、迭代器模式、解释器模式、命令模式。
观察者模式
观察者模式主要用于模块之间的沟通,例如jq中的自定义事件、vuex状态管理。
var obs={
fallback:{},
on : function(type,fn){
this.fallback[type] = fn;
},
fire : function(type){
this.fallback[type]();
},
delete : function(){
this.fallback[type] = null;
}
}
obs.on('mytest',function(){
console.log(1);
})
obs.fire('mytest');
策略模式
//策略模式
通过策略模式,将需要传相同类型的参数的几个函数封装成一个对象,单纯的通过调用实现具体的功能。
function calc(type,a,b){
var a={
add : function(a,b){
return a+b;
},
minus : function(a,b){
return a-b
}
}
a[type](a,b);
}
状态模式
在策略模式的基础上加上一个状态管理。
//状态模式
var a={
statusArr:[],
on : function(){
this.statusArr.push(type);
},
fire : function(){
this.statusArr.forEach((item,index) => {
this.catorlist[item]();
})
},
catorlist : {
add : function(a,b){
return a+b;
},
minus : function(a,b){
return a-b;
}
}
}
a.on('add');
a.on('minus');
a.fire();
命令模式
命令模式是一种指导思想,将具体的实现和需求解耦。
//命令模式
var arr = [
document.getElementById("dom1"),
{title:'title',pic:"url1"},
{title:'title2',pic:"url2"},
{title:'title3',pic:"url4"}
];
function command () {
var _html='';
function create(arr){
arr.forEach(function(item,index){
_html+="<div><img src='"+item.pic+"'></img></div>";
})
}
function display(content){
content.innerHTML=_html;
}
function _excute(command){
create(command.splice(1));
display(command[0]);
}
return {
excute:_excute;
}
}
command().excute(arr);
迭代器模式
迭代器模式就是一系列的数据处理。
//迭代器模式
//把一系列数据的处理先写好
function calc(){
}
calc.prototype.equal = function(arr,num){
var istrue = false;
arr.forEach(function(item,index){
if(item == num){
istrue = true;
}
})
return istrue;
}
解释器模式
解释器模式就相当于模版引擎的概念。
技巧性设计模式
技巧性设计模式包括:链模式、委托模式、节流模式、惰性模式、等待模式。许多技巧型模式都有对应的实例。
链模式
jq链式调用。
委托模式
js的事件委托。
节流模式
防抖截流。
惰性模式
目的是减少判断。
//惰性模式
//b的值一开始制定,就不会变
var b = 100;
var a = (function(){
if(b === 100){
a = function(){console.log(1)};
}else{
a = function(){console.log(2)};
}
})();
等待者模式
等待者模式就类似于es2017中的async await的概念,等待上一个步骤执行完了,再执行下一个操作。
以上就是设计模式在js中的应用的相关整理,先放这里,以后有实际应用的时候翻看。