国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Javascript設計模式(四)策略模式

U2FsdGVkX1x / 3417人閱讀

摘要:策略模式的優缺點優點策略模式利用組合,委托和多態等技術思想,可以有效避免多重條件選擇語句。策略模式提供了對開放封閉原則的完美支持。策略模式會向用戶暴露所有實現細節,這其實是違反最少知識原則。

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

在現實中,如果我們想去某個地方旅游,可以根據實際情況有多種路線

如果沒有時間但是不在乎錢,可以選擇飛機

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

如果再窮一點,可以選擇騎自行車

使用策略模式計算獎金

現在以年終獎的計算為例

公司年終獎根據員工的工資基數年底績效來發放

績效S,四倍年終獎

績效A,三倍年終獎

績效B,二倍年終獎

最初的實現
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

這段代碼簡單,但是存在顯而易見的缺點

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

缺乏彈性,如果想新增績效C,就得深入函數內部實現,違反開放-封閉原則

算法的復用性差

策略模式的實現
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

通過使用策略模式重構代碼,消除來原程序中分支語句。所有計算獎金有關的邏輯分布在策略對象中,每個策略對象的算法已被各自封裝在對象內部,當我們對這些策略對象發出“計算獎金”的請求時,它們會返回各自的計算結果,這不僅是多態性的體現,也是“自由交換”的目的。

使用策略模式實現緩動動畫


    
        
        
        
    
    
    
我說div
用策略模式實現表單驗證

從定義上看,策略模式就是用來封裝算法的。但是如果僅僅用來封裝算法,未免有點大材小用。在實際業務中,策略模式也可以用來封裝一系列的“業務規則”。只要業務規則指向的目標一致,并且可以被替換使用,我們就可以用策略模式來封裝它們。

普通版本的表單驗證



    
    
    


請輸入用戶名
請輸入密碼
請輸入手機號

這是一種很常見的編碼方式,可以看到缺點和計算獎金一摸一樣

用策略模式重構表單驗證

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

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
        }
    }
}

接下來實現Validator類,負責接受用戶的請求并委托給strategies

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

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

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

接下來就是調用了

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: "手機號碼格式不正確"                        
            }
        ]
    )                                
    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
    }
}

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

策略模式的優缺點 優點

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

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

策略模式中的算法也可以復用在系統中的其他地方。

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

缺點

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

策略模式會向用戶暴露所有實現細節,這其實是違反最少知識原則。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/99180.html

相關文章

  • 前端也要學系列:設計模式策略模式

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

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

    摘要:函數式編程前端掘金引言面向對象編程一直以來都是中的主導范式。函數式編程是一種強調減少對程序外部狀態產生改變的方式。 JavaScript 函數式編程 - 前端 - 掘金引言 面向對象編程一直以來都是JavaScript中的主導范式。JavaScript作為一門多范式編程語言,然而,近幾年,函數式編程越來越多得受到開發者的青睞。函數式編程是一種強調減少對程序外部狀態產生改變的方式。因此,...

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

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

    didikee 評論0 收藏0
  • JavaScript設計模式----策略模式

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

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

    摘要:策略模式實現的也是類似的場景。第二個部分是環境類不變,接收客戶的請求,隨后把請求委托給某一個策略類。參考文章設計模式設計模式與開發實踐設計模式系統講解與應用本文首發,期待作者以樂之名本文原創,有不當的地方歡迎指出。 showImg(https://segmentfault.com/img/bVbugi7?w=800&h=600); 策略模式:定義一系列的算法,把它們一個個封裝起來,并且...

    荊兆峰 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<