Chapter3: 策略模式 (Strategy Pattern)
This section contain the following items:
1.Strategy Pattern
2.Strategy Pattern Example
1.Strategy Pattern
策略模式所要解決的問題(痛點)
1.在一個專案中的不同物件, 如果其80%屬性相同, 但在某些方面有差異, 若全部分為不同的類別來寫,勢必會造成維護不易及程式碼不一致的問題.
2.在一個專案中的不同物件, 其屬性有互相重複使用的情形.例如有三個動物, A,B的叫聲相同, B,C的飛行方式相同, 如果分別實作三個class, 則會有很多function是重複的. 我們已經知道code重複的後遺症:維護不易, 無法維持一致性.
3.如果為了解決2的問題, 使用繼承, 考量下面一種情況可能會發生:
A動物並不會飛, D動物也不會叫, 這麼一來必須在這兩個類別的這些function中取消繼承而來的行為, 一個漏掉就會變成bug; 而且重複的function還是必須得複製貼上,如A,B的叫聲相同, 一樣會有維護不異, 無法維持一致性的問題.
策略模式的核心概念
1.找出程式中可能需要變動之處, 把他們獨立出來, 不要與那些不需要更動的程式碼混在一起.
例如:
可以這樣拆分class:
2.寫程式是針對介面(超類別)而寫, 而不是針對實踐方法而寫
介面, 超類別, 多型:
實體化的動作不再需要程式碼中僵化固定成某型態, 而是在runtime時才決定:
Animal animal = new dog(); animal.makeSound();
合成代替繼承
若使用策略模式來套用上述範例, 則可以解決繼承所帶來的問題, 也可以重複使用已經寫好的程式碼:
2.Strategy Pattern Example:
以Javascript為例:
1.以物件導向模式的寫法實作: 架構上可分為策略物件與主體物件
//策略類別 var animalA = function(){}; animalA.prototype.bark = function (){ return "呱呱" } animalA.prototype.fly = function (){ return "展翅高飛" } var animalB = function(){}; animalB.prototype.bark = function (){ return "呱呱" } animalB.prototype.fly = function (){ return "滑翔" } var animalC = function(){}; animalC.prototype.bark = function (){ return "嘰嘰" } animalC.prototype.fly = function (){ return "滑翔" } //主體類別 var animal = function(){ this.animal = null; } animal.prototype.setType = function (animal){ this.animal = animal; } animal.prototype.bark = function (){ console.log(this.animal.bark()); } animal.prototype.fly = function (){ console.log(this.animal.fly()); } //test var littleAnimal = new animal(); littleAnimal.setType(new animalA()); littleAnimal.bark(); littleAnimal.fly();
//2.以Javascript的寫法實作 //策略物件 var barks ={ "animalA": function (){ return "呱呱" }, "animalB": function (){ return "呱呱" }, "animalC": function (){ return "嘰嘰" } } var flys ={ "animalA": function (){ return "展翅高飛" }, "animalB": function (){ return "滑翔" }, "animalC": function (){ return "滑翔" } } //主體物件 var action = function(actions, type){ console.log(actions[type]()); } action(barks, "animalA") action(flys, "animalA")
Last updated
Was this helpful?