提高代碼質(zhì)量的目的
- 高質(zhì)量的代碼,方便后續(xù)的一切操作
2.方便他人閱讀
什么是代碼質(zhì)量
1.代碼整潔
2.結(jié)構(gòu)規(guī)整,沒(méi)有漫長(zhǎng)的結(jié)構(gòu)
3.閱讀好理解
優(yōu)化你的代碼結(jié)構(gòu)
1.策略模式/狀態(tài)模式
目的:優(yōu)化if-else分支
應(yīng)用場(chǎng)景:當(dāng)代碼If-else分支過(guò)多時(shí)
2.外觀模式
目的:通過(guò)為多個(gè)復(fù)雜的子系統(tǒng)提供一個(gè)一致的接口
應(yīng)用場(chǎng)景:當(dāng)完成一個(gè)操作,需要操作多個(gè)子系統(tǒng),不如提供一個(gè)更高級(jí)的
3.迭代器模式
目的:不訪問(wèn)內(nèi)部的情況下,方便的遍歷數(shù)據(jù)
應(yīng)用場(chǎng)景:當(dāng)我們要對(duì)某個(gè)對(duì)象進(jìn)行操作,但是又不能暴露內(nèi)部
4.備忘錄模式
目的:記錄狀態(tài),方便回滾
應(yīng)用場(chǎng)景:系統(tǒng)狀態(tài)多樣,為了保證狀態(tài)的回滾方便,記錄狀態(tài)
基本結(jié)構(gòu)
策略模式的基本結(jié)構(gòu)
假設(shè)要編寫(xiě)一個(gè)計(jì)算器,有加減乘除,我們可以把一層一層的If判斷,變成這樣的形勢(shì)
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 Strategy[type](a,b);
}
狀態(tài)模式的基本結(jié)構(gòu)
為了減少if-else結(jié)構(gòu),將判斷變成對(duì)象內(nèi)部的一個(gè)狀態(tài),通過(guò)對(duì)象內(nèi)部的狀態(tài)改變,讓其擁有不同行為
function stateFactor(state){
var stateObject = {
_status:"",
state:{
state1:function(){
},
state2:function(){
},
},
run:function(){
return this.state[this._status]();
}
}
stateObject.status = state;
return stateObject;
}
stateFactor('state1').run();
外觀模式的基本結(jié)構(gòu)
我們?cè)诮M織方法模塊時(shí)可以細(xì)化多個(gè)接口,但是我們給別人使用時(shí),要合為一個(gè)接口,就像你可以直接去餐廳點(diǎn)餐
···
//模塊1
function Model1(){
}
//模塊2
function Model2(){
}
//功能由Model1獲取Model2得結(jié)果來(lái)完成
function use(){
Model2(Model1());
}
···
迭代器模式的基本結(jié)構(gòu)
在不暴露對(duì)象內(nèi)部結(jié)構(gòu)得同時(shí),可以順序得訪問(wèn)對(duì)象內(nèi)部的,可以幫助我們簡(jiǎn)化循環(huán),簡(jiǎn)化數(shù)據(jù)操作
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);
}
}
備忘錄模式的基本結(jié)構(gòu)
記錄對(duì)象內(nèi)部的狀態(tài),當(dāng)有需要時(shí)回滾到之前的狀態(tài)或者方便對(duì)象使用
function Memento(){
var cache = {};
return function(cacheName){
if(cache[cacheName]){
//有緩存的操作的
}else{
//沒(méi)緩存的操作
}
}
}
var MementoFn = Memento();
MementoFn('xxx')
應(yīng)用示例
策略/狀態(tài)模式的示例
1.動(dòng)態(tài)的內(nèi)容
需求:項(xiàng)目有一個(gè)動(dòng)態(tài)的內(nèi)容,根據(jù)用戶權(quán)限的不同顯示不同的內(nèi)容
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();
}
}
//使用狀態(tài)模式優(yōu)化
function showControll(){
this.status = '';
this.power = {
boss:function(){
showPart1();
showPart2();
showPart3();
},
manner:function(){
showPart1();
showPart2();
},
staff:function(){
showPart3();
},
}
}
}
showControll.prototype.show = function(){
var self = this;
axios.get('xxx').then(res)=>{
self.status=res;
self.power[self.status]();
}
}
new showControll().show();
2.復(fù)合運(yùn)動(dòng)
需求:有一個(gè)小球,可以控制它左右移動(dòng),或者左前,右前等方式移動(dòng)
function moveLeft(){
console.log('left');
}
function moveRight(){
console.log('rigmoveRight');
}
function moveTop(){
console.log('Top');
}
function moveBottom(){
console.log('bomovueBottom');
}
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();
}
//...
}
}
//使用狀態(tài)模式優(yōu)化
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','top')
外觀模式的示例
1.插件封裝的規(guī)律
需求:插件基本上都會(huì)最終使用提供一個(gè)高級(jí)接口
function tab(){
this.dom = null;
}
tab.prototype.initHTML=function(){
}
tab.prototype.changeTab=function(){
}
tab.prototype.eventBind=function(){
}
tab.prototype.init=function(config){
this.initHTML(config);
this.eventBind();
}
2.封裝成方法的思想
需求:再兼容時(shí)代,我們會(huì)常常需要檢測(cè)能力,不妨作為一個(gè)統(tǒng)一接口
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;
}
}
迭代器者模式的示例
1.構(gòu)建一個(gè)自己的forEach
需求:forEach方法其實(shí)是個(gè)典型的迭代器方法
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);
}
}
}
2.給你的項(xiàng)目數(shù)據(jù)添加迭代器
需求:項(xiàng)目會(huì)經(jīng)常對(duì)于后端數(shù)據(jù)進(jìn)行遍歷操作,不如封裝一個(gè)迭代器,遍歷的更方便
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'){
handleFn = handler;
}else{
handleFn=function(item){
if(item[handler] == num){
return item;
}
}
}
for(var i=0;i<this.data.length;i++){
var _result=handleFn.call(this,this.data[i]);
if(_result){
_arr.push(_result);
}
}
return _arr;
}
}
i(data).getHasSomenum('num',1);
i(data).getHasSomenum(function(item){
if(item.num-1==2){
return item;
}
})
迭代器者模式的示例
1.文章頁(yè)緩存
需求:項(xiàng)目有一個(gè)文章頁(yè)需求,現(xiàn)在進(jìn)行優(yōu)化,如果上一篇已經(jīng)讀取過(guò)了,則不進(jìn)行請(qǐng)求,否則請(qǐng)求文章數(shù)據(jù)
function pager(){
var cache = {};
return function(pageName){
if(cache[pageName]){
return cache[pageName];
}else{
axios.get(pageName).then((res) => {
cache[pageName] = res;
})
}
}
}
2.前進(jìn)后退功能
需求:開(kāi)發(fā)一個(gè)可移動(dòng)的div,擁有前進(jìn)后退回滾到之前的位置
function moveDiv(){
this.stateList = [];
this.nowState = 0;
}
movwDiv.prototype.move = function(type,num){
changeDIv(type.num);
this.stateList.push({
type:type,
num:num
})
this.nowState=this.stateList.length -1;
}
movwDiv.prototype.go = function(type,num){
var _state;
if(this.nowState<this.stateList-1){
this.nowState++;
_state=this.stateList[this.nowState];
changeDiv(_state.type,_state.num);
}
}
課程小結(jié)
1.策略/狀態(tài)模式:幫助我們優(yōu)化if-else結(jié)構(gòu)
2.外觀模式:一種套餐化接口的思想,提醒我們封裝常用方法
3.迭代器模式:幫助我們更好的遍歷數(shù)據(jù)
4.備忘錄模式:幫我們緩存以及回到過(guò)去的狀態(tài)