您現在的位置是:電腦技術吧?>? 故障問題 ??>??策略模式,狀態模式和策略模式??>??正文詳情

策略模式,狀態模式和策略模式

靖子凡2019-12-08 11:02:38 人圍觀
簡介命令模式和策略模式本文主要介紹JavaScript的策略模式編程,包括使用函數和類作為策略的情況,以及在多種環境下的策略模式。請參考我最喜歡的策略設計模式為您的朋友。我盡量多用

這篇文章主要介紹了詳解JavaScript的策略模式編程,包括函數和類作為策略的情況以及多環境下的策略模式,需要的朋友可以參考下  我喜歡策略設計模式。

我盡可能多的試著去使用它。

究其本質,策略模式使用委托去解耦使用它們的算法類。

  這樣做有幾個好處。

他可以防止使用大條件語句來決定哪些算法用于特定類型的對象。

將關注點分離開來,因此降低了客戶端的復雜度,同時還可以促進子類化的組成。

它提高了模塊化和可測性。

每一個算法都可以單獨測試。

每一個客戶端都可以模擬算法。

任意的客戶端都能使用任何算法。

他們可以互調。

就像樂高積木一樣。

  為了實現策略模式,通常有兩個參與者:  該策略的對象,封裝了算法。

  客戶端(上下文)對象,以即插即用的方式能使用任何策略。

  這里介紹了我在Javascrip里,怎樣使用策略模式,在混亂無序的環境中怎樣使用它將庫拆成小插件,以及即插即用包的。

  函數作為策略  一個函數提供了一種封裝算法的絕佳方式,同時可以作為一種策略來使用。

只需通過一個到客戶端的函數并確保你的客戶端能調用該策略。

  我們用一個例子來證明。

假設我們想創建一個Greeter 類。

它所要做的就是和人打招呼。

我們希望Greeter 類能知道跟人打招呼的不同方式。

為了實現這一想法,我們為打招呼創建不同的策略。

  ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 // Greeter is a class of object that can greet people. // It can learn different ways of greeting people through // 'Strategies.' // // This is the Greeter constructor. var Greeter = function(strategy) { this.strategy = strategy; }; // Greeter provides a greet function that is going to // greet people using the Strategy passed to the constructor. Greeter.prototype.greet = function() { return this.strategy(); }; // Since a function encapsulates an algorithm, it makes a perfect // candidate for a Strategy. // // Here are a couple of Strategies to use with our Greeter. var politeGreetingStrategy = function() { console.log(Hello.); }; var friendlyGreetingStrategy = function() { console.log(Hey!); }; var boredGreetingStrategy = function() { console.log(sup.); }; // Let's use these strategies! var politeGreeter = new Greeter(politeGreetingStrategy); var friendlyGreeter = new Greeter(friendlyGreetingStrategy); var boredGreeter = new Greeter(boredGreetingStrategy); console.log(politeGreeter.greet()); //= Hello. console.log(friendlyGreeter.greet()); //= Hey! console.log(boredGreeter.greet()); //= sup.   在上面的例子中,Greeter 是客戶端,并有三種策略。

正如你所看到的,Greeter 知道怎樣使用算法,但對于算法的細節卻一無所知。

  對于復雜的算法,一個簡單的函數往往不能滿足。

在這種情況下,對好的方式就是按照對象來定義。

  類作為策略  策略同樣可以是類,特別是當算比上述例子中使用的人為的(策略/算法)更復雜的時候。

