策略模式(Strategy Pattern)

策略模式定义:策略模式定义了算法族,将算法分别封装起来,让他们之间可以互相替换。此模式让算法的变化独立于使用算法的客户

我们来看一个商场打折的例子


public interface Discount {
    public double reduce(double total);
}

public class Derate implements Discount {
    // 8折
    public double reduce(double total){
        return total * 0.8;
    };
}

public class Return implements Discount {
    // 满100减少20
    public double reduce(double total) {
        return total - total / 100 * 20;
    }
}
public class Bill {
    public double pay(double total, String discountType){
        Discount discount = null;
        if(discountType.equals("Return"))
            discount = new Return();
        else if(discountType.equals("Derate"))
            discount = new Derate();

        if(discount != null)
            total = discount.reduce(total);

        return total;
    }
}

商场的折扣力度是会经常性发生变化的,现有代码为了支持这种变化,只能添加新的实现类,但是仅仅为了支持9折,就需要在已有8折代码的基础上添加新的实现类,既没有体现8折、9折之间逻辑的相似性,也没有很好的复用代码


public interface Discount {
    public double reduce(double total);
}

// 打折
public class Derate implements Discount {
    private double rate;

    public Derate(double rate){
        this.rate = rate;
    }

    public double reduce(double total){
        return total * rate;
    };
}

// 满减
public class Return implements Discount {

    private double collect;
    private double reduce;

    public Return(double collect, double reduce){
        this.collect = collect;
        this.reduce = reduce;
    }

    public double reduce(double total) {
        return total - total / collect * reduce;
    }
}
public class Bill {
    public double pay(double total, String discountType){
        Discount discount = null;
        if(discountType.equals("Return"))
            // 满100减少20
            discount = new Return(100, 20);
        else if(discountType.equals("Derate"))
            // 8折
            discount = new Derate(0.8);

        if(discount != null)
            total = discount.reduce(total);

        return total; 
    }
}

经过修改,同类优惠政策,仅需在构造时传入不同的参数即可适应各种情况,除非出现新的优惠政策,比如每满1000,折扣力度增加5%,才需要新的实现类

我们来看看账单类,调用方负责构造具体实现类的构造,我们一下就会想到使用简单工厂进行封装


public class DiscountFactory {
    public static Discount getDiscount(String discountType){
        Discount discount = null;
        if(discountType.equals("Return"))
            // 满100减少20
            discount = new Return(100, 20);
        else if(discountType.equals("Derate"))
            // 8折
            discount = new Derate(0.8);
        
        return discount;
    }
}

public class Bill {
    public double pay(double total, String discountType){
        Discount discount = DiscountFactory.getDiscount(discountType);

        if(discount != null)
            total = discount.reduce(total);

        return total;
    }
}

这下看起来很“完美”了,但是既然是打了引号的完美,那么就说明还是存在问题的。问题就出在这个DiscountFactory类,这个类从功能上来说很明确,就是用来构造Discount类,但是从实际角度出发,这个类是从现实中的哪种对象或行为抽象而来的呢?从类图中我们可以很明确的发现Bill类即依赖DiscountFactory类,也依赖Discount类,事实上,Bill类只关心折扣,不关心折扣的构建过程,那么我们有没有其它的设计方式,可以使Bill类与DiscountFactory类解耦呢?


public class DiscountStrategy {
    private Discount discount;

    public DiscountStrategy(String discountType){
        if(discountType.equals("Return"))
            // 满100减少20
            discount = new Return(100, 20);
        else if(discountType.equals("Derate"))
            // 8折
            discount = new Derate(0.8);
    }

    public double reduce(double total) {
        if(discount != null)
            total = discount.reduce(total);
        return total;
    }
}
public class Bill {
    public double pay(double total, String discountType){
        DiscountStrategy discountStrategy = new DiscountStrategy(discountType);
        return discountStrategy.reduce(total);
    }
}

从类图就能看出策略模式和工厂模式的差别了,DiscountFactory依赖Discount而DiscountStrategy组合Discount,虽说耦合 变得更高了,但是其实是DiscountStrategy抽象化程度更高了,从本质上说DiscountStrategy其实也可以看做是Discount的一种,同时,调用方的耦合度则更低

public class DiscountStrategy implements Discount{
    private Discount discount;

    public DiscountStrategy(String discountType){
        if(discountType.equals("Return"))
            // 满100减少20
            discount = new Return(100, 20);
        else if(discountType.equals("Derate"))
            // 8折
            discount = new Derate(0.8);
    }

    public double reduce(double total) {
        if(discount != null)
            total = discount.reduce(total);
        return total;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值