JS之14種設計模式 (6)

圖片描述

序列文章

JS面試之函數(1)
JS面試之對象(2)
JS面試之數組的幾個不low操做(3)
JS面試之http0.9~3.0對比分析(4)
JS面試之數據結構與算法 (5)html

前言

設計模式若是應用到項目中,能夠實現代碼的複用和解耦,提升代碼質量。 本文主要介紹14種設計模式
寫UI組件,封裝框架必備

1.簡單工廠模式

1.定義:又叫靜態工廠方法,就是建立對象,並賦予屬性和方法
2.應用:抽取類相同的屬性和方法封裝到對象上
3.代碼:面試

let UserFactory = function (role) {
  function User(opt) {
    this.name = opt.name;
    this.viewPage = opt.viewPage;
  }
  switch (role) {
    case 'superAdmin':
      return new User(superAdmin);
      break;
    case 'admin':
      return new User(admin);
      break;
    case 'user':
      return new User(user);
      break;
    default:
      throw new Error('參數錯誤, 可選參數:superAdmin、admin、user')
  }
}

//調用
let superAdmin = UserFactory('superAdmin');
let admin = UserFactory('admin') 
let normalUser = UserFactory('user')
//最後獲得角色,能夠調用

2.工廠方法模式

1.定義:對產品類的抽象使其建立業務主要負責用於建立多類產品的實例
2.應用:建立實例
3.代碼:算法

var Factory=function(type,content){
  if(this instanceof Factory){
    var s=new this[type](content);
    return s;
  }else{
    return new Factory(type,content);
  }
}

//工廠原型中設置建立類型數據對象的屬性
Factory.prototype={
  Java:function(content){
    console.log('Java值爲',content);
  },
  PHP:function(content){
    console.log('PHP值爲',content);
  },
  Python:function(content){
    console.log('Python值爲',content);
  },
}

//測試用例
Factory('Python','我是Python');

3.原型模式

1.定義:設置函數的原型屬性
2.應用:實現繼承
3.代碼:segmentfault

function Animal (name) {
  // 屬性
  this.name = name || 'Animal';
  // 實例方法
  this.sleep = function(){
    console.log(this.name + '正在睡覺!');
  }
}
// 原型方法
Animal.prototype.eat = function(food) {
  console.log(this.name + '正在吃:' + food);
};

function Cat(){ 
}
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';

// Test Code
var cat = new Cat();
console.log(cat.name);//cat
console.log(cat.eat('fish'));//cat正在吃:fish  undefined
console.log(cat.sleep());//cat正在睡覺! undefined
console.log(cat instanceof Animal); //true 
console.log(cat instanceof Cat); //true

4.單例模式

1.定義:只容許被實例化依次的類
2.應用:提供一個命名空間
3.代碼:設計模式

let singleCase = function(name){
    this.name = name;
};
singleCase.prototype.getName = function(){
    return this.name;
}
// 獲取實例對象
let getInstance = (function() {
    var instance = null;
    return function(name) {
        if(!instance) {//至關於一個一次性閥門,只能實例化一次
            instance = new singleCase(name);
        }
        return instance;
    }
})();
// 測試單體模式的實例,因此one===two
let one = getInstance("one");
let two = getInstance("two");

5.外觀模式

1.定義:爲子系統中的一組接口提供一個一致的界面
2.應用:簡化複雜接口
3.代碼:
外觀模式數組

6.適配器模式

1.定義:將一個接口轉換成客戶端須要的接口而不須要去修改客戶端代碼,使得不兼容的代碼能夠一塊兒工做
2.應用:適配函數參數
3.代碼:
適配器模式緩存

7.裝飾者模式

1.定義:不改變原對象的基礎上,給對象添加屬性或方法
2.代碼數據結構

let decorator=function(input,fn){
  //獲取事件源
  let input=document.getElementById(input);
  //若事件源已經綁定事件
  if(typeof input.onclick=='function'){
    //緩存事件源原有的回調函數
    let oldClickFn=input.onclick;
    //爲事件源定義新事件
    input.onclick=function(){
      //事件源原有回調函數
      oldClickFn();
      //執行事件源新增回調函數
      fn();
    }
  }else{
    //未綁定綁定
    input.onclick=fn;
  }
}

//測試用例
decorator('textInp',function(){
  console.log('文本框執行啦');
})
decorator('btn',function(){
  console.log('按鈕執行啦');
})

8.橋接模式

1.定義:將抽象部分與它的實現部分分離,使它們均可以獨立地變化
2.代碼
橋接模式框架

9.模塊方法模式

1.定義:定義一個模板,供之後傳不一樣參數調用
2.代碼:
模塊方法模式函數

10.觀察者模式

1.做用:解決類與對象,對象與對象之間的耦合
2.代碼:

let Observer=
  (function(){
    let _message={};
    return {
      //註冊接口,
        //1.做用:將訂閱者註冊的消息推入到消息隊列
        //2.參數:因此要傳兩個參數,消息類型和處理動做,
        //3.消息不存在從新建立,存在將消息推入到執行方法
        
      regist:function(type,fn){
        //若是消息不存在,建立
        if(typeof _message[type]==='undefined'){
          _message[type]=[fn];
        }else{
          //將消息推入到消息的執行動做
          _message[type].push(fn);
        }
      },

      //發佈信息接口
        //1.做用:觀察這發佈消息將全部訂閱的消息一次執行
        //2.參數:消息類型和動做執行傳遞參數
        //3.消息類型參數必須校驗
      fire:function(type,args){
        //若是消息沒有註冊,則返回
        if(!_message[type]) return;
          //定義消息信息
          var events={
            type:type, //消息類型
            args:args||{} //消息攜帶數據
          },
          i=0,
          len=_message[type].length;
          //遍歷消息
          for(;i<len;i++){
            //依次執行註冊消息
            _message[type][i].call(this,events);
          }
      },

      //移除信息接口
        //1.做用:將訂閱者註銷消息從消息隊列清除
        //2.參數:消息類型和執行的動做
        //3.消息參數校驗
      remove:function(type,fn){
        //若是消息動做隊列存在
        if(_message[type] instanceof Array){
          //從最後一個消息動做序遍歷
          var i=_message[type].length-1;
          for(;i>=0;i--){
            //若是存在該動做在消息隊列中移除
            _message[type][i]===fn&&_message[type].splice(i,1);
          }
        }
      }
    }
  })()

//測試用例
  //1.訂閱消息
  Observer.regist('test',function(e){
    console.log(e.type,e.args.msg);
  })

  //2.發佈消息
  Observer.fire('test',{msg:'傳遞參數1'});
  Observer.fire('test',{msg:'傳遞參數2'});
  Observer.fire('test',{msg:'傳遞參數3'});

11.狀態模式

1.定義:一個對象狀態改變會致使行爲變化
2.做用:解決複雜的if判斷
3.代碼
狀態模式

12.策略模式

1.定義:定義了一系列家族算法,並對每一種算法單獨封裝起來,讓算法之間能夠相互替換,獨立於使用算法的客戶
2.代碼
策略模式

13.訪問模式

1.定義:經過繼承封裝一些該數據類型不具有的屬性,
2.做用:讓對象具有數組的操做方法
3.代碼:
訪問者模式

14.中介者模式

1.定義:設置一箇中間層,處理對象之間的交互
2.代碼:
中介者模式

相關文章
相關標籤/搜索