設計模式(二):構造器模式與模塊模式


這一篇主要講述構造器(Constructor)模式和模塊(Module)模式以及相關的變體模式,例子是JavaScript代碼。

構造器(Constructor)模式

對象構造器用於創建特定類型的對象——准備好對象以備使用,同時接收構造器可以使用的參數,以在第一次創建對象時,設置成員屬性和方法的值。概念並沒什么好說的,這種模式最是簡單,雖然名字是那么吊炸天,但內容沒什么,看下面例子就可明白。

基本構造器

function Car( model, year, miles ) {
  this.model = model;
  this.year = year;
  this.miles = miles;
  this.toString = function () {
    return this.model + " has done " + this.miles + " miles";
  };
}
// Usage:
// We can create new instances of the car
var civic = new Car( "Honda Civic", 2009, 20000 );
var mondeo = new Car( "Ford Mondeo", 2010, 5000 );
// and then open our browser console to view the
// output of the toString() method being called on
// these objects
console.log( civic.toString() );
console.log( mondeo.toString() );

PS:類與對象實例效果圖。

帶原型的構造器

function Car( model, year, miles ) {
  this.model = model;
  this.year = year;
  this.miles = miles;
}
// Note here that we are using Object.prototype.newMethod rather than
// Object.prototype so as to avoid redefining the prototype object
Car.prototype.toString = function () {
  return this.model + " has done " + this.miles + " miles";
};
// Usage:
var civic = new Car( "Honda Civic", 2009, 20000 );
var mondeo = new Car( "Ford Mondeo", 2010, 5000 );
console.log( civic.toString() );
console.log( mondeo.toString() );

PS:類與對象實例效果圖。

兩者區別

這兩個示例區別就在於toString方法的定義。前一個例子每一個實例都各自重新定義這種方法;后一個例子使用原型定義方式,使得這種方法在所有的Car實例之間共享,好處在於,共享函數能夠減少內存消耗(我認為),優化代碼。

這里需要注意幾件事:

1. 函數才有prototype屬性,指向的是一個實例對象(不是函數)。

2. 每個實例對象都有__proto__的屬性,這個屬性指向原函數所指的原型對象(原型繼承的基礎)。

模塊(Module)模式

模塊模式是為類提供私有變量和特權方法(有權訪問私有變量和私有函數的公有方法)的方法。在JavaScript,就可通過閉包的方式,模擬實現模塊模式。

對象字面量:

var myModule = {
    variableKey: variableValue,
    getKey: function () {
      // ...
    }
};

嚴格上講,對象字面量實現的只是不完整的模塊模式,因為無法達到變量、方法私有效果。不過確實有分離和組織代碼的能力,也就算一種簡略的模塊模式的實現方式。

簡單例子:

var myModule = (function(){
    var privateVar = 10;
    return {
        getPrivateVar : function(){
             return privateVar;
        }
    }
})();

引入全局變量例子:

// Global module
var myModule = (function ( jQ, _ ) {
    function privateMethod1(){
        jQ(".container").html("test");
    }
    function privateMethod2(){
      console.log( _.min([10, 5, 100, 2, 1000]) );
    }
    return{
        publicMethod: function(){
            privateMethod1();
        }
    };
// Pull in jQuery and Underscore
})( jQuery, _ );

PS:書中還有相應結合Dojo、ExtJS、YUI、jQuery等框架的模塊模式的實現方式,不過我覺得只要理解模塊模式的就行了,也不一一列例子。

揭示(Revealling)模塊模式

這種是模塊模式的改進版本,它是在模塊代碼底部,定義所有對外公布的函數(僅是指針)和變量。

var myRevealingModule = (function () {
        var privateVar = "Ben Cherry",
            publicVar = "Hey there!";
        function privateFunction() {
            console.log( "Name:" + privateVar );
        }
        function publicSetName( strName ) {
            privateVar = strName;
        }
        function publicGetName() {
            privateFunction();
        }
        // Reveal public pointers to
        // private functions and properties
        return {
            setName: publicSetName,
            greeting: publicVar,
            getName: publicGetName
        };
  })();

這種模式我經常使用,它很容易指出哪些函數和變量可以被公開訪問,增強了可讀性。

 

總結

有時我們在不經意間就使用了某種模式(例如上面兩種模式),但並不知道寫的東西已經是前人總結很好的東西了。所以在細細閱讀過程中,書中內容使得我自己對模式的認識更加系統全面,也能改正自己使用上的誤區。

 

參考文獻

1. 《Learning JavaScript Design Patterns》 by Addy Osmani

https://addyosmani.com/resources/essentialjsdesignpatterns/book/

2. 《JavaScript設計模式》by 徐濤【譯】

 

本文為原創文章,轉載請保留原出處,方便溯源,如有錯誤地方,謝謝指正。

本文地址 :http://www.cnblogs.com/lovesong/p/5572568.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM