JS设计模式——提高代码质量

提高代码质量的目的

  • 高质量的代码,方便后续的一切操作
  • 方便他人阅读

说明是代码质量

  1. 代码整洁
  2. 结构规整,没有漫长的结构
  3. 阅读好理解

优化你的代码结构

策略模式/状态模式

目的:优化if-else分支

应用场景:当代码if-else分支过多时

策略模式基本结构

// 假设要编写一个计算器,有加减乘除,我们可以把一层一层的if判断,变成这样的形式
function Strategy(type,a,b){
    var Strategyer={
        add:function(a,b){
            return a+b;        
        },
        minus:function(a,b){
            return a-b;        
        },
        division:function(a,b){
            return a/b;        
        }  
    }
    return Strateger[type](a,b);
}

 状态模式的基本结构

// 为了减少if-else结构,将判断变成对象内部的一个状态,
// 通过对象内部的一个状态改变,让其拥有不同行为
function stateFactor(state){
    var stateObject={
        _statue:"",
        state:{
            state1:function(){
                            
            },
            state2:function(){
                            
            },  
        },
        run:function(){
            return this.state[this._status]();        
        }
    }
    stateObject._status=state;
    return stateObject;
}
stateFactor('state1').run();

 示例(动态的内容、复合运动)

// 动态的内容
// 需求:项目有一个动态的内容,根据用户权限的不同显示不同的内容
 function showPart1(){
   console.log(1);
 }
 function showPart2(){
  console.log(2);
}
function showPart3(){
  console.log(3);
}
// 未使用状态模式前
axios.get('xxx').then((res)=>{
   if(res=='boss'){
     showPart1();
     showPart2();
     showPart3();
   }else if(res=='manner'){
    showPart1();
    showPart2();     
   }else if(res=='staff'){
    showPart3();
   }
})
// 使用状态模式
 function showControl(){
  this.status='';
    this.power={
    boss:function(){
    showPart1();
    showPart2();
    showPart3();      
    },
    manner:function(){
    showPart1();
    showPart2();
    },
    staff:function(){
    showPart3();
    }
  }
 }
 showControl.prototype.show=function(){
   var self=this;
   axios.get('xxx').then((res)=>{
     self.status=res;
     self.power[self.status]();
   })
 }
 new showControl().show();

 

// 复合运动
// 需求:有一个小球,可以控制它左右移动,或者左前,右前等方式移动
// 基本方法
function moveLeft(){
  console.log('left')
}
function moveRight(){
  console.log('RigmoveRight')  
}
function moveTop(){
  console.log('Top')   
}
function moveBottom(){
  console.log('bomoveBottom')  
}
// 未用状态模式时
function mover(){
   if(arguments.length==1){
     if(arguments[0]=='left'){
         moveLeft();
     }else if(arguments[0]=='right'){
     moveRight();
     }else if(arguments[0]=='top'){
     moveTop();
     }else if(arguments[0]=='bottom'){
     moveBottom();
     }
   }else{
     if(arguments[0]=='left'&&arguments[1]=='top'){
     moveLeft();
     moveTop();
     }else if(arguments[0]=='right'&&arguments[1]=='bottom'){
     moveRight();
     moveBottom();
     }
     //....
   }
 }
 
// 使用状态模式 
 function mover(){
   this.status=[];
   this.actionHandle={
    left:moveLeft,
    right:moveRight,
    top:moveTop,
    bottom:moveBottom
   }
 }
 mover.prototype.run=function(){
   this.status=Array.prototype.slice.call(arguments);
   this.status.forEach((action)=>{
     this.actionHandle[action]();
   })
 }
 new mover().run('left','right');

外观模式

目的:通过为多个复杂的子系统提供一个一致的接口

应用场景:当完成一个操作,需要操作多个子系统,不如提供一个更高级的

基本结构

/我们在组织方法模块时可以细化多个接口,但是我们给别人使用时,
// 要合为一个接口,就像你可以直接去餐厅点套餐
// 模块1
function Model1(){
    
}
// 模块2
function Model2(){
    
}
// 功能由Model1获取Model2得结果来完成
function use(){
    Model2(Model1());
}

 示例(插件封装的规律、封装成方法的思想)

