成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Javascript設(shè)計(jì)模式(四)策略模式

U2FsdGVkX1x / 3425人閱讀

摘要:策略模式的優(yōu)缺點(diǎn)優(yōu)點(diǎn)策略模式利用組合,委托和多態(tài)等技術(shù)思想,可以有效避免多重條件選擇語句。策略模式提供了對開放封閉原則的完美支持。策略模式會(huì)向用戶暴露所有實(shí)現(xiàn)細(xì)節(jié),這其實(shí)是違反最少知識(shí)原則。

策略模式的定義是:定義一系列的算法,把它們一個(gè)個(gè)封裝起來,并且使它們可以相互替換。

在現(xiàn)實(shí)中,如果我們想去某個(gè)地方旅游,可以根據(jù)實(shí)際情況有多種路線

如果沒有時(shí)間但是不在乎錢,可以選擇飛機(jī)

如果沒有錢,可以選擇大巴活著火車

如果再窮一點(diǎn),可以選擇騎自行車

使用策略模式計(jì)算獎(jiǎng)金

現(xiàn)在以年終獎(jiǎng)的計(jì)算為例

公司年終獎(jiǎng)根據(jù)員工的工資基數(shù)年底績效來發(fā)放

績效S,四倍年終獎(jiǎng)

績效A,三倍年終獎(jiǎng)

績效B,二倍年終獎(jiǎng)

最初的實(shí)現(xiàn)
var calculateBonus = function(performanceLevel, salary) {
    if (performanceLevel === "S") {
        return salary*4
    }
    if (performanceLevel === "A") {
        return salary*3
    }
    if (performanceLevel === "B") {
        return salary*2
    }
}
calculateBonus("B", 2000) // 4000
calculateBonus("S", 2000) // 8000

這段代碼簡單,但是存在顯而易見的缺點(diǎn)

函數(shù)比較龐大,包含很多if-else語句,這些語句需要覆蓋所有的邏輯分支

缺乏彈性,如果想新增績效C,就得深入函數(shù)內(nèi)部實(shí)現(xiàn),違反開放-封閉原則

算法的復(fù)用性差

策略模式的實(shí)現(xiàn)
var strategies = {
    "S": function(salary) {
        return salary * 4
    },
    "A": function(salary) {
        return salary * 3
    },
    "B": function(salary) {
        return salary * 2
    }                
}
var calculateBonus = function(level, salary) {
    return strategies[level](salary)
}
console.log(calculateBonus("S", 2000)) // 8000
console.log(calculateBonus("B", 2000)) // 4000

通過使用策略模式重構(gòu)代碼,消除來原程序中分支語句。所有計(jì)算獎(jiǎng)金有關(guān)的邏輯分布在策略對象中,每個(gè)策略對象的算法已被各自封裝在對象內(nèi)部,當(dāng)我們對這些策略對象發(fā)出“計(jì)算獎(jiǎng)金”的請求時(shí),它們會(huì)返回各自的計(jì)算結(jié)果,這不僅是多態(tài)性的體現(xiàn),也是“自由交換”的目的。

使用策略模式實(shí)現(xiàn)緩動(dòng)動(dòng)畫


    
        
        
        
    
    
    
我說div
用策略模式實(shí)現(xiàn)表單驗(yàn)證

從定義上看,策略模式就是用來封裝算法的。但是如果僅僅用來封裝算法,未免有點(diǎn)大材小用。在實(shí)際業(yè)務(wù)中,策略模式也可以用來封裝一系列的“業(yè)務(wù)規(guī)則”。只要業(yè)務(wù)規(guī)則指向的目標(biāo)一致,并且可以被替換使用,我們就可以用策略模式來封裝它們。

普通版本的表單驗(yàn)證



    
    
    


請輸入用戶名
請輸入密碼
請輸入手機(jī)號(hào)

這是一種很常見的編碼方式,可以看到缺點(diǎn)和計(jì)算獎(jiǎng)金一摸一樣

用策略模式重構(gòu)表單驗(yàn)證

很明顯第一步我們需要將驗(yàn)證邏輯封裝成策略對象

