什么是封装
封装就是把一个对象保护起来,使其只提供定义的接口方法,而保护私有的变量。打个比方,游戏中的一个人物对象,它的经验只有通过打死怪兽这个接口方法来增加。如果可以直接修改经验就会直接影响到整个游戏的设定。所以这个时候经验这个属性就是一个需要保护的变量。
封装之利
封装保护了私有属性,不用担心这些属性会被接口以外的方法以外的修改。更好的解耦。实现迪米特法则(最少知道原则)(Demeter Principle)
封装之弊
私有方法无法做单元测试,只能对共有方法做单元测试,单元测试用例的设计可能需要对共有方法的覆盖增加保证覆盖越多的私有方法。灵活性降低。对需要封装的对象做很好的理解才能实现别人调用时候需要的接口可以被获取。
闭包实现封装类
var Person = (function () {
// 静态变量
var PersonCount = 0;
// 静态方法
function checkage(age) {
var r = /^\+?[1-9][0-9]*$/; //正整数
return r.test(age);
}
return function (name, age) {
// 私有属性.
var name, age;
this.getName = function () {
return name;
}
this.getAge = function () {
return age;
}
this.setName = function (name) {
name = name || 'No Name';
};
this.setAge = function (age) {
if (!checkage(age)) throw new Error('年龄不是一个正整数');
age = age;
}
PersonCount++;
if (PersonCount > 50) throw new Error('一个只能创建50个人');
this.setName(name);
this.setAge(age);
}
})();
//测试静态变量
/*
var Persons = [];
for (var i = 0; i < 51; i++) {
Persons[i] = new Person(i, i + 1);
console.log('name:' + Persons[i].getName() + 'age:' + Persons[i].getName());
}
//*/
//测试封装效果
/*
var Test = new Person("111", "1");
console.log(Test.name);
//*/
//测试静态函数checkage
//var TestAge =new Person("111","asd");
主要参考《javascript设计模式》的例子
总结
可以看到这样实现了封装效果。不过对于私有函数的测试。只能通过测试接口的用例囊括才能实现。对于测试的要求可能就变高了。