1.信息隐藏原则
1.1封装与信息隐藏
信息隐藏是目的,而封装则是藉以达到这个目的的技术。封装可以被定义为对对象的内部数据表现形式和实现细节进行隐藏。
1.2接口扮演的角色
接口提供了一份记载着可供公众访问的方法的契约。它定义了两个对象间可以具有的关系。只要接口不变,这个关系的双方都是可以替换的。但不是有了接口就万事大吉了,应该避免公开未定义于接口中的方法。否则其它对象可能对那些并不属于接口的方法产生依赖,而这是不安全的。因为这些方法随时都可能发生改变或被删除,从而对到整个系统失灵。一个理想的软件系统应该为所有类定义接口。这些类只向外界提供它们实现的接口中规定的方法,任何别的方法都留作自用。其所有属性都是私用的,外界只有通过接口中定义的存取操作与之打交道。
1.3创建对象的基本模式
1.3.1门户大开型
是最简单的,但它只能提供公用成员,所有属性和方法都是公开的、可访问的。这些公用属性需要用this关键字来创建.
1.3.2用命名规范区别私用成员
从本质上说这种模式与门户大开型对象创建模式如出一辙,只不过在一些方法和属性的名称前加了下划线以示其私用性而已。
这种创建对象的模式具有门户大开型对象创建模式的所有优点,而且比后者少了一个缺点。但是,它只是一种约定,只有在遵守时才有效果,而且并没有什么强制性手段可以保证这一点。所以它并不是真正可以用来隐藏对象内部数据的解决方案。它主要适用于非敏感性的内部方法和属性,也即,那些因为未见于公开的接口,所以类的大多数使用者都不会关心的方法和属性。
1.3.3作用域、嵌套函数和闭包
在JavaScript中,只有函数具有作用域。也就是说,在一个函数内部声明的变量在函数外部无法访问。私用属性就其本质而言就是希望在对象外部无法访问的变量所以为实现这种拒访性而求救于作用域是合乎情理的。定义在一个函数中的变量在该函数的内嵌函数中是可以访问的。
1.3.4用闭包实现私用成员
1.3.5更多高级对象创建模式
1.3.5.1静态方法和属性
大多数方法和属性所关联的是类的实例,而静态成员扬关联的则是类本身。换句话说,静态成员是丰类的的层次上操作,而不是在实例的层次上操作。每个静态成员只有一份。静态成员是直接通过类对象访问的。
添加了静态属性和方法的Book类:
varPublication = new Interface('Publication', ['getIsbn','setIsbn', 'getTitle','setTitle', 'getAuthor', 'setAuthor', 'display']);
var Book =(function(){
//静态私有属性
varnumOfBooks = 0;
//静态私有方法
function checkIsbn(isbn){
...
}
//返回构造函数
return function(newIsbn, newTitle,newAuthor){//implements Publication
//私有属性
var isbn, title, author;
//特权方法
this.getIsbn= function(){
return isbn;
};
this.setIsbn= function(){
if(!checkIsbn(newIsbn))throw newError("Book: invalid ISBN.");
isbn= newIsbn;
};
this.getTitle= function(){
return title;
};
this.setTitle= function(newTitle){
title= newTitle || 'No titlespecified';
};
this.getAuthor= function(){
return author;
};
this.setAuthor= function(newAuthor){
author= newAuthor || 'No authorspecified';
};
numOfBooks++; //追踪有多少对象被实例化,即多少本书
//使用静态私有属性
if(numOfBooks> 50) throw newError("Book: Only 50 instance of Book can becreated.");
this.setIsbn(newIsbn);
this.setAuthor(newAuthor);
this.setTitle(newTitle);
}
})();
//Book的公开的静态方法,因为它是作为Book的一个属性,而不是在Book函数中定义的,不作为构造函数中的部分返回
Book.convertToTitleCase= function(inputString){
...
};
//公开的非特权方法
Book.prototype= {
display:function(){
...
}
};
//Book(isbn,title, author)
vartheHobbit = new Book('0-395-07122-4', 'the hobbit', 'J.R.R.Tolkien');
theHobbit.display();
1.3.5.2常量
//常量取值器方法
varClass = (function(){
//私有静态属性
var constants = {
UPPER_BOUND: 100,
LOWER_BOUND: -100;
}
//构造器
var ctor =function(constructor Argument){
...
};
//静态的特权方法
ctor.getConstant=function(name){
return constants[name];
};
...
//返回构造器
return ctor;
})();