策略模式

时势造英雄-策略模式

模式简介

策略模式定义了一系列的算法,并将每一个算法独立封装起来,而且使它们还可以相互替换。策略模式让算法独立于它的客户而独立变化

使用场景

  • 针对同一类型问题的多种处理方式,仅仅是具体行为有差别时。
  • 需要安全的封装多种同一类型的操作时
  • 出现同一抽象类有多个子类,而又需要使用if-else或者switch-case来选择子类时

简单实现

以计算公交车和地铁票价为例子

计算接口

1
2
3
4
public interface CalculateStrategy {
    //根据距离计算价格
    int calculatePrice(int km);
}

公交车计算

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
//公交车的价格计算策略
public class BudStrategy implements CalculateStrategy {
    //10公里内1元,超过10公里每5公里加收1元
    public int calculatePrice(int km) {
        int extraTotal = km -10;
        int extraFactor = extraTotal/5;
        int fraction=extraTotal%5;
        //价格计算,分段式计价
        int price=1+extraFactor*1;
        return fraction>0?++price:price;
    }
}

地铁计算

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
//地铁的价格计算策略
public class SubwayStrategy implements CalculateStrategy {
    public int calculatePrice(int km) {
        //6公里内3元,6~12 4元  12~22 5元  22~32 6元
        if(km<=6){
            return 3;
        }else if(km>6&&km<12){
            return 4;
        }else if(km>12&&km<22){
            return 5;
        }else if(km>22&&km<32){
            return 6;
        }
        //其他距离简化7元
        return 7;
    }
}

调用实现的测试类

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
public class TranficCalculator {
    public static void main(String[] args) {
        TranficCalculator tranficCalculator=new TranficCalculator();
        //设置策略
        tranficCalculator.setCalculateStrategy(new BudStrategy());
        int price=tranficCalculator.calculatePrice(16);
        System.out.println("公交车乘坐16公里的价格"+price);
    }
    CalculateStrategy mCalculateStrategy;
    public void setCalculateStrategy(CalculateStrategy calculateStrategy){
        this.mCalculateStrategy=calculateStrategy;
    }
    public int calculatePrice(int km){
        return mCalculateStrategy.calculatePrice(km);
    }
}

执行结果

show.png

总结

​ 建立抽象,将不同的策略构建成一个具体策略实现,通过不同的策略实现算法替换。在简化逻辑、结构的同时,增强了系统的可读性、稳定性、可拓展性、这对于较为复杂的业务显得更为直观,拓展也更为方便

优点

  1. 结构清晰明了,使用简单直观
  2. 耦合度相对而言降低,拓展方便
  3. 操作封装也更为彻底,数据更为安全

缺点

  1. 随着策略的增加,子类也会变得繁多