javascript设计模式--封装和信息隐藏(下)

  今天讲解的内容是高级模式(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.因为复杂的作用域导致代码调试变的很困难。

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值