代理模式2 + 策略模式

代理模式.png

虚拟代理的一个应用
图片预加载,懒加载案例
步骤一

          <div id="app">
           
         </div>
         <button id="btn">click</button>

 var urlYu = './img/1.jpg';
            var urlLan = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1539590544679&di=f745d562e74a73cac45777318fa2f1b1&imgtype=0&src=http%3A%2F%2Fpic22.nipic.com%2F20120621%2F1628220_155636709122_2.jpg';
            
            function MyImg (id) {
                var myImg = new Image();
                this.setSrc = function (src) {
                    myImg.src = src;
                }
                document.getElementById(id).appendChild(myImg);
            }
            
            function ProxyImage (src) {
                var oImg = new Image();
                var oMyImage = new MyImg('app');
                oMyImage.setSrc(urlYu);
                oImg.onload = function () {
                    oMyImage.setSrc(oImg.src);
                }
                oImg.src = src;
            }
            
            btn.onclick = function () {
                ProxyImage(urlLan);
            }

步骤二

<script type="text/javascript">
            var urlYu = './img/1.jpg';
            var urlLan = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1539590544679&di=f745d562e74a73cac45777318fa2f1b1&imgtype=0&src=http%3A%2F%2Fpic22.nipic.com%2F20120621%2F1628220_155636709122_2.jpg';
            
            function MyImg (id) {
                var myImg = new Image();
                this.setSrc = function (src) {
                    myImg.src = src;
                }
                document.getElementById(id).appendChild(myImg);
            }
            
            var ProxyImage = (function () {// 通过闭包,可以免去重复占用一些资源.
              var oImg = new Image();
              var oMyImage = new MyImg('app');
              oImg.onload = function () {
                setTimeout(function () {
                  oMyImage.setSrc(oImg.src);
                },1000);
              }
              return function (occupySrc,src) {
                oImg.src = src;
                oMyImage.setSrc(urlYu);
              }
            })();
            
            btn.onclick = function () {
                ProxyImage(urlLan);
            }
            
        </script>

步骤1 基本功能实现 : 点击改变样式

 var oDiv = document.getElementById('show');
            var oButtonArray = document.getElementsByTagName('button');
            for(var i = 0;i < oButtonArray.length; i++) {
              oButtonArray[i].onclick = function () {
                changeStyle(oDiv,this.getAttribute('type'));
              }
            }
            
            
            //
            function changeStyle (dom,type) {
                var typeObj = {
                  bg: ['backgroundColor','green'],
                  cl : ['color','blue'],
                  fs : ['fontSize', '24px'],
                  fw : ['fontWeight', 'bold'],
                  op : ['opacity', '0.3']
                }
                dom.style[typeObj[type][0]] = typeObj[type][1];
            }

步骤二 能够接收数组, 有了合并能力

 function changeStyle (dom,typeArr) {
                var typeObj = {
                  bg: ['backgroundColor','green'],
                  cl : ['color','blue'],
                  fs : ['fontSize', '24px'],
                  fw : ['fontWeight', 'bold'],
                  op : ['opacity', '0.3']
                }
                if (typeArr.constructor == Array) {// 对应情况 changeStyle(dom,['bg','cl'])
// 也就是合并功能的实现?
                    typeArr.forEach(function (item) {
                        dom.style[typeObj[item][0]] = typeObj[item][1];
                    })
                } else{// 对应的情况 changeStyle(dom,'bg')
                  dom.style[typeObj[typeArr][0]] = typeObj[typeArr][1];
                }
                
            }

步骤三

<script type="text/javascript">
            function ProxyRequest (callback) {
                var cache = [];
                var timer = null;
                return function () {
                    cache.push(this.getAttribute('type'));
                    clearTimeout(timer);
                    timer = setTimeout(function () {
                        callback(oDiv,cache);
                        cache = [];
                    },2000);
                }
            }
            var realChangeStyle = ProxyRequest(changeStyle);
          
          
            //
            var oDiv = document.getElementById('show');
            var oButtonArray = document.getElementsByTagName('button');
            for(var i = 0;i < oButtonArray.length; i++) {
              oButtonArray[i].onclick = realChangeStyle;
            }
            
            
            
            //
            function changeStyle (dom,typeArr) {
                var typeObj = {
                  bg: ['backgroundColor','green'],
                  cl : ['color','blue'],
                  fs : ['fontSize', '24px'],
                  fw : ['fontWeight', 'bold'],
                  op : ['opacity', '0.3']
                }
                if (typeArr.constructor == Array) {
                    typeArr.forEach(function (item) {
                        dom.style[typeObj[item][0]] = typeObj[item][1];
                    })
                } else{
                  dom.style[typeObj[typeArr][0]] = typeObj[typeArr][1];
                }
                
            }
            
