萬盛學電腦網

 萬盛學電腦網 >> 腳本專題 >> javascript >> 詳解JavaScript的策略模式編程

詳解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 i
copyright © 萬盛學電腦網 all rights reserved