JavaScript設計模式第一彈-建立型設計模式

前言

接下來將會爲你們介紹設計模式中的建立型設計模式,在此以前須要掌握必定的JavaScript對象繼承基礎。java

簡單工廠模式

先說說

  • 什麼是簡單工廠模式:又叫靜態工廠方法,由一個工廠對象決定建立某一種產品對象類的實例

看着定義有點懵,不要緊。繼續往下走設計模式

工廠函數

  • 說明:簡單來講,就是爲了把多個相同類型的類集成到一個函數內,咱們把這個函數叫作工廠函數
  • 用途:使得其餘人不用關注建立對象是基於哪一個基類,直接用該工廠函數便可
  • 代碼
//定義小貓類
var Cat = function(){
    this.voice = '喵';
}
Cat.prototype.getVoice = function(){
    console.log(this.voice);
}

//定義小狗類
var Dog = function(){
    this.voice = '汪';
}
Dog.prototype.getVoice = function(){
    console.log(this.voice);
}

//動物工廠
var AnimalFactory = function(name) {
    switch(name){
        case 'cat':
            return new Cat();
        case 'dog':
            return new Dog();
    }
}

//建立實例
var hellokity = AnimalFactory('cat');
hellokity.getVoice();   //'喵'

固然,上面兩種方法十分類似,因而還能夠有下面的定義方式:緩存

var createAnimal = function(name,voice) {
    var o = new Object(); 
    o.name = name;
    o.voice = voice;
    o.getVoice = function() {
        console.log(this.voice);
    }
    return o;
}
var hellokity = createAnimal('hellokity','喵');
hellokity.getVoice();   //'喵'

看似最後一種方法好像簡便很多,可是實際上這兩種定義方法是有區別的。安全

  • 第一種方式所定義的實例對象是擁有父類的方法,也就是能夠訪問到原型鏈上面的屬性和方法的。
  • 第二種方式定義則是由於在內部新建了一個對象,那麼父級對象什麼的天然也就不存在了(固然這裏不是指object)。

最後回顧

最後再次加深對簡單工廠模式的印象吧模塊化

簡單工廠模式:又叫靜態工廠方法,由一個工廠對象決定建立某一種產品對象類的實例函數

工廠方法模式

先說說

  • 什麼是工廠方法模式:經過對產品類的抽象使其建立業務主要負責用於建立多類產品的實例

懵?不要緊。繼續往下走學習

安全模式類

  • 用途:能夠屏蔽使用該類的所形成的錯誤
  • 例子
var Demo = function() {};
Demo.prototype.getName = function(){
    console.log('get success!')
}

var d = Demo();
d.getName();    //報錯

//安全模式類
var Demo = function() {
    if(!(this instanceof Demo)){
        return new Demo
    }
};
Demo.prototype.getName = function(){
    console.log('get success!')
}

var d = Demo();
d.getName();    //'get success!'

工廠方法

實際上工廠方法和簡單工廠模式區別在於:簡單工廠模式若是須要增長類的話,那麼它則須要改變兩處地方,一處是工廠函數,一處是改變類。可是若是是工廠方法模式的話,則只須要往工廠方法中添加基類則能夠。代碼實現以下:this

//安全模式建立的工廠類
var superHeroFatory = function(type,skill){
    if(this instanceof superHeroFatory){
        var s = new this[type](skill);
        return s
    }else{
        return new superHeroFatory(type,skill)
    }
}
superHeroFatory.prototype = {
    IronMan: function(skill){
        this.name = 'Iron Man';
        this.skill = skill;
        this.getName = function(){
            console.log(this.name);
        }
        this.getSkill = function(){
            console.log(this.skill);
        }
    },
    CaptainAmerica: function(skill){
        this.name = 'Captain America';
        this.skill = skill;
        this.getName = function(){
            console.log(this.name);
        }
        this.getSkill = function(){
            console.log(this.skill);
        }
    }
}

var captainAmerica = superHeroFatory('CaptainAmerica','shield');
captainAmerica.getName();   //'Captain America'
captainAmerica.getSkill();  //'shield'

最後回顧

這個工廠方法模式解決了建立多類對象所帶來的麻煩,這樣的工廠方法對象的方式也避免了使用者與對象類之間的耦合,用戶不關心建立該對象的具體類,只需調用工廠方法便可。prototype

抽象工廠模式

先說說

  • 什麼是抽象工廠模式:經過對類的工廠抽象使其業務用於對產品類簇的建立,而不負責建立其某一類產品的實例

看着定義有點懵,不要緊。繼續往下走設計

