大家好呀,今天阴云密布,杭州闪过3816次闪电,仔细一看,原来组成四个大字:设计模式!
今天又是设计模式的一天,洪爵今天想讲的是策略模式呀。
策略模式是一种行为性模式,这类的设计模式特别关注对象之间的通信。
什么是策略模式,啥时候用策略模式?
比如说,当你做一个计算的时候,你可能使用到,加法,减法,乘法或者除法,那么说到底,加减乘除本身就是一种算法,算法本身只是一种策略;当你要出行,步行、自行车、高铁、飞机等都是出行方式的一种,本身也是一种策略。
当有这样类似的算法,我们就把这些算法抽象出一个具体执行的方法,这个执行方法由具体的策略类去实现和管理。然后所有的策略类由统一的Context上下文来屏蔽内部细节,同时提供算法的直接访问。
在定义了一系列的算法后,就可以灵活的相互替换,避免使用多重判断条件,拓展性好。
但是也有缺点,对应的具体策略类会增多,并且需要对外暴露。这里举个例子来解释使用了策略模式的好处。
class Calculator {
public int operation(int op1, int op2, int type) {
if(type == 1) {
return op1 + op2;
} else if(type == 2) {
return op1 - op2;
} else if(type == 3) {
// ....
} else if(type == 4) {
// ....
}
}
}
如果你没有使用策略模式,那么你想要实现计算,你就需要多重判断是什么类型的计算,然后返回对应的答案,并且后续增加了计算的方式,你还需要修改原有的代码,违背了开闭原则(对拓展开放,对修改关闭)。
那么如果我们使用了策略模式,这个框架结构会是怎么样的呢?
public class Main {
public static void main(String[] args) throws Exception {
Context context = new Context(new Add());
System.out.println(context.executeOperation(1, 2));
context = new Context(new Sub());
System.out.println(context.executeOperation(1, 2));
}
}
interface Calculator {
int operation(int op1, int op2);
}
class Context {
Calculator calculator;
public Context(Calculator calculator) {
this.calculator = calculator;
}
public int executeOperation(int num1, int num2) {
return calculator.operation(num1, num2);
}
}
class Add implements Calculator {
@Override
public int operation(int op1, int op2) {
return op1 + op2;
}
}
class Sub implements Calculator {
@Override
public int operation(int op1, int op2) {
return op1 - op2;
}
}
/*
3
-1
*/
这只是比较简单策略模式实现,我们现在讨论稍微复杂些的场景,加深大家的印象,大家在平常购物的时候,购买一个商品,可能是以原价的方式去购买,可能是有打折,或者满xxx元返yyy元等等,都是一种营销活动,那么这些本身其实也是一种策略。那么用策略模式要如何实现呢?
类图
具体代码:
public abstract class Strategy {
// 具体行为(算法 营销活动等等)
public abstract double operation(double money);
}
public class NormalStrategy extends Strategy {
// 原价
@Override
public double operation(double money) {
return money;
}
}
public class DiscountStrategy extends Strategy {
// 折扣 默认10折
private double discount = 1;
public DiscountStrategy(double discount) {
this.discount = discount;
}
@Override
public double operation(double money) {
return money * discount;
}
}
public class RefundStrategy extends Strategy {
// 满lowerLimitMoney 返 refundMoney
// 返利条件
private double lowerLimitMoney;
// 返回金额
private double refundMoney;
public RefundStrategy(double lowerLimitMoney, double refundMoney) {
this.lowerLimitMoney = lowerLimitMoney;
this.refundMoney = refundMoney;
}
@Override
public double operation(double money) {
if(money >= refundMoney) {
return money - Math.floor(money / lowerLimitMoney) * refundMoney;
} else {
return money;
}
}
}
public class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public double getCash(double money) {
return strategy.operation(money);
}
}
public class client {
public static void main(String[] args) {
Context context = new Context(new NormalStrategy());
// 商品A卖100元
double price = 100;
System.out.println("100元商品正常收费 = " + context.getCash(price));
// 商品A打五折
context = new Context(new DiscountStrategy(0.5));
System.out.println("100元商品打五折后收费 = " + context.getCash(price));
// 购买数量
int num = 5;
// 满400 返 100
context = new Context(new RefundStrategy(400, 100));
System.out.println("满400 返 100 活动, 购买了" + num + "件, 每件" + price + "元, 现收费 = " + context.getCash(num * price));
}
}
/*
100元商品正常收费 = 100.0
100元商品打五折后收费 = 50.0
满400 返 100 活动, 购买了5件, 每件100.0元, 现收费 = 400.0
*/
我们可以总结出,如果说一个系统有很多类,并且区别只在于它们行为的不同,那么使用策略模式可以动态的选择其中一种行为。
好啦,本篇文章就是这么多啦,希望对你有所帮助!
愿每个人都能带着怀疑的态度去阅读文章并探究其中原理。
道阻且长,往事作序,来日为章。
期待我们下一次相遇!