//          changeStyle(oDiv,['bg','op','fw']);
            //
            
        </script>

这段代码的思想可以套用在ajax请求的整合,
可以套用在上传多个文件.

跟我自己写的相比, 这个延时,积累的是状态,是数据.
比较妙的地方是, 参数接口,改成了数组.应该说兼容了数组.
这个参数接口的设置,很妙.


保护代理/安全代理


image.png

表单验证案例
第一版,菜鸟版

           <div>
           用户名 : <input type="text" name="username" id="username" value="" />
           <span id="showUser">
            
           </span>
           密码: <input type="password" name="code" id="psDom" value="" />
           <span id="showCode">
            
           </span>
           <button id="submit">提交</button>
         </div>
        <script type="text/javascript">
            var userDom = document.getElementById('username');
            var psDom = document.getElementById('psDom');
            // 用户名长度 不能超过4个
            // 密码不能为空, 且长度不能小于6
            // 先假定 数据是可以发送成功的
            var flag = true;
            submit.onclick = function () {
              showUser.innerText = '';
              showCode.innerText = '';
              if(userDom.value == '') {
                flag = false;
                showUser.innerText = '用户名不能为空';
              }else if (userDom.value.length >= 4) {
                flag = false;
                showUser.innerText = "长度不得超过4";
              }
              
              if (psDom.value == '') {
                flag = false;
                showCode.innerText = "密码不能为空";
              }else if (psDom.value.length <= 6) {
                flag = false;
                showCode.innerText = "长度不得小于6";
              }
              
                if (flag) {
                    // 发送网络请求 
                    Request();
                }
            }
            function Request () {
                
            }
            
        </script>

缺陷


image.png

配合策略模式


什么是策略模式

策略模式优点

特点说明

看情况而用

第二版 策略模式版