抽象類

  • 概念:抽象類是一種聲明但不能使用的類,使用就會報錯。
  • 用途:定義一個產品簇,並聲明一些必備的方法,若是子類沒有重寫就會報錯
  • 例子:在java中能夠簡單定義,可是在js中的話暫時尚未這種抽象類的定義,因而咱們能夠用這種方式模仿抽象類:
var Car = function() {};
Car.prototype = {
    getPrice(){
        return new Error('抽象方法不可用')
    },
    getName(){
        return new Error('抽象方法不可用')
    }
}

因而乎,在對象實例化後調用這些函數就會報錯。由於抽象類是沒有具體實現的,它只用做繼承的方式

抽象工廠模式

  • 說明:爲了更好的建立抽象類,因而將抽象類整合爲一個抽象工廠
  • 用途:用於建立抽象對象的一種方法
  • 定義
var VehicleFactory = function(subType,superType){
    if(typeof VehicleFactory[superType] === 'function'){
        // 緩存類
        function F() { };
        
        //繼承父類屬性和方法
        F.prototype = new VehicleFactory[superType]();
        
        //子類constructor指向子類
        subType.constructor = subType;
        
        //子類原型繼承「父類」
        subType.prototype = new F();
    }else{
        throw new Error('未建立該抽象類')
    }
}

//小汽車抽象類 
VehicleFactory.Car = function(){
    this.type = 'car';
}
VehicleFactory.Car.prototype = {
    getPrice(){
        return new Error('抽象方法不可用')
    },
    getName(){
        return new Error('抽象方法不可用')
    }
}

//大巴抽象類
VehicleFactory.Bus = function(){
    this.type = 'bus';
}
VehicleFactory.Bus.prototype = {
    getPrice(){
        return new Error('抽象方法不可用')
    },
    getName(){
        return new Error('抽象方法不可用')
    }
}

抽象類的實現

啥也別說了,直接上碼

var BMW = function(price,name){
    this.price = price;
    this.name = name;
}
VehicleFactory(BMW,'Car');
BMW.prototype.getName = function(){
    console.log(this.name);
}

var X2 = new BMW(200,'X2');
X2.getName();   //'X2'
X2.getPrice();  //報錯,由於忘記定義這個方法了

最後回顧

最後再次感覺一下定義吧

抽象工廠模式:經過對類的工廠抽象使其業務用於對產品類簇的建立,而不負責建立其某一類產品的實例

建造者模式

先說說

  • 什麼是建造者模式:將一個複雜對象的構建層與其表示層相互分離,一樣的構建過程可採用不一樣的表示

與工廠模式差異

  • 工廠模式主要是爲了建立對象實例或者類簇(抽象工廠),關心的是最終建立的是什麼,而對建立的過程並不關心
  • 建造者模式在建立對象時要更復雜,它更多的關心建立對象的過程甚至於每一個細節。或者說這種模式建立了一個複合對象

建造者模式

  • 說明:關心建立對象的過程,對於建立的具體實現的細節也參與了干涉
  • 用途:當須要咱們建立對象不只須要獲得對象實例,還需對對象細化時,則可使用建造者模式
  • 代碼
//建立類
var Human = function(props){
    this.name = props && props.name || '保密';
}
Human.prototype.getName = function(){
    console.log(this.name);
}

//名字類
var Name = function(name){
    var that = this;
    (function(name,that){
        that.wholeName = name;
        if(name.indexOf(' ') > -1){
            that.FirstName = name.slice(0,name.indexOf(' '));
            that.SecondName = name.slice(name.indexOf(' '));
        }
    })(name,that)
}


var Person = function(name){
    var _name = new Name(name);
    var _person = new Human({name:_name});
    return _person
}

var Miles = new Person('Miles Jiang');
Milse.getName();    //{wholeName: "Miles Jiang", FirstName: "Miles", SecondName: " Jiang"}

最後回顧

這種模式下,咱們就能夠關心到對象的建立過程。所以咱們一般將建立對象模塊化,這樣使得被建立的類的每一個模塊均可以得到靈活的運用和高質量的複用

單例模式

先說說

  • 什麼是單例模式:又被稱爲單體模式,是隻容許實例化一次的對象類。有時咱們也用一個對象來規劃一個命名空間,層次分明地管理對象上的屬性與方法

命名空間

  • 說明:用來約束每一個人定義的變量
  • 用途:防止共同開發時帶來的變量名衝突
  • 例子
var Miles = {
    getDom: function(id){
        return document.getElementById(id)
    }
}

最後回顧

爲了梳理代碼,使得代碼有序整潔

後話

本文章是經過學習張榮銘所著的《JavaScript設計模式》所總結。但願你們看完文章能夠學到東西,同時也推薦你們去看看這本設計模式,寫得很不錯。

成功不在一朝一夕,咱們都須要努力

相關文章
相關標籤/搜索