javascript設計模式–封裝和資訊隱藏(下)

來源:互聯網
上載者:User

  今天講解的內容是進階模式(Advanced Patterns),如何?靜態方法和屬性,常量還有其他一些知識點。

  1.靜態方法和屬性

  其實要實現這一功能還是要藉助於閉包。在上一講中的第三種實現方式也使用了閉包,但通過那種實現,內部屬性和方法是執行個體層級的。

var book1=new Book('isbn1','title1','author1');var book2=new Book('isbn2','title2','author2');

alert(book1.getTitle()); //輸出title1
alert(book2.getTitle()); //輸出title2

  通過上面的例子可以看出,建立的book1和book2有獨立的私人屬性,對book2的私人屬性賦值不會影響到book1。

  那麼怎麼才能實作類別層級的私人屬性和方法呢,這裡除了需要使用閉包之外,還需要使用到匿名函數。代碼如下:代碼1

var Book = (function() {  // Private static attributes.  var numOfBooks = 0;  // Private static method.  function checkIsbn(isbn) {    ...  }
  // Return the constructor.  return function(newIsbn, newTitle, newAuthor) { // implements Publication    // Private attributes.    var isbn, title, author;    // Privileged methods.    this.getIsbn = function() {      return isbn;    };    this.setIsbn = function(newIsbn) {      if(!checkIsbn(newIsbn)) throw new Error('Book: Invalid ISBN.');      isbn = newIsbn;    };    this.getTitle = function() {      return title;    };    this.setTitle = function(newTitle) {      title = newTitle || 'No title specified';    };    this.getAuthor = function() {      return author;    };    this.setAuthor = function(newAuthor) {      author = newAuthor || 'No author specified';    };    this.getNumOfBooks = function(){
      return numOfBooks;
    };

    // Constructor code.    numOfBooks++; // Keep track of how many Books have been instantiated    // with the private static attribute.    if(numOfBooks > 50) throw new Error('Book: Only 50 instances of Book can be '                        + 'created.');    this.setIsbn(newIsbn);    this.setTitle(newTitle);    this.setAuthor(newAuthor);  }})();
// Public static method.Book.convertToTitleCase = function(inputString) {  ...};
// Public, non-privileged methods.Book.prototype = {  display: function() {    ...  }};

  對匿名函數不瞭解的同學可以自己去查閱相關資料。其實上面的代碼等價於:代碼2

var tempBook = function() {  // Private static attributes.  var numOfBooks = 0;  // Private static method.  function checkIsbn(isbn) {    ...  }   // Return the constructor.  return function(newIsbn, newTitle, newAuthor) { // implements Publication    ...
  }};
var Book = tempBook();

// Public static method.Book.convertToTitleCase = function(inputString) {  ...}; // Public, non-privileged methods.Book.prototype = {  display: function() {    ...  }};

  那麼如果再執行之前的代碼會有什麼效果呢:

var book1=new Book('isbn1','title1','author1');var book2=new Book('isbn2','title2','author2'); 
alert(book1.getNumOfBooks()); //輸出 2
alert(book2.getNumOfBooks()); //輸出 2

  為什麼會有這樣的效果呢,其實通過匿名函數加閉包這種組合模式,numOfBooks已經是真正意義上的私人靜態變數的,無論你建立多少個Book的執行個體,系統中也只有一個numOfBooks變數。有人或許疑問,為什麼每建立一個新的Book執行個體的時候,沒有多產生一個numOfBooks呢?

  我們從代碼2上可以找到答案,其實我們建立的Book執行個體是執行了tempBook()方法,而不是new tempBook對象!tempBook對象在系統中只會運行一次,所以他內部的numOfBooks變數也就只有一份。每次執行new Book(‘...’,‘...’,‘...’);的時候,其實只是執行了tempBook中的function(newIsbn, newTitle, newAuthor),並沒有建立新的tempBook對象,所有Book執行個體在使用getNumOfBooks方法時調用到的都是同一個numOfBooks。

  不知道我的講解是否清楚,希望對大家有協助。

 

  2.常量

   其實這部分還真沒什麼好講的,只要你理解了上面的內容,在匿名函數內部實現一個類似於numOfBooks的變數,在整個初始化過程不對他進行修改,也不提供任何修改的方法,同時提供一個類似於getNumOfBooks方法供外部存取它,就ok了,代碼我就懶的寫了。

 

  3.使用封裝的好處和弊端

  好處:

  可以實現對代碼的控制,公布想公開的隱藏不想公開的資訊。同時也方便你重構代碼,你建立的對象的使用者不會因為你修改內部對象(私人的變數或者方法)而影響別人正常的使用。面相介面編程可以實現代碼之間的松耦合。

  弊端:

  1.測試內部變數很困難,最好的辦法是通過測試公用方法實現對內部方法的測試。

  2.因為複雜的範圍導致代碼調試變的很困難。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.