大型JavaScript应用程序架构模式(1)(3)
对象自面量
对象自面量使用大括号声明,并且使用的时候不需要使用new关键字,如果对一个模块里的属性字段的publice/private不是很在意的话,可以使用这种方式,不过请注意这种方式和JSON的不同。对象自面量:var item={name: "tom", value:123} JSON:var item={"name":"tom", "value":123}。
- var myModule = {
- myProperty: 'someValue',
- //object literals can contain properties and methods.
- //here, another object is defined for configuration
- //purposes:
- myConfig: {
- useCaching: true,
- language: 'en'
- },
- //a very basic method
- myMethod: function () {
- console.log('I can haz functionality?');
- },
- //output a value based on current configuration
- myMethod2: function () {
- console.log('Caching is:' + (this.myConfig.useCaching) ? 'enabled' : 'disabled');
- },
- //override the current configuration
- myMethod3: function (newConfig) {
- if (typeof newConfig == 'object') {
- this.myConfig = newConfig;
- console.log(this.myConfig.language);
- }
- }
- };
- myModule.myMethod(); //I can haz functionality
- myModule.myMethod2(); //outputs enabled
- myModule.myMethod3({ language: 'fr', useCaching: false }); //fr
CommonJS
关于 CommonJS的介绍,这里就不多说了,博客园有很多帖子都有介绍,我们这里要提一下的是CommonJS标准里里有2个重要的参数exports和require,exports是代表要加载的模块,require是代表这些加载的模块需要依赖其它的模块,也需要将它加载进来。
- /*
- Example of achieving compatibility with AMD and standard CommonJS by putting boilerplate around the standard CommonJS module format:
- */
- (function(define){
- define(function(require,exports){
- // module contents
- var dep1 = require("dep1");
- exports.someExportedFunction = function(){...};
- //...
- });
- })(typeof define=="function"?define:function(factory){factory(require,exports)});
有很多CommonJS标准的模块加载实现,我比较喜欢的是RequireJS,它能否非常好的加载模块以及相关的依赖模块,来一个简单的例子,例如需要将图片转化成ASCII码,我们先加载encoder模块,然后获取他的encodeToASCII方法,理论上代码应该是如下:
- var encodeToASCII = require("encoder").encodeToASCII;
- exports.encodeSomeSource = function(){
- //其它操作以后,然后调用encodeToASCII
- }
但是上述代码并没用工作,因为encodeToASCII函数并没用附加到window对象上,所以不能使用,改进以后的代码需要这样才行:
- define(function(require, exports, module) {
- var encodeToASCII = require("encoder").encodeToASCII;
- exports.encodeSomeSource = function(){
- //process then call encodeToASCII
- }
- });
CommonJS 潜力很大,但是由于大叔不太熟,所以就不过多地介绍了。
Facade模式
Facade模式在本文架构里占有重要角色,关于这个模式很多JavaScript类库或者框架里都有体现,其中最大的作用,就是包括High level的API,以此来隐藏具体的实现,这就是说,我们只暴露接口,内部的实现我们可以自己做主,也意味着内部实现的代码可以很容易的修改和更新,比如今天你是用jQuery来实现的,明天又想换YUI了,这就非常方便了。
下面这个例子了,可以看到我们提供了很多私有的方法,然后通过暴露一个简单的 API来让外界执行调用内部的方法:
- var module = (function () {
- var _private = {
- i: 5,
- get: function () {
- console.log('current value:' + this.i);
- },
- set: function (val) {
- this.i = val;
- },
- run: function () {
- console.log('running');
- },
- jump: function () {
- console.log('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
Facade和下面我们所说的mediator的区别是,facade只提供现有存在的功能,而mediator可以增加新功能。






