定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换
为什么用?
当你写代码的时候发现一个操作有好多种实现方法,而你需要根据不同的情况使用if-else
等分支结构来确定使用哪种实现方式的时候,想一想这个模式。
什么时候使用?
一个操作有好多种实现方法
怎么用?
业务场景
乘坐不同的方式去旅游
public class TrafficFeeCalculator {
public int goToTianJinEye(String way, int distance) {
int trafficFee = 0;
switch (way) {
case "bus":
if (distance < 10)
trafficFee = 4;
else
trafficFee = 6;
break;
case "didi":
if(distance<3)
trafficFee = 8;
else
trafficFee=8+(distance-3)*3;
break;
case "sharedBicyle":
trafficFee = 2;
break;
default:
break;
}
return trafficFee;
}
}
那么这么写有什么弊端呢?
第一:每一种出行方式的交通花费的计算方式都写在了TrafficFeeCalculator
类中,这个类承担的职责较多,违反了单一职责原则。
第二:假如王二狗突然想自己开车去,那就需要修改goToTianJinEye
这个方法了。违反了开闭原则。
使用策略模式
将多种不同的实现算法封装,然后客户端根据不同策略分别调用相应的算法
第一步:封装不同的实现算法 首先定义一个策略接口,规定算法的同一操作
public interface CalculateStrategy {
int calculateTrafficFee(int distance);
}
第二步:封装各个算法
//乘坐公交车算法
public class ByBus implements CalculateStrategy {
@Override
public int calculateTrafficFee(int distance) {
return distance<10?4:6;
}
}
//乘坐滴滴快车算法
public class ByDiDiExpress implements CalculateStrategy {
@Override
public int calculateTrafficFee(int distance) {
return distance<3?8:(8+(distance-3)*3);
}
}
//骑共享单车算法
public class BySharedBicycle implements CalculateStrategy {
@Override
public int calculateTrafficFee(int distance) {
return 2;
}
}
第三步:使用算法
public class TrafficFeeCalculator {
...
public int goToTianJinEye(CalculateStrategy strategy,int distance){
return strategy.calculateTrafficFee(distance);
}
}
第四步:客户端调用 根据情况,构建相应的算法类实例,传入计算器计算即可
第四步:客户端调用 根据情况,构建相应的算法类实例,传入计算器计算即可
public static void main(String[] args) {
TrafficFeeCalculator calculator=new TrafficFeeCalculator();
System.out.println(String.format("乘坐公交车到天津之眼的花费为:%d块人民币",
calculator.goToTianJinEye(new ByBus(),10)));
System.out.println(String.format("乘坐滴滴快车到天津之眼的花费为:%d块人民币",
calculator.goToTianJinEye(new ByDiDiExpress(),10)));
System.out.println(String.format("骑共享单车到天津之眼的花费为:%d块人民币",
calculator.goToTianJinEye(new BySharedBicycle(),10)));
}
输出为:
乘坐公交车到天津之眼的花费为:6块人民币
乘坐滴滴快车到天津之眼的花费为:29块人民币
骑共享单车到天津之眼的花费为:2块人民币
优缺点
优点:解决开闭原则,单一职责
缺点:复杂性增大