<!DOCTYPE html>
<html>

  <head>
    <meta charset="UTF-8">
    <meta name="viewprot" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>dddd</title>
    <style type="text/css">
      span {
        color: red;
      }
      
      ;
    </style>
  </head>

  <body>
    <div>
      用户名 : <input type="text" name="username" id="username" value="" /><br />
      <span id="showUser"></span><br />
                  密码: <input type="password" name="code" id="psDom" value="" /><br />
      <span id="showCode"></span><br />
      邮箱:<input type="text" name="mail" id="mail" value="" /><br />
      <span id="showMail"></span><br />
      <button id="submit">提交</button>
    </div>
    <script type="text/javascript">
      var userDom = document.getElementById('username');
      var psDom = document.getElementById('psDom');
      var mailDom = document.getElementById('mail');
      // 代理模式 和 策略模式 结合一下

      // C 是代理, 进行控制
      // A = C = B
      function Request() {
        console.log('send');
      }

      // 构造函数 => 对象实例 // 策略模式思想的体现.
      function Validator() {
        //数据尽量存放在实例上,
        //方法尽量存放在原型上,
        this.cache = []; // 用来存放规则?
        this.warnDom = [];
      }
      Validator.prototype.strategies = { // 策略模式 管理了一堆算法
        isNonEmpty: function(value, errorMsg) {
          if(value == '') {
            return errorMsg
          }
          return true;
        },
        maxLength: function(value, length, errorMsg) {
          if(value != '' && value.length > length) {
            return errorMsg;
          }
          return true;
        },
        minLength: function(value, length, errorMsg) {
          if(value != "" && value.length < length) {
            return errorMsg;
          }
          return true;
        }
      }
      Validator.prototype.add = function(dom, showDom, strategyArr) {
        var self = this;
        self.warnDom.push(showDom);
        strategyArr.forEach(function(ele, index) {
          self.cache.push(function() {
            // arr => ['isNonEmpy']['maxLength','4']; 让字符串变成了数组.
            var arr = ele.strategy.split(':');
            // arr => [];['4']
            // type => isNonEmpy maxLength;
            var type = arr.shift();
            //[dom.value] [dom.value,'4'];
            arr.unshift(dom.value);
            // [dom.value,errorMsg] [dom.value,'4',errorMsg]
            arr.push(ele.errorMsg);

            //self.strategies[type](dom.value,ele.errorMsg);
            var msg = self.strategies[type].apply(dom, arr);

            if(msg != true) {
              showDom.innerText = msg;
            }

            return msg;
          })
        })
      }
      Validator.prototype.start = function() {
        // 标记最后是否能符合规则
        var flag = true;
        this.warnDom.forEach(function(ele) {
          ele.innerText = '';
        })
        this.cache.forEach(function(ele, index) {
          if(ele() !== true) {
            flag = false;
          }
        });
        return flag;
      }
      // add 添加校验规则 (dom,showDom,[{strategy:'isNonEmpty',errorMsg:'用户名不为空'},{strategy: 'maxLength:4',errorMsg:'用户名长度不能超过4'}])
      // start 开始校验并返回真正的校验结果 
      // extend 可以扩展 算法
      
      
      Validator.prototype.extend = function(config) {
        for(var prop in config){
          Validator.prototype.strategies[prop] = config[prop];
        }
      }
      
      
      var validator = new Validator();
        
        validator.extend({
          isEmail : function (value, errorMsg) {
            if (value != '' && value.indexOf('@') == -1) {
                return errorMsg
            }
            return true;
          },
          isPhone : function (value,errorMsg) {
            if (value != '' && value.length !== 11) {
                return errorMsg
            }
            return true;
          }
        });
        
      //代理
      var ProxyRequest = (function() {
        // 添加规则
        // 参数1.校验内容dom 2.错误信息显示dom 3.检验规则
        validator.add(userDom, showUser, [{
          strategy: 'isNonEmpty',
          errorMsg: '用户名不能为空'
        }, {
          strategy: 'maxLength:4',
          errorMsg: '用户名长度不能超过4'
        }]);
        validator.add(psDom, showCode, [{
          strategy: 'isNonEmpty',
          errorMsg: '密码名不能为空'
        }, {
          strategy: 'minLength:6',
          errorMsg: '密码长度不能少于6'
        }]);
        validator.add(mailDom, showMail, [{
          strategy: 'isNonEmpty',
          errorMsg: '密码名不能为空'
        }, {
          strategy: 'isEmail',
          errorMsg: '请输入正确的邮箱格式'
        }]);
        return function() {
          if(validator.start()) {
            Request();
          };
        }
      })();

      submit.onclick = ProxyRequest;
    </script>
  </body>

</html>

从第一版到第二版,看起来跨越还是挺大的.
这个要怎么消化呢?

首先,有value,这个value 可能来自不同的dom,input
其次,需要针对这个value的校验规则,规则会返回 数据,(可能是布尔值)
再次,可能针对这个value 需要有多个 校验规则,
继续次, 根据每个规则的校验结果,需要执行不同的操作,(展现不同的错误信息?)

关键是用一个对象来实现上面的东西?
strategies = [] 用来存放规则
extend() 用来扩展添加规则.
cache = [] 这里存放要执行的函数. 执行列表?
add() 用来选择触发哪条规则,同时传参. 把要执行的函数放进cache
start() 用来执行cache , 执行列表里的函数.

针对上面刚刚写的,我们再思考一下.
你看到了, 上面实际上没有提到什么 dom,input, value, 规则校验
等等等等.
实际上上面的这个模型,这个结构,讲得是什么?

先定义一组核心函数, 这些函数用于复用,
放进数组,用于扩展.

然后调用时,传参的同时,选择函数,但不马上执行,(当然也可以马上执行)
形成待执行的函数(此时已经配好了参数),放进执行列表.

最后根据某种触发,一并执行.

哇塞.. 这个结构,, 这个策略模式,,很精彩啊..
我之前的思路是,
定义函数, 函数寻找数据,寻找参数.
或者是
得到了数据,根据数据的流向,找到或者定义需要的函数.