使用類的話,允許你為每一種策略定義一個接口。

  在下面的例子中,證實了這一點。

  ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 // We can also leverage the power of Prototypes in Javascript to create // classes that act as strategies. // // Here, we create an abstract class that will serve as the interface // for all our strategies. It isn't needed, but it's good for documenting // purposes. var Strategy = function() {}; Strategy.prototype.execute = function() { throw new Error('Strategy#execute needs to be overridden.') }; // Like above, we want to create Greeting strategies. Let's subclass // our Strategy class to define them. Notice that the parent class // requires its children to override the execute method. var GreetingStrategy = function() {}; GreetingStrategy.prototype = Object.create(Strategy.prototype); // Here is the `execute` method, which is part of the public interface of // our Strategy-based objects. Notice how I implemented this method in term of // of other methods. This pattern is called a Template Method, and you'll see // the benefits later on. GreetingStrategy.prototype.execute = function() { return this.sayHi() this.sayBye(); }; GreetingStrategy.prototype.sayHi = function() { return Hello, ; }; GreetingStrategy.prototype.sayBye = function() { return Goodbye.; }; // We can already try out our Strategy. It requires a little tweak in the // Greeter class before, though. Greeter.prototype.greet = function() { return this.strategy.execute(); }; var greeter = new Greeter(new GreetingStrategy()); greeter.greet() //= 'Hello, Goodbye.'   通過使用類,我們與anexecutemethod對象定義了一個策略。

客戶端可以使用任何策略實現該接口。

  同樣注意我又是怎樣創建GreetingStrategy的。

有趣的部分是對methodexecute的重載。

它以其他函數的形式定義。

現在類的后繼子類可以改變特定的行為,如thesayHiorsayByemethod,并不改變常規的算法。

這種模式叫做模板方法,非常適合策略模式。

  讓我們看個究竟。

  ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 // Since the GreetingStrategy#execute method uses methods to define its algorithm, // the Template Method pattern, we can subclass it and simply override one of those // methods to alter the behavior without changing the algorithm. var PoliteGreetingStrategy = function() {}; PoliteGreetingStrategy.prototype = Object.create(GreetingStrategy.prototype); PoliteGreetingStrategy.prototype.sayHi = function() { return Welcome sir, ; }; var FriendlyGreetingStrategy = function() {}; FriendlyGreetingStrategy.prototype = Object.create(GreetingStrategy.prototype); FriendlyGreetingStrategy.prototype.sayHi = function() { return Hey, ; }; var BoredGreetingStrategy = function() {}; BoredGreetingStrategy.prototype = Object.create(GreetingStrategy.prototype); BoredGreetingStrategy.prototype.sayHi = function() { return sup, ; }; var politeGreeter = new Greeter(new PoliteGreetingStrategy()); var friendlyGreeter = new Greeter(new FriendlyGreetingStrategy()); var boredGreeter = new Greeter(new BoredGreetingStrategy()); politeGreeter.greet(); //= 'Welcome sir, Goodbye.' friendlyGreeter.greet(); //= 'Hey, Goodbye.' boredGreeter.greet(); //= 'sup, Goodbye.'   GreetingStrategy 通過指定theexecutemethod的步驟,創建了一個類的算法。

在上面的代碼片段中,我們通過創建專門的算法從而利用了這一點。

  沒有使用子類,我們的Greeter 依然展示出一種多態行為。

沒有必要在Greeter 的不同類型上進行切換來觸發正確的算法。

