Java中的设计模式-二(策略模式)

78 阅读2分钟

释义

  策略模式和第一节的工厂模式很像,这个看到后面就会了解。所以这里继续使用工厂模式编写的商场促销做一定的修改。之所以要修改,需要先考虑使用工厂模式编写的促销程序有什么痛点需要解决。工厂模式,通过上一节的学习,可以了解到,是一个生产对象的工厂设计模式。对象创建完成,那么它可以做的事情就已经确定了,如果我们要定义行为的可变性,那么工厂模式产生的对象无法满足我们的需求,通过案例来看下区别即了解其中意义。

案例

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即可,耦合更加降低。返回最开始的问题,如果我们要对算法做特殊处理,在策略模式中,就不需要修改所有的计算类。只需要修改策略类里面的调用逻辑即可。两种模式的相似度极高,所以在没有特殊情况处理的情况下,两种方式可以结合使用或者互换使用。
  从含义上来说策略模式和工厂模式最大的区别是,工厂模式是对对象本身的一种封装,策略模式是对行为的一种封装,在该案例中,不同的促销方式更是一种金额计算行为的不同分类。所以更加适合用策略模式来处理。 image.png