而这里的思路,打破脑洞的地方在于,
感觉,核心函数和数据,都是参数.组合到一起,
形成要执行的函数.

感觉,已经把相同的话,重复说了三次....

此时,我有点感觉,这些个设计模式确实挺牛逼的.

要从某种更高的角度,把结构抽象出来.
没错,我相信,任何设计模式,都必然有某种核心结构支撑,

下面是一个叫动脑学院的公开课上的表单验证插件封装.
基于jq,bootstrap.
当时觉得挺难的,把源码留了下来,今天看的时候,基本就能消化了,
很多地方的精彩虽然还无法完全消化,
但确实有很多精彩的套路.
▪html

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title>practice</title>
        <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
        
        <style type="text/css">
            html,body {
                margin: 0;
                padding: 0;
                background-color: #eee;
            }
            .login-region{
                width: 40%;
                height: auto;
                margin: 50px auto;
                background-color: #fff;
                padding: 20px;
                border: 1px solid #bbb;
            }
        </style>
        
    </head>

    <body>
        <!--
            //页面 (bootstrap)
            //设计表单校验插件
            //实现
            //重构
        -->
        
        <!--
            有些是刚需 , 有些 不是 , 基础的核心的需求框架 必须完成 我们在标签中 属性中用 require 标记
            
            require 必须填写
            number  必须是数字
            integer 必须是整数
            email   填写的内容必须是标准的email邮箱格式
            url     必须是合法的URL(统一资源定位符)
            regex   必须符合正则表达式配置的格式
            length  必须是多少位.
            ...     理论上无限.
            
            不是刚需的,考虑留个接口,用扩展性解决
            cardid  必须是身份证
            mobile  必须是合法的手机
        -->
        <!--
            
            
        -->
        
        <form class="form-horizontal login-region" autocomplete="off">
            <div class="form-group">
                <label for="inputEmail3" class="col-sm-2 control-label">Email</label>
                <div class="col-sm-10">
                    <!--必须填写  必须符合邮箱地址的规范.-->
                    <input type="text" class="form-control" id="inputEmail3" placeholder="Email" 
                        data-bv-require="true" 
                        data-bv-require-message="* 邮箱地址为必填项" 
                        data-bv-email-message="* 邮箱地址不合法" 
                        data-bv-email="email">
                </div>
            </div>
            <div class="form-group">
                <label for="inputPassword3" class="col-sm-2 control-label">Password</label>
                <div class="col-sm-10">
                    <!--有字母数字下划线组成 6-12位-->
                    <input type="password" class="form-control" id="inputPassword3" placeholder="Password" 
                        data-bv-require="true" 
                        data-bv-require-message="* 密码必须填入" 
                        data-bv-regex-message="* 密码由 数字 字母 下划线组成 的 6-12位" 
                        data-bv-regex="^\w{6,12}$">
                </div>
            </div>
            <!--可以不填写 如果填写必须由一个以上的字母组成-->
            <div class="form-group">
                <label for="inputNickName" class="col-sm-2 control-label">NickName</label>
                <div class="col-sm-10">
                    <!--有字母数字下划线组成 6-12位-->
                    <input type="text" class="form-control" id="inputNickName" placeholder="Password" require="true" data-bootstrapValidate-regex="^\w{6,12}$">
                </div>
            </div>
            <div class="form-group">
                <label for="inputCardId" class="col-sm-2 control-label">NickName</label>
                <div class="col-sm-10">
                    <!--有字母数字下划线组成 6-12位-->
                    <input type="text" class="form-control" id="inputCardId" placeholder="身份证" 
                        data-bv-require="true" 
                        data-bv-require-message="*必填选项" 
                        data-bv-cardid-message="*身份证号码不合法"
                        data-bv-cardid="true">
                </div>
            </div>
            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                    <button type="submit" class="btn btn-default">Sign in</button>
                </div>
            </div>
        </form>
        <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
        <script src="js/plug/bootstrap-valiator/bv.1.0.1.js" type="text/javascript" charset="utf-8"></script>
        <script src="js/common.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            $(".login-region").bootstrapValidate({//这个参数是更改默认事件
                raise: "keyup",//设置触发的事件