// 插件封装的规律
// 需求:插件基本上都会给最终使用提供一个高级接口
//选项卡插件
function tab(){
  this.dom=null
}
tab.prototype.initHTML=function(){
}
tab.prototype.changeTab=function(){
      
}
tab.prototype.eventBind=function(){
   var self=this;
   this.dom.onclick=function(){
     self.changeTab();
   }
}
tab.prototype.init=function(config){
  this.initHTML(config);
  this.eventBind();
}

 

/ 封装成方法的思想
// 需求:在兼容时代,我们会常常需要检测能力,不妨作为一个统一接口
//dom支持检测
function addEvent(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
  }
}

优化你的代码操作

迭代器模式

目的:不访问内部的情况下,方便的遍历数据

应用场景:当我们要对某个对象进行操作,但是有不能暴露内部

基本结构

// 在不暴露对象内部结构得同时,可以顺序的访问对象内部的,
// 可以帮助我们简化循环,简化数据操作
function Iterator(item){
    this.item=item;
}
Iterator.prototype.dealEach=function(fn){
    for(var i=0;i<this.item.length;i++){
        fn(this.item[i],i);    
    }
}

 示例(构建一个自己的forEach、给你的项目数据添加迭代器)

// 构建一个自己的forEach
// 需求:forEach方法其实是个典型的迭代器方法
//forEach
function Iterator(data){
  this.data=data;
}
Iterator.prototype.dealEach=function(fn){
  if(this.data instanceof Array){
     for(var i=0;i<this.data.length;i++){
       fn(this.data[i],i)
     }
  }else{
     for(var item in this.data){
       fn(this.data[item],item)
     }
  }
}
// 给你的项目数据添加迭代器
// 需求:项目会经常对于后端数据进行遍历操作,不如封装一个迭代器,遍历的更方便
//数据迭代器
var data=[{num:1},{num:2},{num:3}]
function i(data){ // 工厂模式
    function Iterator(data){
      this.data=data;
    }
    Iterator.prototype.getHasSomenum=function(handler,num){// 符合要求的对象
       var _arr=[];// 存符合条件的对象
       var handleFn;
       if(typeof handler=='function'){ // handler=方法
         handleFn=handler;
       }else{
         handleFn=function(item){ // handler=参数
             if(item[handler]==num){
                return item;
             }
         }
       }
       // 享元模式,提出不同点handleFn
       for(var i=0;i<this.data.length;i++){
          var _result=handleFn.call(this,this.data[i])
          if(_result){
            _arr.push(_result);  
          }
          
       }
       return _arr;
    }
    return new Iterator(data);
}
// 使用我们的迭代器
//i(data).getHasSomenum('num',1);

i(data).getHasSomenum(function(item){
  if(item.num-1==2){
      return item;
  }
});

备忘录模式

目的:记录状态,方便回滚

应用场景:系统状态多样,为保证状态的回滚方便,记录状态

基本结构

// 记录对象内部的状态,当有需要时回滚到之前的状态或者方便对象使用
function Memento(){
    var cache={}
    return function(cacheName){
        if(cache[cacheName]){
            // 有缓存的操作        
        } else {
            // 没缓存的操作        
        }
    }
}
var MementoFn = Memento();
MementoFn('xxx')

示例(文章页缓存、前进后退功能)

// 文章页缓存
// 需求:项目有一个文章页需求,现在进行优化,
// 如果上一篇已经读取过了,则不进行请求,否则请求文章数据
//缓存
function pager(){
  var cache={};
  return function(pageName){
     if(cache[pageName]){
         return cache[pageName];
     }else{
         axios.get(pageName).then((res)=>{
           cache[pageName]=res;
         })
     }
  }
}
var getpage=pager();
getpage('pageone');
// 前进后退功能
// 需求:开发一个可移动的div,拥有前进后退功能回滚到之前的位置
//前进后退
function moveDiv(){
    this.stateList=[];
    this.nowState=0;
}
moveDiv.prototype.move=function(type,num){
    moveDiv(type,num);
    this.stateList.push({
     type:type,
     num:num
    });
    this.nowState=this.stateList.length-1;
}
moveDiv.prototype.go=function(){
  var _state;
  if(this.nowState<this.stateList.length-1){
      this.nowState++;
      _state=this.stateList[this.nowState];
      moveDiv(_state.type,_state.num);
  } 
}
moveDiv.prototype.back=function(){
    var _state;
    if(this.nowState>=0){
        this.nowState--;
        _state=this.stateList[this.nowState];
        // 后退的话反向轨迹操作
        moveDiv(_state.type,_state.num);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值