var strategies = {
    isNonEmpty: function(value, errorMsg) {
        if (value === "") {
            return errorMsg
        }
    },
    minLength: function(value, length, errorMsg) {
        if (value.length < length) {
            return errorMsg
        }
    },
    isMobile: function(value, errorMsg) {
        if (!/(^1[3|5|8][0-9]{9}$)/.test(value)) {
            return errorMsg
        }
    }
}

接下來實(shí)現(xiàn)Validator類,負(fù)責(zé)接受用戶的請求并委托給strategies

var Validator = function() {
    //保存校驗(yàn)規(guī)則
    this.cache = [] 
}

// 添加校驗(yàn)
Validator.prototype.add = function(dom, rules) {
    var self = this
    // 遍歷校驗(yàn)規(guī)則
    for(var i = 0, rule; rule = rules[i++];) { 
        (function(rule){
            //把strategy和參數(shù)分開
            var strategyAry = rule.strategy.split(":")     
            var errorMsg = rule.errorMsg    
            // 把校驗(yàn)的步驟用空函數(shù)包裝起來,并且放入cache
            self.cache.push(function(){    
                // 挑選出校驗(yàn)規(guī)則
                var strategy = strategyAry.shift()
                // 把input的value添加進(jìn)參數(shù)列表
                strategyAry.unshift(dom.value)        
                // 把errorMsg添加進(jìn)參數(shù)列表
                strategyAry.push(errorMsg)            
                return strategies[strategy].apply(dom, strategyAry)
            })
        })(rule)
    }
}

// 啟動(dòng)校驗(yàn)
Validator.prototype.start = function() {
    for (var i = 0, validatorFunc; validatorFunc = this.cache[i++];) { 
        // 開始校驗(yàn),并取得校驗(yàn)后的結(jié)果
        var errorMsg = validatorFunc() 
        if (errorMsg) {
            return errorMsg
        }
    }
}

接下來就是調(diào)用了

var registerForm = document.getElementById("registerForm")

var validataFunc = function() {
    var validator = new Validator()
    validator.add(registerForm.username, [
            {
                strategy: "isNonEmpty",
                errorMsg: "用戶名不能為空"
            },
            {
                strategy: "minLength:10",
                errorMsg: "用戶名長度不能小于10位"                        
            }
        ]
    )
    validator.add(registerForm.password, [
            {
                strategy: "minLength:6",
                errorMsg: "密碼長度不能小于6位"                        
            }
        ]
    )
    validator.add(registerForm.phonenumber, [
            {
                strategy: "isMobile",
                errorMsg: "手機(jī)號(hào)碼格式不正確"                        
            }
        ]
    )                                
    var errorMsg = validator.start()
    return errorMsg                            
}

var sub = document.querySelector("input[type="submit"]")
sub.onclick = function() {
    var errorMsg = validataFunc()
    if (errorMsg) {
        console.error(errorMsg)
        return false
    }
}

使用策略模式重構(gòu)代碼之后,我們不僅通過“配置”的方式就可以完成一個(gè)表單的校驗(yàn),這些規(guī)則也可以復(fù)用在程序的任何地方,還能以插件的形式,方便地移植到其他項(xiàng)目中。并且新增或者修改規(guī)則也是毫不費(fèi)力的。

策略模式的優(yōu)缺點(diǎn) 優(yōu)點(diǎn)

策略模式利用組合,委托和多態(tài)等技術(shù)思想,可以有效避免多重條件選擇語句。

策略模式提供了對開放-封閉原則的完美支持。將算法封裝在獨(dú)立的strategy中,使得它們易于切換,易于理解,易于擴(kuò)展。

策略模式中的算法也可以復(fù)用在系統(tǒng)中的其他地方。

在策略模式中利用組合和委托讓Content擁有執(zhí)行算法的能力,這也是繼承的一種更輕便的替代方案。

缺點(diǎn)

使用策略對象會(huì)增加很多策略類或者策略對象,但實(shí)際上比把這些邏輯放在Content更好。

策略模式會(huì)向用戶暴露所有實(shí)現(xiàn)細(xì)節(jié),這其實(shí)是違反最少知識(shí)原則。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/99180.html

