设计模式学习笔记 ———— 策略模式+简单工厂模式

背景

接受到一个商场收银系统的续期,客户那边说需要做一个收银软件,根据客户所购买的单价和数量进行计算应该收多少钱。做完一版之后客户要求增加打折功能,然后还需要支持满减功能。
起初我的涉及思路是这样的,创建一个公共的接口根据type判断当前使用哪一种收款模式,然后选择对应的函数来计算所需要收的现金。

简单工厂模式

因为之前学习了简单工厂模式,觉得这种场景下也比较适用简单工厂模式,于是产生了以下的代码;先创建一个收费的父类。

public abstract class CashSuper {
    private int nums;
    private double price;
    protected abstract double acceptCash(double money);
}

然后分别定义普通收款模式、打折收款模式和满减模式三个类

class NormalCash extends CashSuper {

    @Override
    protected double acceptCash(double money) {
        return money;
    }
}

class RebateCash extends CashSuper {

    private double rebate;

    public RebateCash(double rebate) {
        this.rebate = rebate;
    }

    @Override
    protected double acceptCash(double money) {
        return money * rebate;
    }
}

class ReturnCash extends CashSuper {

    private double moneyCondition = 0.0;
    private double moneyReturn = 0.0;

    public ReturnCash(double moneyCondition, double moneyReturn) {
        this.moneyCondition = moneyCondition;
        this.moneyReturn = moneyReturn;
    }

    @Override
    protected double acceptCash(double money) {
        return money - Math.floor(money / moneyCondition) * moneyReturn;
    }
}

然后创建一个收款工厂就可以了

class CashFactory {
    public static CashSuper createAcceptCasg(int type) {
        CashSuper cashSuper;
        switch (type) {
            case 0:
                cashSuper = new NormalCash();
                break;
            case 1:
                cashSuper = new RebateCash(0.7);        // 打七折
                break;
            case 2:
                cashSuper = new ReturnCash(100, 50);        // 满100减50
                break;
            default:
                cashSuper = new NormalCash();
        }
        return cashSuper;
    }

}

这种模式下虽然也能解决这个需求,但是这个模式只是解决对象的创建问题,而且由于工厂本身也包括了所有的收费方式,商场是可能会经常性的更改打折额度和返利刻度,每次维护或者扩展都需要改动这个工厂,以致于代码需要重新编译部署,这真的是一种很糟糕的处理方式,所以它不是最好的办法。

策略模式

面对算法的经常性的变动,应该使用策略模式。
** 策略模式 定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化不会影响使用时u案发的客户**
代码如下:客户端只需要调用这段代码即可完成,但是需要通过客户端判断使用哪个算法

class CashContexts {
    private CashSuper cashSuper;

    public CashContexts(CashSuper cashSuper) {
        this.cashSuper = cashSuper;
    }

    public double getReesult(double money) {
        return cashSuper.acceptCash(money);
    }
}

客户端:

public static void main(String[] args) {
        CashContexts cashContexts;
        double money = 100;
        int type = 0;
        switch (type) {
            case 0:
                cashContexts = new CashContexts(new NormalCash());
                break;
            case 1:
                cashContexts = new CashContexts(new RebateCash(0.7));
                break;
            case 2:
                cashContexts = new CashContexts(new ReturnCash(100,50));
                break;
            default:
                cashContexts = new CashContexts(new NormalCash());;
        }

        double reesult = cashContexts.getReesult(money);
        System.out.println(reesult);
    }

策略模式与简单工厂模式结合

class CashContextt {
    private CashSuper cashSuper;

    public CashContextt(Integer type) {
        switch (type) {
            case 0:
                cashSuper = new NormalCash();
                break;
            case 1:
                cashSuper = new RebateCash(0.7);
                break;
            case 2:
                cashSuper = new ReturnCash(100,50);
                break;
            default:
                cashSuper = new NormalCash();
        }
    }
    
    public double getResult(double money) {
        return cashSuper.acceptCash(money);
    }
}

回头想一想,其实策略模式是一种定义一系列算法的方法,从概念上来看,这些方法完成的都是相同的工作,只是实现不一样,它可以额用相同的方法调用所有的算法,减少了各种算法类与实用类之间的耦合

猜你喜欢

转载自www.cnblogs.com/joimages/p/11977652.html