使用场景
如果通常一个问题会因为多种因素而选择不同的方案。对于这种情况,最直接的方法就是直接用if-else或者switch-case来做处理。但是对于这种方式来解决问题,主要的缺点就是代码臃肿,耦合性高,难以维护,可读性差。
假如由于项目的要求,代码里会涉及到大量的逻辑,判断。或者需要增加一个解决方案时。怎么做才能使德代码对于修改是关闭的,扩展是开放的。也就是遵循接口的开闭原则?
策略模式就是为了解决这种问题。把各种方案分隔开来,让程序根据具体的需求选择不同的方案。
类图
具体实现
public interface CaculateStrategy {
//计算价格
int caculatePrice(int km);
}
//公交车计算策略
public class BusStragety implements CaculateStrategy{
/**
* 公家车计价策略 十公里之内2 元 十公里之外 每增加5公里 价格增加 1元
*/
public int caculatePrice(int km) {
//超过5公里的总距离
int extraTotal = km-10;
//超过的距离是5公里的倍数
int extraFactor = extraTotal/5;
//超过的距离对5公里取余
int fraction = extraTotal%5;
//超过的距离是5公里的倍数
int price = 1+extraFactor*1;
return fraction>0?++price:price;
}
}
//地铁价格计算策略
public class SubwayStragety implements CaculateStrategy{
/**
* 6公里3元 6-12公里4元 12-22公里5元 22-32公里6元
*/
public int caculatePrice(int km) {
if(km<=6){
return 3;
}else if(km>=6&&km<12){
return 4;
}else if(km>=12&&km<22){
return 6;
}else if(km>=22&&km<32){
return 6;
}
return 7;
}
}
public class Client {
CaculateStrategy strategy;
public static void main(String[] args) {
Client client = new Client();
client.setStrategy(new BusStragety());
System.out.println("公交车乘坐12公里的价格为:"+client.caculatePrice(12));
}
public void setStrategy(CaculateStrategy strategy) {
this.strategy = strategy;
}
public int caculatePrice(int km){
return strategy.caculatePrice(km);
}
}
这么做就避免了耦合,并且能扩展。而如果不这么做。看下面。
public class CaculatePrice {
private final int BUS=5;
private final int SUBWAY=6;
public static void main(String[] args) {
CaculatePrice caculateStrategy = new CaculatePrice();
int price = caculateStrategy.setCurrentType(caculateStrategy.BUS, 15);
System.out.println("乘坐公交15公里价格为:"+price);
}
/**
* 设置乘坐种类和公里数
* @param type
* @param km
*/
private int setCurrentType(int type,int km){
if(type ==5){
return caculateBusPrice(km);
}else if(type ==6){
return caculateSubWayPrice(km);
}
return 0;
}
private int caculateSubWayPrice(int km) {
if(km<=6){
return 3;
}else if(km>=6&&km<12){
return 4;
}else if(km>=12&&km<22){
return 6;
}else if(km>=22&&km<32){
return 6;
}
return 7;
}
private int caculateBusPrice(int km) {
//超过5公里的总距离
int extraTotal = km-10;
//超过的距离是5公里的倍数
int extraFactor = extraTotal/5;
//超过的距离对5公里取余
int fraction = extraTotal%5;
//超过的距离是5公里的倍数
int price = 1+extraFactor*1;
return fraction>0?++price:price;
}
}
这段代码如果想增加计程车的计费方式,那么就要修改代码逻辑才可以。而采用策略模式,就不用修改。可以直接定义一个类继承抽象的计费类。