构建大型程序最大的秘密
这次我们提议的架构使用了我们都很熟知的设计模式:module, facade和mediator。
Module模式
1、module模式是一个比较流行的设计模式,它可以通过大括号封装私有的变量、方法、状态等,通过包装这些内容,一般全局的对象不能直接访问,在这个设计模式里,只返回一个API,其它的内容全部被封装成私有;
2、这个模式和自执行的函数表达式比较相似,唯一不同的是module模式返回的是对象,而自执行函数返回的是function;
3、javascript没有声明private、public修饰符,我们可以通过return语句返回我们要公共的方法,达到public效果,而其它的为private;
示例:统计对象
需求:一个超市有多种产品,现在要求统计多种产品的价格
思想:把超市里的每一种产品作为一个对象,产品有名称、价格,如:{item:'桔子',price:0.5}
-->
<script type="text/javascript">
var md = (function() { //return的对象直接赋值给了md
var ar = []; //private
return { //public
add: function(values) {
ar.push(values);
},
count: function() { //有多少个对象
return ar.length;
},
total: function(){ //统计价格
var q = this.count(),p=0;//this为md对象的构造函数,this.constructor == md.constructor
while(q--){
p+= ar[q].price;
}
return p;
}
}
}());
//把对象添加到数组里
md.add({item:'桔子',price:0.5});
md.add({item:'苹果',price:2.0});
alert("种类:" + md.count()); //种类:2
alert("总价:" + md.total()); //总价:2.5
</script>
<!--
Module模式,工厂风格
标题:一个library函数声明了一个新的library对象
-->
<script type="text/javascript">
function library(module) {
(function() {
if (module.init) {
module.init(); //init()已被执行
}
})();
return module;
}
var lib = library(function() {
return {
init: function() {
alert('init');
},
msg:function(s){
return s;
}
};
}());
alert(lib.msg('msg')); //调用执行,结果:msg
<!--
Facade模式
定义:Facade(外观)模式为子系统中的各类(或结构与方法)提供一个简明一致的界面,隐藏子系统的复杂性,使子系统更加容易使用。
遇到以下情况使用Facade模式:
1、当你要为一个复杂子系统提供一个简单接口时。
2、客户程序与抽象类的实现部分之间存在着很大的依赖性。
3、当你需要构建一个层次结构的子系统时,使用Facade模式定义子系统中每层的入口点,如果子系统之间是相互依赖的,你可以让它们仅通过Facade进行通讯,从而简化了它们之间的依赖关系。
实例:下面这个例子了,可以看到我们提供了很多私有的方法,然后通过暴露一个简单的 API来让外界执行调用内部的方法
-->
<script type="text/javascript">
var module = (function () {
var _private = {
i: 5,
get: function () {
alert('current value:' + this.i);
},
set: function (val) {
this.i = val;
},
run: function () {
alert('running');
},
jump: function () {
alert('jumping');
}
};
return {
facade: function (args) {
_private.set(args.val);
_private.get();
if (args.run) {
_private.run();
}
}
}
} ());
module.facade({run:true, val:10});//结果:outputs current value: 10, running
</script>
<!--
Mediator模式
定义:Mediator(中介者)模式为用一个中介对象来封装一系列关于对象交互行为。
遇到以下情况使用Mediator模式:
各个对象之间的交互操作非常多;每个对象的行为操作都依赖彼此对方,修改一个对象的行为,同时会涉及到修改很多其他对象的行为,如果使用Mediator模式,可以使各个对象间的耦合松散,只需关心和 Mediator的关系,使多对多的关系变成了一对多的关系,可以降低系统的复杂性,提高可修改扩展性.
-->
<script type="text/javascript">
var mediator = (function(){ //定义mediator接口,用来定义成员对象之间的交互联系方式:
var subscribe = function(channel, fn){ //订阅行为
if (!mediator.channels[channel]) mediator.channels[channel] = [];
mediator.channels[channel].push({ context: this, callback: fn });
return this;
},
publish = function(channel){ //公布行为
if (!mediator.channels[channel]) return false;
var args = Array.prototype.slice.call(arguments, 1);
for (var i = 0, l = mediator.channels[channel].length; i < l; i++) {
var subscription = mediator.channels[channel][i];
subscription.callback.apply(subscription.context, args);
}
return this;
};
return { //返回对象
channels: {},
publish: publish,
subscribe: subscribe,
installTo: function(obj){ //安装行为
obj.subscribe = subscribe;
obj.publish = publish;
}
};
}());
//1、向中介者订阅行为
mediator.name = "tim";
mediator.subscribe('nameChange', function(arg){
console.log(this.name);
this.name = arg;
console.log(this.name);
});
//2、让中介者发布行为
mediator.publish('nameChange', 'david'); //tim, david
//3、安装行为
var obj = { name: 'sam' };
mediator.installTo(obj);
obj.subscribe('nameChange', function(arg){
console.log(this.name);
this.name = arg;
alert(this.name);
});
obj.publish('nameChange', 'john'); //sam, john
</script>
总结:
1、mediator只有在facade授权检测以后才能进行信息处理。
2、各个模块之间联系的越密切,重用性越小,改变起来困难越大。
3、构建大型程序最大的秘密就是从来不构建大型程序,而是将程序分解成各个小的模块去做,让每个小模块都可测试,可size化,然后集成到程序里。
4、一切皆可变,所以要抽象。
"唯有高屋建瓴,方可水到渠成"

浙公网安备 33010602011771号