圖解設計模模式

對於將來的前端都要像全棧過分,那麼就可能要操做後臺,瞭解設計模式仍是有用的。其實就是一種思想。前端

工廠模式

工廠模式思想就是相似工廠機器能夠造一樣功能屬性的產品。因此咱們只須要建立一個工廠,而且告訴他咱們要什麼樣的產品。

function Horse (name,sex) {
        let obj = new Object()
        //抽象出一個馬,這個馬具備全部馬的特性
        obj.name = name
        obj.sex = sex
        obj.saySex = function () {
            alert(`個人性別是${this.sex}`)
        }
        //定義要生產一類馬的屬性
        return obj //製造好之後生產
    }
    let banma = Horse('小花','母')
    banma.saySex()             //個人性別是母
建立一個生產猴子的工廠,馬都具備相同屬性,可是名字卻能夠不同,這就是多態性,因此傳遞參數來命名。
在工做中好比咱們有一項相功能,在不少地方都使用了,那麼就能夠用工廠模式來完成,而沒必要每次都從新寫一次。
好比:咱們作一個數字和字母的驗證方法。
function Validation (type) {
        let obj = new Object()
        obj.method = function (type) {
            return   //效驗規則的結果
        }
        return obj //製造好之後生產
    }
    let reusult = Validation(123)
             //根據reusult結果判斷
複製代碼

構造器模式

構造器模式的思想和工廠模式實際上是同樣的,我的認爲只是寫法不一樣。es6

function Horse (name,sex) {
       this.name=name;
       this.sex=sex;
    }
    let banma = new Horse('小花','母');
    //工廠函數使用了new 操做符
    //下圖是new作了些什麼的圖
複製代碼

安全模式的構造函數

其實安全構造函數就是爲了不你們不知道你是構造函數,而直接去使用。因此加個判斷就行了,若是不是函數。編程

function Person(content){
  if (this instanceof Person){
  // 判斷是否是Person的實例
    this.name = name;
    this.age = age;
    this.sex = sex;
  }else{
    return new Person( content);
  }
}
let banma = new Person('小花');
function Person(type,content){
  if (this instanceof Person){
  // 判斷是否是Person的實例
   let  newPerson = this[type](content)
   //添加屬性並傳遞參數。返回新對象
    return newPerson
  }else{
    return new Person(type, content);
  }
}
let banma = new Person('name','小花');

複製代碼

建造者模式

建造者模式(Builder Pattern)使用多個簡單的對象一步一步構建成一個複雜的對象。這種類型的設計模式屬於建立型模式,它提供了一種建立對象的最佳方式。建造者模式就像拿一個個對象當磚塊,一個個壘起來。工廠模式咱們是不須要了解建立結果的過程,而建造者能夠清晰的知道建造過程。 應用實例:設計模式

es5
//建立一我的類
    var Human = function(param){
        //skill技能
        this.skill = param && param.skill || '保密';
        //興趣愛好
        this.hobby = param && param.hobby || '保密';
    }
    //添加人類的原型方法
    Human.prototype = {
        getSkill:function(){
            return this.skill;
        },
        getHobby:function(){
            return this.hobby;
        }
    }
    //建立姓名類
    var Named = function(name){
        var that = this;
        //構造器函數:解析姓與名(new構造實例時即刻執行此閉包函數)
        (function(name,that){
          //閉包函數this指向window
            that.wholeName = name;//全名賦值
            if (name.indexOf(' ')>-1) {
                that.firstName = name.slice(0,name.indexOf(' '));
                that.secondName = name.slice(name.indexOf(' '));
            };
        })(name,that);
    };
    //建立職位類
    var Work = function(work){
        var that = this;
        //構造器函數:經過傳入的職位類設置相應的職位及描述
        (function(work,that){
            switch(work){
                case 'code':
                    that.work = '軟件工程師';
                    that.workDescript = '天天都在敲代碼';
                break;
                case 'UI':
                case 'UE':
                    that.work = '設計師';
                    that.workDescript = '設計是一種藝術';
                break;
                case 'teacher':
                    that.work = '教師';
                    that.workDescript = '分享也是一種快樂';
                break;
                default:
                    that.work = work;
                    that.workDescript = '沒有合適的描述';
            }
        })(work,that);
    }
    //添加更換職位的方法
    Work.prototype.changeWork = function(work){
        this.work = work;
    }
    //添加對職位的描述方法
    Work.prototype.changeDescript = function(setence){
        this.workDescript = setence;
    }
    //建立一個應聘者builder
    var Person = function(name,work,param){
        //實例化人對象 建立實例化緩存對象
        var _person = new Human(param);
        //實例化人的姓名
        _person.name = new Named(name);
        //實例化人的指望職位
        _person.work = new Work(work);
        //最後將構建的複雜對象應聘者返回出去
        return _person;
    }
    //測試用例
    var person = new Person('小 明','code');

    console.log(person.skill);  //保密
    console.log(person.name.firstName);  //小
    console.log(person.work.work); // 軟件工程師
    console.log(person.work.workDescript); //天天都在敲代碼
    person.work.changeDescript('我天天都在快樂的編程學習')
    console.log(person.work.workDescript); //我天天都在快樂的編程學習  
    console.log(person instanceof Person); //false
    console.log(person instanceof Human); //true
    console.log(person instanceof Named); //false
    