//              lang : 'zh'
            }).extendRules({//打开选中表单的 校验功能.//放在 common.js就可以让整个项目都可以用了
                "cardid" : function () {//这个入口是更改 或者增加 新的规则.
                    console.log('身份证被校验');
                    return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(this.val());
                }
            });;
            
            //从目前来看,参数入口有三个,第一个是在标签里添加属性. 可以给不同表单设置不同规则的参数
            //第二个是,默认配置项,也就是主要的可以更改的入口.这个原则是,会有默认的选项,如果不配置,则用默认的,如果配置则用配置的覆盖掉默认的,
            //用extend 两次添加到 DOM 包装对象 实在太漂亮了.
            //第三个是 增加新的规则, 也就是引擎的扩展.
            
            //选插件?
            //自己写?
            //架构师. 架构思维,全局思维. 我写的这个东西,未来会有很多人用. 所有人都将用我的
            //移植性, 维护性, 稳定性, 扩展性
            //需要敢想,,
            //1.所有 jQ + BS 的架构的项目都会用我们的 框架
            //2.VALIDATE有什么共性的问题 (幻想如果我是用户,我希望怎么尽量简单的用它?)
            //3.重构增强扩展性和维护性 (方法: 把硬编码 变成 软编码);
            
            //自定义属性有一套命名规则 data-插件的名字 (缩写 bv) + 属性名
            
            //不要强奸用户, 只要遇到没有把握 知道用户喜好的时候,第一给默认值,(满足大部分用户),然后给 配置
            // 给配置  好的框架是 能够尽量让 不要让用户改你的源码 也就是有足够的扩展性 或者提供的 ai 足够齐全
            
            
            
        </script>
    </body>

</html>

▪js

(function (global, factory,plug) {
    //这里考虑 移植性
    factory.call(global,global.jQuery,plug);
    
})(typeof window === 'undefined' ? this:window,function ($,plug) {
    var __I18N__ = {
        "en" : {
            "notForm" : "is not form element",
            "erropMsg" : "* valid fail"
        },
        "zh" : {
            "notForm" : "非表单元素",
            "erropMsg" : "* 校验不合法"
        }
    }
    
    //默认配置项
    var __DEFS__ = {
        raise : "change",//默认change事件
        pix : 'bv-',
        lang: "en",
        i18n: "en",
        getMessage : null,
        errormsg : null
    }
    //默认规则引擎 //参照引擎
    var __RULES__ = {
        "require" : function () {
            return this.val() && this.val() !== "";
        },
        "number" : function () {
            return !isNaN(this.val());
        },
        "integer" : function () {
            return true;
        },
        "email" : function () {
            
            return /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/.test(this.val());
        },
        "length" : function () {
            return this.val().length === Number(this.data(__DEFS__.pix+"length"));
        },
        "regex" : function () {
            console.log(this.data(__DEFS__.pix + "regex"));
            return new RegExp(this.data(__DEFS__.pix + "regex")).test(this.val());
        }
        //...可以继续添加
    }
    
    
    //国际化问题
    //真正被创建的闭包,并且只执行一次的内存机构//这里是闭包空间
    $.fn[plug] = function (ops) {//在 jq原型上扩展了方法
        //参数校验
        var that = $.extend(this,__DEFS__, ops);//这个很牛逼 ,this是个jq对象,直接把参数给了这个对象
        this.getMessage = $.fn[plug].getMessage;
        if(this.is("form")) {
            //先扩展默认值, 再用 用户 设置的 值覆盖默认值 如果有的话.
            var $fields = this.find("input,textarea,select").not("[type=submit],[type=button],[type=reset]");
            //$fields : 表单域 //目标表单元素 //目标对象.
             $fields.on(this.raise,function () {//违背了架构性?
                var $field = $(this);
                var $group = $field.parents(".form-group:first");//找到所在的 from-group 用来改变样式
                $group.removeClass("has-success has-error");
                $group.find(".help-block").remove();
                var result = false;//默认 校验结果为失败
                var msg = that.getMessage(that.lang,that.errormsg);//获取错误信息
                $.each(__RULES__, function(rule , active) {
                    if($field.data(that.pix+rule)) {
                        result = active.call($field);
                        if(!result) {
                            msg = $field.data(that.pix+rule + "-message") || that.errormsg;//获得配置的错误提示信息
                            //确实很漂亮的 解决了 默认值问题
                            $group.addClass("has-error");
                            $field.after("<span class=\"help-block\">" + msg + "<span>");
                            return false
                        }else {
                            $group.addClass("has-success");
                        }
                        
                    }
                });
                
             });
             this.extendRules = $.fn[plug].extendRules;//注释1-1:这是实例化之后的对象上,调用方法
             return this;
             //有一个方法是 把[plug]对象也 extend 掉
        }else {
            throw new Error(that.getMessage(that.lang,"notForm"));
        }
    }
    //我了个擦,才发现,下面的这些不是在 jq原型链上直接定义的,而是定义在 plug 这个上面的工具方法.
    //这个方式也挺有意思.比如我用一个构造函数构造了一个对象,但是我没有把方法定义在原型链上,而是定义在构造函数本身上.
    //然后,我用extend,对象深度赋值的方式,继承,也能实现.当然,除非在构造函数上设置,每个实例都 extend 这个对象,否则并不能自然继承.
     $.fn[plug].extendRules = function (rules) {//注释1-2: 这是直接在原型链上调用
                $.extend(__RULES__,rules);
             }
     // zh en
     $.fn[plug].addLocale = function (language,data) {
        __I18N__[language] = data;
        //这里我们只要改掉 that.lang 那么下面都会跟着改
     }
     $.fn[plug].getMessage = function (language,key) {
        return __I18N__[language][key]; 
     }
     //方法定义在原型链上,然后移植给 包装对象,方便调用
},"bootstrapValidate");

