释义
策略模式和第一节的工厂模式很像,这个看到后面就会了解。所以这里继续使用工厂模式编写的商场促销做一定的修改。之所以要修改,需要先考虑使用工厂模式编写的促销程序有什么痛点需要解决。工厂模式,通过上一节的学习,可以了解到,是一个生产对象的工厂设计模式。对象创建完成,那么它可以做的事情就已经确定了,如果我们要定义行为的可变性,那么工厂模式产生的对象无法满足我们的需求,通过案例来看下区别即了解其中意义。
案例
public abstract class CashSuper {
public abstract double acceptCash(double price, int num);
}
public class CashNormal extends CashSuper {
@Override
public double acceptCash(double price, int num) {
return price * num;
}
}
public class CashRebate extends CashSuper {
private double zk;
public CashRebate(double zk) {
this.zk = zk;
}
@Override
public double acceptCash(double price, int num) {
return price * num * zk;
}
}
public class CashReturn extends CashSuper {
private double m;
private double j;
public CashReturn(double m, double j) {
this.m = m;
this.j = j;
}
@Override
public double acceptCash(double price, int num) {
double total = price * num;
if (total >= m) {
total -= Math.floor(total / m) * j;
}
return total;
}
}
这里继续使用这三种计算方式,以及父类。不同的是,这里既然不再使用工厂模式,那么CashFactory就不再使用了。我们使用一个Context类,维护一个对CashSuper对象的使用。
public class CashContext {
private CashSuper cs;
public CashContext(int s) {
switch (s) {
case 1:
cs = new CashNormal();
break;
case 2:
cs = new CashRebate(0.8);
break;
case 3:
cs = new CashReturn(300, 100);
break;
}
}
public double getResult(double price, int num) {
return cs.acceptCash(price, num);
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int s = Integer.parseInt(scanner.nextLine());
CashContext cashContext = new CashContext(2);
double result = cashContext.getResult(200, 2);
System.out.println(result);
}
策略模式和工厂模式差别
这里把客户端和工厂模式的写法做一个对比。
//策略模式
CashContext cashContext = new CashContext(2);
double result = cashContext.getResult(200, 2);
//工厂模式
CashSuper sf = CashFactory.getSf(s);
double result = sf.acceptCash(200, 2);
可以发现一个问题,简单工厂需要让客户端认识两个类,而策略模式只需要操作一个CashContext即可,耦合更加降低。返回最开始的问题,如果我们要对算法做特殊处理,在策略模式中,就不需要修改所有的计算类。只需要修改策略类里面的调用逻辑即可。两种模式的相似度极高,所以在没有特殊情况处理的情况下,两种方式可以结合使用或者互换使用。
从含义上来说策略模式和工厂模式最大的区别是,工厂模式是对对象本身的一种封装,策略模式是对行为的一种封装,在该案例中,不同的促销方式更是一种金额计算行为的不同分类。所以更加适合用策略模式来处理。