這一切都綁定到每一個Greeter 對象上。

  ? 1 2 3 4 5 6 7 8 9 10 11 12 13 var greeters = [ new Greeter(new BoredGreetingStrategy()), new Greeter(new PoliteGreetingStrategy()), new Greeter(new FriendlyGreetingStrategy()), ]; greeters.forEach(function(greeter) { // Since each greeter knows its strategy, there's no need // to do any type checking. We just greet, and the object // knows how to handle it. greeter.greet(); });   多環境下的策略模式  我最喜歡的有關策略模式的例子之一,實在 Passport.js庫中。

Passport.js提供了一種在Node中處理身份驗證的簡單方式。

大范圍內的供應商都支持(Facebook, Twitter, Google等等),每一個都作為一種策略實現。

  該庫作為一個npm包是可行的,其所有的策略也一樣。

庫的用戶可以決定為他們特有的用例安裝哪一個npm包。

下面是展示其如何實現的代碼片段:  ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 // Taken from http://passportjs.org var passport = require('passport') // Each authentication mechanism is provided as an npm package. // These packages expose a Strategy object. , LocalStrategy = require('passport-local').Strategy , FacebookStrategy = require('passport-facebook').Strategy; // Passport can be instanciated using any Strategy. passport.use(new LocalStrategy( function(username, password, done) { User.findOne({ username: username }, function (err, user) { if (err) { return done(err); } if (!user) { return done(null, false, { message: 'Incorrect username.' }); } if (!user.validPassword(password)) { return done(null, false, { message: 'Incorrect password.' }); } return done(null, user); }); } )); // In this case, we instanciate a Facebook Strategy passport.use(new FacebookStrategy({ clientID: FACEBOOK_APP_ID, clientSecret: FACEBOOK_APP_SECRET, callbackURL: http://www.example.com/auth/facebook/callback }, function(accessToken, refreshToken, profile, done) { User.findOrCreate(..., function(err, user) { if (err) { return done(err); } done(null, user); }); } ));   Passport.js庫只配備了一兩個簡單的身份驗證機制。

除此之外,它沒有超過一個符合上下文對象的一個策略類的接口。

這種機制讓他的使用者,很容易的實現他們自己的身份驗證機制,而對項目不產生不利的影響。

  反思  策略模式為你的代碼提供了一種增加模塊化和可測性的方式。

這并不意味著(策略模式)總是有效。

Mixins 同樣可以被用來進行功能性注入,如在運行時的一個對象的算法。

扁平的老式 duck-typing多態有時候也可以足夠簡單。

  然而,使用策略模式允許你在一開始沒有引入大型體系的情況下,隨著負載型的增長,擴大你的代碼的規模。

正如我們在Passport.js例子中看到的一樣,對于維護人員在將來增加另外的策略,將變得更加方便。

版權聲明:本文由 靖子凡 整理編輯。

原標題:策略模式實例,策略模式的優點

轉載注明出處:http://www.dn9ww09s.icu/fault/15233.html

文章評論

    共有條評論來說兩句吧...

    用戶名:

    驗證碼:

作者推薦

  • HTTP協議是,什么是HTTP協議

    HTTP協議是,什么是HTTP協議 相關圖片http基于什么協議HTTP協議是由Tim Berners-Lee發明的,他被稱為web之父。HTTP協議完全基于文本。瀏覽器通過HTTP協議與服務器交互,默認為端口80。您還可以HTTP協議稱為...

  • 點擊按鈕跳轉,如何快速點擊頁面的按鈕

    點擊按鈕跳轉,如何快速點擊頁面的按鈕 相關圖片點擊按鈕彈出輸入框本文主要介紹jQuery實現按鈕點擊全選/取消全選單選框/復選框文本框表單驗證的相關資料。對于您的朋友,請參閱jQuery實現按鈕單擊全選/取消選擇單選框/復選點擊按...

  • php explode函數,matlab中explode函數

    php explode函數,matlab中explode函數 相關圖片matlab中explode關于PHP split string expand函數的用法,使用expand函數將字符串拆分成數組。這里有幾個例子供你參考。PHP數組和擴展函數應用程序示例供strreplace函數...

  • 此頁面需要在極速模式下顯示,極速模式怎么設置

    此頁面需要在極速模式下顯示,極速模式怎么設置 相關圖片找不到兼容性視圖設置標題:JSP頁面查詢顯示通用模式作者:Evan郵箱:Evan[[email protected]背景:1。需要在JSP中以列表模式2顯示數據庫查詢結果。在良好的J極速360切換不了兼容模式...

  • 名詞解釋,LAK名詞解釋

    名詞解釋,LAK名詞解釋 相關圖片標準預防的名詞解釋本文主要介紹Python中幾種常見的名詞解釋。這種解釋也適用于其他編程語言。本文解釋了loop、iteration、recursion、traversal等名詞病理名詞解釋...

  • excel函數實例教程,函數

    excel函數實例教程,函數 相關圖片excel函數運用教程ASP函數和ASP過程提供了一種方法來創建可用于重新編程代碼的模塊,并避免在執行特定任務時一次重寫一個塊的代碼。如果在ASP頁中沒有任何函數/程序,則當ASP頁coun...

  • 2c,8c

    2c,8c 相關圖片1c本文主要介紹C?webclient類的使用實例。本文介紹如何使用webclient下載文件,openwriter打開流,使用指定的方法將數據寫入URI并上載文件c點...

  • 解決中文亂碼問題,怎么解決中文亂碼問題

    解決中文亂碼問題,怎么解決中文亂碼問題 相關圖片文件亂碼怎么解決一、安裝網易博客網友制作的Sublimitext3優化版和Sublimitext2優化版,深度集成GBK編碼,完美解決中文亂碼問題,比官方版本更適合家庭使用環境網頁中文變成亂碼...

  • 交互開發,小程序開發交互

    交互開發,小程序開發交互 相關圖片javaweb交互系統開發教程一。基本知識:1。意圖對象包含一組信息:1。組件名稱指定要啟動的活動2。做什么動作3。數據傳輸4。第5類。附加鍵值對前端數據交互...

  • selectcase怎么用,select case

    selectcase怎么用,select case 相關圖片select case結構如果語句選擇報表,則工作原理相同。但是,區別在于它們可以檢查多個值。當然,如果。。。其他的說法,但這并不總是最好的方法。select語句允許程序計算表達式,并嘗...

熱評文章

  • 異步機制,異步處理機制

    異步機制,異步處理機制 相關圖片異步本文主要介紹對JavaScript編程中同步和異步機制的深入理解。不僅Ajax已經滲透到了各個角落,而且node.js的流行也使得js異步編程特別具有吸引力。可異步任務處理機制理解...

  • oracle節點,oracle怎么看所有節點

    oracle節點,oracle怎么看所有節點 相關圖片oracle遞歸查詢子節點Select trans ID from trans Inst, where connect by IsLeaf = 1 starts from trans ioracle查詢子節點...

  • 漢字編碼中不支持,漢字編碼的敘述中錯誤的是

    漢字編碼中不支持,漢字編碼的敘述中錯誤的是 相關圖片下列關于微型機中漢字編碼的敘述關于JSP/servlet中的DBCS字符編碼在Internet上有很多優秀的文章和討論。本文對它們進行了一些整理,并對ibmwebsphereapplicat漢字庫中儲存漢字的編碼是...

  • oracle數據庫基礎,oracle創建數據庫

    oracle數據庫基礎,oracle創建數據庫 相關圖片oracle數據庫怎么打開甲骨文1。(1)SQL*plus命令行工具(注意:在啟用反斜杠(/)之前必須添加空格):(2)運行命令2。連接到Oracle數據庫(1)SQL*plus連接成功orical數據庫...

  • 如何獲取地址欄參數,如何在地址欄添加參數

    如何獲取地址欄參數,如何在地址欄添加參數 相關圖片asp 加密地址欄參數ASP get address bar參數代碼====================函數名:joinchar角色:add?或者參數:strurl----URLjs獲取地址欄參數...

  • file exists,file exists 什么意思

    file exists,file exists 什么意思 相關圖片exists在本文中,我們將解釋PHP中的文件存在函數,以確定文件或目錄是否存在。我們會附上一些經典的例子,你可以參考它,如果你需要的話。描述:BooFieleI存在(Stfile.separator...

  • visibility,htmlvisibility

    visibility,htmlvisibility 相關圖片high visibility本文演示了jQuery可見性過濾器:hidden和:visibility的用法。與您分享以供參考。具體分析如下:隱藏匹配所有不可見元素。如果使用CSS的visiadvisability...

  • 電腦文件夾代碼,文件代碼

    電腦文件夾代碼,文件代碼 相關圖片文件夾刪除主要任務是獲取當前目錄的路徑,然后確定文件夾是否存在。如果不是,創建它。Define('dir'root',str'replace(','/',dirname(文件夾軟件...

  • aspmvc文件上傳,asppost文件上傳

    aspmvc文件上傳,asppost文件上傳 相關圖片asp上傳組件一、解決方案:IE7或更高版本實際上可以選擇是否發送完整的本地路徑進行文件上傳,可以在IE的Internet選項中設置,如下圖所示:1。互聯網安全選項:2。完整asp文件上傳繞...

  • php關鍵字,php定義靜態變量的關鍵字

    php關鍵字,php定義靜態變量的關鍵字 相關圖片php 多繼承本文的例子描述了PHP自動獲取關鍵字的方法。與您分享以供參考。具體實現方法如下:代碼如下:$mincipin=5;//最小詞頻為$minlen=4;//最小關鍵php超全局變量...

關注微信

变脸官网查询