下面的内容没有逻辑.我都懒得去看第二遍.所以不存在修改.
陈老师的版本确实是把设计模式的思想讲得清晰透彻.
而这个版本相比而言,很明显有一种精心打造,要秀一下的感觉.
(确实很秀)

有好几个印象,

这个插件是可配置的,可扩展的.
策略模式的应用本来就是为了可扩展的.
这里有两种主要的配置入口?(扩展入口?)
1)在调用时传参,比如事件类型
2)在html中用data-bv-require-message这种形式,
联想到vue的数据绑定,当然这里不算是双向绑定.
但有个思路是,跟当前这个dom元素相关的参数,可以直接用这种方式写在html中.

默认+配置套路?
var that = .extend(this,__DEFS__, ops); ops 和 __DEFS__ 一个是配置对象,一个是默认对象. 用的是extend进行保留覆盖. 这里有个细节是, 不能把ops配置到__DEFS__上, 因为有可能再次调用,默认值不能被污染. 也许可以.extend( ops,DEFS)
(设计模式当中有类似的嘛?装饰者模式?
装饰者模式挺像的,也是给对象动态增添属性和方法.
不过装饰者模式比较重,为了重用和扩展,结构更复杂一点)

写在html,通过这种方式配置,或者传参,
其实这几天学设计模式的时候,我就觉得,
面向对象的设计,
一个很重要的方面是,
数据要怎么组织的问题.
假设一个代码的执行,所需要的参数
包括几个函数,几个dom,几个数据,
这些函数,dom,数据都放置在各自的对象(数组)中,
我们要做的实际上是对他们进行组合.
想成是组合的方式的时候,
我们就会感觉,复用性和扩展性就会提升很多.
而如果想要进行组合,
就要想办法把这些函数,dom, 数据,
都按照有规则的方式组织起来,
多么好的组织方式,决定了组合调用的时候,多么方便.

而具体用什么方式组织这些数据,
可能是没有完全的正确答案?
面向对象的编程,从某种角度上看,就是组织这些数据和行为,在对象里.
而不同的设计模式,就是针对不同的抽象关系,
选择不同的设计模式?

如果说从这种方式来考虑的话,
我们首先是确定需求,
然后是确定相关量,
确定数据流向,
然后考虑这些需求和逻辑,他们的一般关系是什么?
然后考虑体现了哪些设计模式?
最后决定架构或者逻辑?

