<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                1.理解javascript中的策略模式 策略模式的定義是:定義一系列的算法,把它們一個個封裝起來,并且使它們可以相互替換。 使用策略模式的優點如下: 優點:1. 策略模式利用組合,委托等技術和思想,有效的避免很多if條件語句。 2. 策略模式提供了開放-封閉原則,使代碼更容易理解和擴展。 3. 策略模式中的代碼可以復用。 一:使用策略模式計算獎金; 下面的demo是我在書上看到的,但是沒有關系,我們只是來理解下策略模式的使用而已,我們可以使用策略模式來計算獎金問題; 比如公司的年終獎是根據員工的工資和績效來考核的,績效為A的人,年終獎為工資的4倍,績效為B的人,年終獎為工資的3倍,績效為C的人,年終獎為工資的2倍;現在我們使用一般的編碼方式會如下這樣編寫代碼: ~~~ var calculateBouns = function(salary,level) { if(level === 'A') { return salary * 4; } if(level === 'B') { return salary * 3; } if(level === 'C') { return salary * 2; } }; // 調用如下: console.log(calculateBouns(4000,'A')); // 16000 console.log(calculateBouns(2500,'B')); // 7500 ~~~ 第一個參數為薪資,第二個參數為等級; 代碼缺點如下: calculateBouns 函數包含了很多if-else語句。 calculateBouns 函數缺乏彈性,假如還有D等級的話,那么我們需要在calculateBouns 函數內添加判斷等級D的if語句; 算法復用性差,如果在其他的地方也有類似這樣的算法的話,但是規則不一樣,我們這些代碼不能通用。 2.使用組合函數重構代碼 組合函數是把各種算法封裝到一個個的小函數里面,比如等級A的話,封裝一個小函數,等級為B的話,也封裝一個小函數,以此類推;如下代碼: ~~~ var performanceA = function(salary) { return salary * 4; }; var performanceB = function(salary) { return salary * 3; }; var performanceC = function(salary) { return salary * 2 }; var calculateBouns = function(level,salary) { if(level === 'A') { return performanceA(salary); } if(level === 'B') { return performanceB(salary); } if(level === 'C') { return performanceC(salary); } }; // 調用如下 console.log(calculateBouns('A',4500)); // 18000 ~~~ 代碼看起來有點改善,但是還是有如下缺點: calculateBouns 函數有可能會越來越大,比如增加D等級的時候,而且缺乏彈性。 3.使用策略模式重構代碼 策略模式指的是 定義一系列的算法,把它們一個個封裝起來,將不變的部分和變化的部分隔開,實際就是將算法的使用和實現分離出來;算法的使用方式是不變的,都是根據某個算法取得計算后的獎金數,而算法的實現是根據績效對應不同的績效規則; 一個基于策略模式的程序至少由2部分組成,第一個部分是一組策略類,策略類封裝了具體的算法,并負責具體的計算過程。第二個部分是環境類Context,該Context接收客戶端的請求,隨后把請求委托給某一個策略類。我們先使用傳統面向對象來實現; 如下代碼: ~~~ var performanceA = function(){}; performanceA.prototype.calculate = function(salary) { return salary * 4; }; var performanceB = function(){}; performanceB.prototype.calculate = function(salary) { return salary * 3; }; var performanceC = function(){}; performanceC.prototype.calculate = function(salary) { return salary * 2; }; // 獎金類 var Bouns = function(){ this.salary = null; // 原始工資 this.levelObj = null; // 績效等級對應的策略對象 }; Bouns.prototype.setSalary = function(salary) { this.salary = salary; // 保存員工的原始工資 }; Bouns.prototype.setlevelObj = function(levelObj){ this.levelObj = levelObj; // 設置員工績效等級對應的策略對象 }; // 取得獎金數 Bouns.prototype.getBouns = function(){ // 把計算獎金的操作委托給對應的策略對象 return this.levelObj.calculate(this.salary); }; var bouns = new Bouns(); bouns.setSalary(10000); bouns.setlevelObj(new performanceA()); // 設置策略對象 console.log(bouns.getBouns()); // 40000 bouns.setlevelObj(new performanceB()); // 設置策略對象 console.log(bouns.getBouns()); // 30000 ~~~ 如上代碼使用策略模式重構代碼,可以看到代碼職責更新分明,代碼變得更加清晰。 4.Javascript版本的策略模式 ~~~ //代碼如下: var obj = { "A": function(salary) { return salary * 4; }, "B" : function(salary) { return salary * 3; }, "C" : function(salary) { return salary * 2; } }; var calculateBouns =function(level,salary) { return obj[level](salary); }; console.log(calculateBouns('A',10000)); // 40000 ~~~ 可以看到代碼更加簡單明了; 策略模式指的是定義一系列的算法,并且把它們封裝起來,但是策略模式不僅僅只封裝算法,我們還可以對用來封裝一系列的業務規則,只要這些業務規則目標一致,我們就可以使用策略模式來封裝它們; 表單效驗 比如我們經常來進行表單驗證,比如注冊登錄對話框,我們登錄之前要進行驗證操作:比如有以下幾條邏輯: 用戶名不能為空 密碼長度不能小于6位。 手機號碼必須符合格式。 比如HTML代碼如下: ~~~ <form action = "http://www.baidu.com" id="registerForm" method = "post"> <p> <label>請輸入用戶名:</label> <input type="text" name="userName"/> </p> <p> <label>請輸入密碼:</label> <input type="text" name="password"/> </p> <p> <label>請輸入手機號碼:</label> <input type="text" name="phoneNumber"/> </p> </form> ~~~ 我們正常的編寫表單驗證代碼如下: ~~~ var registerForm = document.getElementById("registerForm"); registerForm.onsubmit = function(){ if(registerForm.userName.value === '') { alert('用戶名不能為空'); return; } if(registerForm.password.value.length < 6) { alert("密碼的長度不能小于6位"); return; } if(!/(^1[3|5|8][0-9]{9}$)/.test(registerForm.phoneNumber.value)) { alert("手機號碼格式不正確"); return; } } ~~~ 但是這樣編寫代碼有如下缺點: 1. registerForm.onsubmit 函數比較大,代碼中包含了很多if語句; 2. registerForm.onsubmit 函數缺乏彈性,如果增加了一種新的效驗規則,或者想把密碼的長度效驗從6改成8,我們必須改registerForm.onsubmit 函數內部的代碼。違反了開放-封閉原則。 3. 算法的復用性差,如果在程序中增加了另外一個表單,這個表單也需要進行一些類似的效驗,那么我們可能又需要了; 下面我們可以使用策略模式來重構表單效驗; 第一步我們先來封裝策略對象;如下代碼: ~~~ var strategy = { isNotEmpty: function(value,errorMsg) { if(value === '') { return errorMsg; } }, // 限制最小長度 minLength: function(value,length,errorMsg) { if(value.length < length) { return errorMsg; } }, // 手機號碼格式 mobileFormat: function(value,errorMsg) { if(!/(^1[3|5|8][0-9]{9}$)/.test(value)) { return errorMsg; } } }; ~~~ 接下來我們準備實現Validator類,Validator類在這里作為Context,負責接收用戶的請求并委托給strategy 對象,如下代碼: ~~~ var Validator = function(){ this.cache = []; // 保存效驗規則 }; Validator.prototype.add = function(dom,rule,errorMsg) { var str = rule.split(":"); this.cache.push(function(){ // str 返回的是 minLength:6 var strategy = str.shift(); str.unshift(dom.value); // 把input的value添加進參數列表 str.push(errorMsg); // 把errorMsg添加進參數列表 return strategys[strategy].apply(dom,str); }); }; Validator.prototype.start = function(){ for(var i = 0, validatorFunc; validatorFunc = this.cache[i++]; ) { var msg = validatorFunc(); // 開始效驗 并取得效驗后的返回信息 if(msg) { return msg; } } }; ~~~ Validator類在這里作為Context,負責接收用戶的請求并委托給strategys對象。上面的代碼中,我們先創建一個Validator對象,然后通過validator.add方法往validator對象中添加一些效驗規則,validator.add方法接收3個參數,如下代碼: validator.add(registerForm.password,'minLength:6','密碼長度不能小于6位'); registerForm.password 為效驗的input輸入框dom節點; minLength:6: 是以一個冒號隔開的字符串,冒號前面的minLength代表客戶挑選的strategys對象,冒號后面的數字6表示在效驗過程中所必須驗證的參數,minLength:6的意思是效驗 registerForm.password 這個文本輸入框的value最小長度為6位;如果字符串中不包含冒號,說明效驗過程中不需要額外的效驗信息; 第三個參數是當效驗未通過時返回的錯誤信息; 當我們往validator對象里添加完一系列的效驗規則之后,會調用validator.start()方法來啟動效驗。如果validator.start()返回了一個errorMsg字符串作為返回值,說明該次效驗沒有通過,此時需要registerForm.onsubmit方法返回false來阻止表單提交。下面我們來看看初始化代碼如下: ~~~ var validateFunc = function(){ var validator = new Validator(); // 創建一個Validator對象 /* 添加一些效驗規則 */ validator.add(registerForm.userName,'isNotEmpty','用戶名不能為空'); validator.add(registerForm.password,'minLength:6','密碼長度不能小于6位'); validator.add(registerForm.userName,'mobileFormat','手機號碼格式不正確'); var errorMsg = validator.start(); // 獲得效驗結果 return errorMsg; // 返回效驗結果 }; var registerForm = document.getElementById("registerForm"); registerForm.onsubmit = function(){ var errorMsg = validateFunc(); if(errorMsg){ alert(errorMsg); return false; } } ~~~ 下面是所有的代碼如下: ~~~ var strategys = { isNotEmpty: function(value,errorMsg) { if(value === '') { return errorMsg; } }, // 限制最小長度 minLength: function(value,length,errorMsg) { if(value.length < length) { return errorMsg; } }, // 手機號碼格式 mobileFormat: function(value,errorMsg) { if(!/(^1[3|5|8][0-9]{9}$)/.test(value)) { return errorMsg; } } }; var Validator = function(){ this.cache = []; // 保存效驗規則 }; Validator.prototype.add = function(dom,rule,errorMsg) { var str = rule.split(":"); this.cache.push(function(){ // str 返回的是 minLength:6 var strategy = str.shift(); str.unshift(dom.value); // 把input的value添加進參數列表 str.push(errorMsg); // 把errorMsg添加進參數列表 return strategys[strategy].apply(dom,str); }); }; Validator.prototype.start = function(){ for(var i = 0, validatorFunc; validatorFunc = this.cache[i++]; ) { var msg = validatorFunc(); // 開始效驗 并取得效驗后的返回信息 if(msg) { return msg; } } }; var validateFunc = function(){ var validator = new Validator(); // 創建一個Validator對象 /* 添加一些效驗規則 */ validator.add(registerForm.userName,'isNotEmpty','用戶名不能為空'); validator.add(registerForm.password,'minLength:6','密碼長度不能小于6位'); validator.add(registerForm.userName,'mobileFormat','手機號碼格式不正確'); var errorMsg = validator.start(); // 獲得效驗結果 return errorMsg; // 返回效驗結果 }; var registerForm = document.getElementById("registerForm"); registerForm.onsubmit = function(){ var errorMsg = validateFunc(); if(errorMsg){ alert(errorMsg); return false; } }; ~~~ 如上使用策略模式來編寫表單驗證代碼可以看到好處了,我們通過add配置的方式就完成了一個表單的效驗;這樣的話,那么代碼可以當做一個組件來使用,并且可以隨時調用,在修改表單驗證規則的時候,也非常方便,通過傳遞參數即可調用; 給某個文本輸入框添加多種效驗規則,上面的代碼我們可以看到,我們只是給輸入框只能對應一種效驗規則,比如上面的我們只能效驗輸入框是否為空,validator.add(registerForm.userName,'isNotEmpty','用戶名不能為空');但是如果我們既要效驗輸入框是否為空,還要效驗輸入框的長度不要小于10位的話,那么我們期望需要像如下傳遞參數: validator.add(registerForm.userName,[{strategy:’isNotEmpty’,errorMsg:’用戶名不能為空’},{strategy: 'minLength:6',errorMsg:'用戶名長度不能小于6位'}]) 我們可以編寫代碼如下: ~~~ // 策略對象 var strategys = { isNotEmpty: function(value,errorMsg) { if(value === '') { return errorMsg; } }, // 限制最小長度 minLength: function(value,length,errorMsg) { if(value.length < length) { return errorMsg; } }, // 手機號碼格式 mobileFormat: function(value,errorMsg) { if(!/(^1[3|5|8][0-9]{9}$)/.test(value)) { return errorMsg; } } }; var Validator = function(){ this.cache = []; // 保存效驗規則 }; Validator.prototype.add = function(dom,rules) { var self = this; for(var i = 0, rule; rule = rules[i++]; ){ (function(rule){ var strategyAry = rule.strategy.split(":"); var errorMsg = rule.errorMsg; self.cache.push(function(){ var strategy = strategyAry.shift(); strategyAry.unshift(dom.value); strategyAry.push(errorMsg); return strategys[strategy].apply(dom,strategyAry); }); })(rule); } }; Validator.prototype.start = function(){ for(var i = 0, validatorFunc; validatorFunc = this.cache[i++]; ) { var msg = validatorFunc(); // 開始效驗 并取得效驗后的返回信息 if(msg) { return msg; } } }; // 代碼調用 var registerForm = document.getElementById("registerForm"); var validateFunc = function(){ var validator = new Validator(); // 創建一個Validator對象 /* 添加一些效驗規則 */ validator.add(registerForm.userName,[ {strategy: 'isNotEmpty',errorMsg:'用戶名不能為空'}, {strategy: 'minLength:6',errorMsg:'用戶名長度不能小于6位'} ]); validator.add(registerForm.password,[ {strategy: 'minLength:6',errorMsg:'密碼長度不能小于6位'}, ]); validator.add(registerForm.phoneNumber,[ {strategy: 'mobileFormat',errorMsg:'手機號格式不正確'}, ]); var errorMsg = validator.start(); // 獲得效驗結果 return errorMsg; // 返回效驗結果 }; // 點擊確定提交 registerForm.onsubmit = function(){ var errorMsg = validateFunc(); if(errorMsg){ alert(errorMsg); return false; } } ~~~ 注意:如上代碼都是按照書上來做的,都是看到書的代碼,最主要我們理解策略模式實現,比如上面的表單驗證功能是這樣封裝的代碼,我們平時使用jquery插件表單驗證代碼原來是這樣封裝的,為此我們以后也可以使用這種方式來封裝表單等學習;
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看