前後端視角看設計模式——策略模式

 

 

設計模式是經驗之談,對某些需求情況下的良好實踐進行了歸納,雖然並非必須遵守的準則,卻能對我們解決各類問題提供指引。不同語言擁有不同特性,對各類設計模式的支持度不盡相同,比如原型模式在js中是天然實現的,java也有內置的迭代器模式——有些泛用性強的模式,經過長年累月重複使用,最終會被固化到語言中。

對不同語言使用的多了,常常能感受到不同特性間的相互碰撞。於是筆者想借助前後端兩門代表性語言js和java,對設計模式進行多角度觀察,希望給自己和讀者帶來些許啓發。

先從最經典的策略模式入手,java實現策略模式是科班出身的程序員們的基礎技能點——先通過面向接口方式抽象出一個類略類,繼而通過多態完成具體策略的綁定,從而可以切換不同策略。還是以經典的工資計算爲例,已知基本工資,不同員工有不同提成。

public interface Strategy {
   public int calculateSalary(int num);
}
public class Strategy1 implements Strategy{
   @Override
   public int calculateSalary(int num) {
      return 3*num;
   }
}
public class Strategy2 implements Strategy{
   @Override
   public int calculateSalary(int num) {
      return 2*num;
   }
}

外部一個公司類負責調用策略計算工資:

public class Company{
   private Strategy strategy;

   public Company(Strategy strategy){
      this.strategy = strategy;
   }

   public int calculateSalary(int num){
      return strategy.calculateSalary(num);
   }
}

java實現,結構非常明晰,不過每個策略對應一個類,而這個類僅僅維護一個算法而已,略顯笨重。

js本身是動態類型語言,達到和java一樣的面向對象和多態效果並不用抽象接口,只要每個對象各自實現calculateSalary方法即可:

let strategy1 = function(){};
strategy1.prototype.calculateSalary = function(num){
    return 3*num;
}
let strategy2 = function(){};
strategy1.prototype.calculateSalary = function(num){
    return 2*num;
}

 然而這本質上和java並沒有什麼區別,但別忘了js的函數式特性,函數也是第一對象,這和java有本質不同,於是策略類可以直接簡化成方法形式:

let strategy1(num){
    return 3*num;
};
let strategy2(num){
    return 2*num;
};
let strategies = {
    strategy1,
    strategy2
}

let calculateSalary(level,num){
    return strategies[level](num);
};

這裏的calculateSalary對應着java中的公司類。

對比看來,js由於函數式特性的緣故,對策略模式的支持比java簡潔,策略模式已經平滑滲透進js的方方面面,但這並不代表js比java優秀,畢竟嚴格聲明類的方式能使項目結構更加清晰便於維護。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章