前后端视角看设计模式——策略模式

设计模式是经验之谈,对某些需求情况下的良好实践进行了归纳,虽然并非必须遵守的准则,却能对我们解决各类问题提供指引。不同语言拥有不同特性,对各类设计模式的支持度不尽相同,比如原型模式在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优秀,毕竟严格声明类的方式能使项目结构更加清晰便于维护。

发布了71 篇原创文章 · 获赞 31 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/m0_37828249/article/details/102795016