• 构建大型程序最大的秘密


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

  • 相关阅读:
    解决使用intellij idea开发MAVEN项目在target目录下不存在mapper.xml文件
    Mybatis中接口和对应的mapper文件位置配置详解
    Mybatis(1、核心配置文件、Properties、Settings、typeAliases...)
    nginx的常用负载均衡算法,分别是
    修改JVM的参数、Jstat、Jstack、gclog
    shiro 系列
    sso简单原理及实现
    Thymeleaf3.0内容
    Thymeleaf模板引擎+Spring整合使用方式的介绍
    给 IIS Express 配置虚拟目录
  • 原文地址:https://www.cnblogs.com/sntetwt/p/3234030.html
Copyright © 2020-2023  润新知