es6 
//父類
class BaseBuilder {
  init() {
    Object.keys(this).forEach(key => {
      const withName = `with${key.substring(0, 1).toUpperCase()}${key.substring(1)}`;
      this[withName] = value => {
        this[key] = value;
        return this;
      }
    })
  }

  build() {
    const keysNoWithers = Object.keys(this).filter(key => typeof this[key] !== 'function');

    return keysNoWithers.reduce((returnValue, key) => {
      return {
        ...returnValue,
        [key]: this[key]
      }
    }, {})
  }
}

//子類1: 書籍建造者類//建造者
class BookBuilder extends BaseBuilder {
  constructor() {
    super();

    this.name = '';
    this.author = '';
    this.price = 0;
    this.category = '';
    
    super.init();
  }
}

//子類2: 印刷廠建造者類 //建造者
class printHouseBuilder extends BaseBuilder {
  constructor() {
    super();

    this.name = '';
    this.location = '';
    this.quality = '';

    super.init();
  }
}

//調用書籍建造者類
const book = new BookBuilder()
  .withName("高效能人士的七個習慣")
  .withAuthor('史蒂芬·柯維')
  .withPrice(51)
  .withCategory('勵志')
  .build();
//每次執行一個方法就是一次建造

//調用印刷廠建造類
const printHouse = new printHouseBuilder()
  .withName('新華印刷廠')
  .withLocation('北京海淀區')
  .withQuality('A')
  .build(); //建造過程
複製代碼

優勢: 一、建造者獨立,易擴展。 二、便於控制細節風險。 缺點: 一、產品必須有共同點,範圍有限制。 二、如內部變化複雜,會有不少的建造類。 使用場景: 一、須要生成的對象具備複雜的內部結構。 二、須要生成的對象內部屬性自己相互依賴。 注意事項:與工廠模式的區別是:建造者模式更加關注與零件裝配的順序。其實就是複合型工廠模式。瀏覽器

單例模式惰性加載

function createXHR(){ 
     if (typeof XMLHttpRequest != "undefined"){ 
     createXHR = function(){ 
     return new XMLHttpRequest(); 
     }; 
 } else if (typeof ActiveXObject != "undefined"){ 
     createXHR = function(){ 
     if (typeof arguments.callee.activeXString != "string"){ 
         var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", 
         "MSXML2.XMLHttp"], 
         i, len; 
         for (i=0,len=versions.length; i < len; i++){ 
             try { 
                 new ActiveXObject(versions[i]); 
                 arguments.callee.activeXString = versions[i]; 
                 break; 
             } catch (ex){ 
             //skip 
             } 
         } 
     } 
     return new ActiveXObject(arguments.callee.activeXString); 
     }; 
 } else { 
 createXHR = function(){ 
 throw new Error("No XHR object available."); 
        }; 
    } 
 return createXHR(); 
} 
這是第一段檢測代碼瀏覽器支持內置 XHR是否支持。單例模式的思想能夠爲咱們提升代碼效率減小沒必要要的重複步驟。
在這個惰性載入的 createXHR()中,if 語句的每個分支都會爲 createXHR 變量賦值,有效覆
蓋了原有的函數。最後一步即是調用新賦的函數。下一次調用 createXHR()的時候,就會直接調用被
分配的函數,這樣就不用再次執行 if 語句了。

複製代碼

期待一拳趕快更新。後半部分下次寫吧,寫累了。 參考:js高級編程,js設計模式。緩存

相關文章
相關標籤/搜索