构建大型程序最大的秘密

这次我们提议的架构使用了我们都很熟知的设计模式: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、一切皆可变,所以要抽象。

posted @ 2013-08-02 23:41  microsoftzhcn  阅读(277)  评论(0编辑  收藏  举报