或者,
从一开始,我们脑子里就应该有一种基本思维,
想办法以合理的方式进行组织.
也许面向对象的编程,潜台词就是,
你要不停的用对象的方式组织数据和行为.

当然了,我觉得面向对象的编程,
以及设计模式的思想当中包含的内容,
肯定是超过这个范围的.

比如,我们进行了数据的组织,那么怎么进行组合?
面向对象的编程的思想当中,似乎也有这方面的意思.
一个对象为单位,设计这个对象的行为,就是在设计数据和数据的组合方式?

但既然我们提到了组织数据的问题.
我们继续谈一谈.
有没有已经存在的数据组织方式?

关于在html里增添属性的方式增添数据的方式.
从某种角度来看,
html整个标签的文档结构,
就是一种数据组织结构.
而且这种结构可读性非常强.
(关键在于,能看成是数据组织的一种方式.)

组织数据,实际上是解决一个把数据的标记放哪的问题,
因为js里是存在引用值的.

先建立一个基本数据库,
然后里面的数据可以有各种引用值,标识.

所谓的数据的组织,从这种角度来讲的话,
是两种不同的管理?

一种是创建,一种是组合?
比如,我在html创建了结构,创建了很多dom结构.

这就属于创建.
比如我用jq,('div'),('.class'),
这些则是用一种标识(维度)进行标记,
以某种规则整合在一起?
如果从标记的角度去看的话,
维度可以有很多?
这里也许有个问题是,
这些标识当然应该都有访问权限,
但其中一些只应该有访问权限而没有修改权限.
或者,根据最底层的数据,可以创建另外一些独立数据?

不知从何处开始,文章的逻辑已经完全走向迷宫..

问题在于,
想要组合这些数据(利用这些数据),
就要想办法,让我们理解这些数据的组织方式,
也许组织数据的方式存在无数种,
但我们想要利用这些数据,
就要把组织数据和组合数据的方式,
让人能够看懂,
因为需求是人定的.
虽然写好的代码,程序可能自己能跑起来,
但写代码的依旧是人,
所以需要让人能看懂,能利用.
这也是强调可读性的原因.
如果代码不存在可读性这个维度,
可能代码就不用是人写的了.

面向对象的思维,不就是说是模拟人解决事物的思维方式吗.

也许代码本身只需要知道,
谁跟谁组合在一起?
执行顺序?

回过头,
上面说到,
html 结构本身可以看成是一种数据组织方式.

我觉得肯定需要一个概念,叫维度.
组织数据,我们可以认为,是根据一个维度进行的.
html 结构可以算是一个维度,
数据挂载到这个维度上.

我们此前在设计模式有感中提到过,
这几个设计模式都有类似的某种结构,
也许面向对象编程的好处是,
他能天生带好几个维度?
比如
实例上定义属性 是一个维度
原型上定义属性 是一个维度
根据需求可以扩展维度,

对象和数组的结构本身,
就含有强烈的维度色彩.
对象还有一个继承的维度

说了这么些废话,实际上并没有什么学到的东西.
但说这些废话的过程,实际上是一种铺垫.
或者说留个印象,有过一丢丢的思考.
因为日后遇到类似的内容的时候,
我可能会稍微比较容易的理解.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354

推荐阅读更多精彩内容

  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 31,931评论 2 89
  • 嫁到婆家后,我在厨房小露过几手。家庭版的胡辣汤、肉夹馍、麻辣香锅、羊肉烩面、可乐鸡翅、糖醋鱼、排骨扣碗等等什么都做...
    步步履不停阅读 273评论 0 0
  • 坚持你的爱好,便是一种成功。 开始写这篇文章的时候,内心是忐忑的,自己有多少年没有正经的写过东西了?不得不让我想...
    大杯喝柠檬汁大口吃肉阅读 401评论 0 1
  • 怀孕在家一直待着,有时候会很无聊,特别是这样天气炎热的夏天,又不能过多的外出,看电视,手机,电脑的时间也缩短了。 ...
    後青春的詩阅读 147评论 0 2
  • 她是一个妖艳的女子。他们都那样说。 她是一个孤独入髓的女子。只有她自己知道。 每天在外面的日子,灯红酒绿觥筹交错,...
    成都周周阅读 251评论 0 2