相關(guān)文章

  • 前端也要學(xué)系列:設(shè)計(jì)模式策略模式

    摘要:做前端開發(fā)已經(jīng)好幾年了,對設(shè)計(jì)模式一直沒有深入學(xué)習(xí)總結(jié)過。今天第一天,首先來講策略模式。什么是策略模式四兄弟的經(jīng)典設(shè)計(jì)模式中,對策略模式的定義如下定義一系列的算法,把它們一個(gè)個(gè)封裝起來,并且使它們可互相替換。 做前端開發(fā)已經(jīng)好幾年了,對設(shè)計(jì)模式一直沒有深入學(xué)習(xí)總結(jié)過。隨著架構(gòu)相關(guān)的工作越來越多,越來越能感覺到設(shè)計(jì)模式成為了我前進(jìn)道路上的一個(gè)阻礙。所以從今天開始深入學(xué)習(xí)和總結(jié)經(jīng)典的設(shè)計(jì)模...

    Anchorer 評論0 收藏0
  • JavaScript系列() - 收藏集 - 掘金

    摘要:函數(shù)式編程前端掘金引言面向?qū)ο缶幊桃恢币詠矶际侵械闹鲗?dǎo)范式。函數(shù)式編程是一種強(qiáng)調(diào)減少對程序外部狀態(tài)產(chǎn)生改變的方式。 JavaScript 函數(shù)式編程 - 前端 - 掘金引言 面向?qū)ο缶幊桃恢币詠矶际荍avaScript中的主導(dǎo)范式。JavaScript作為一門多范式編程語言,然而,近幾年,函數(shù)式編程越來越多得受到開發(fā)者的青睞。函數(shù)式編程是一種強(qiáng)調(diào)減少對程序外部狀態(tài)產(chǎn)生改變的方式。因此,...

    cfanr 評論0 收藏0
  • JavaScript 模式》知識(shí)點(diǎn)小抄本(上)

    摘要:單體模式有以下優(yōu)點(diǎn)用來劃分命名空間,減少全局變量數(shù)量。通常我們使用操作符創(chuàng)建單體模式的三種選擇,讓構(gòu)造函數(shù)總返回最初的對象使用全局對象來存儲(chǔ)該實(shí)例不推薦,容易全局污染。實(shí)現(xiàn)該工廠模式并不困難,主要是要找到能夠穿件所需類型對象的構(gòu)造函數(shù)。 介紹 最近開始給自己每周訂個(gè)學(xué)習(xí)任務(wù),學(xué)習(xí)結(jié)果反饋為一篇文章的輸出,做好學(xué)習(xí)記錄。 這一周(02.25-03.03)我定的目標(biāo)是《JavaScri...

    didikee 評論0 收藏0
  • JavaScript設(shè)計(jì)模式----策略模式

    摘要:實(shí)際上在這種將函數(shù)作為一等對象的語言里,策略模式已經(jīng)融入到了語言本身當(dāng)中,我們經(jīng)常使用高階函數(shù)來封裝不同的行為,并且把它傳遞到另一個(gè)函數(shù)中。 聲明:這個(gè)系列為閱讀《JavaScript設(shè)計(jì)模式與開發(fā)實(shí)踐》 ----曾探@著一書的讀書筆記 1.策略模式的定義 將不變的部分和變化的部分隔開是每個(gè)設(shè)計(jì)模式的主題。 定義一系列的算法,把它們一個(gè)個(gè)封裝起來,并且使它們可以相互替換。 2.策略模式...

    forrest23 評論0 收藏0
  • JavaScript 設(shè)計(jì)模式(二):策略模式

    摘要:策略模式實(shí)現(xiàn)的也是類似的場景。第二個(gè)部分是環(huán)境類不變,接收客戶的請求,隨后把請求委托給某一個(gè)策略類。參考文章設(shè)計(jì)模式設(shè)計(jì)模式與開發(fā)實(shí)踐設(shè)計(jì)模式系統(tǒng)講解與應(yīng)用本文首發(fā),期待作者以樂之名本文原創(chuàng),有不當(dāng)?shù)牡胤綒g迎指出。 showImg(https://segmentfault.com/img/bVbugi7?w=800&h=600); 策略模式:定義一系列的算法,把它們一個(gè)個(gè)封裝起來,并且...

    荊兆峰 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<