通俗易懂的java设计模式之策略模式

82 阅读1分钟

策略君正在看直播,突然一大波if...else...弹幕飘过,策略君顿时满头黑线。为什么策略君对if...else...有这么大的反应?。

首先明确一点的是,if...else...仍是首选,因为它确实很简单方便,但有个前提就是不需要再对它的逻辑进行扩展且判断条件不多的情况。

真实项目中,最不缺的就是变化,我们要充分考虑到如何去适应这些变化,而不是去逃避它。

举一个非常简单的例子:会员制,一本书的价格不同的会员有不同的算法。共性是都是计算价格,不同的是算法。那么我们是不是就可以建立一个接口,并将计算价格作为共性方法,其他都是些策略类,实现该接口,这样具体的算法在策略类里实现即可。我们可以将这些策略类存在一个map中,key就是会员的级别。之后呢我们想要扩展了,只需要建立一个策略类,实现算法,并存入map不就完事了,就这么简单。当然还要更多的延伸我就不一一举例了,重点是了解它的适用场景,灵活运用到自己的项目里,目的就达到了。

代码如下:

public class Strategy {
    public static void main(String[] args) {
        // 具体行为策略
        MemberStrategy primaryMemberStrategy = new PrimaryMemberStrategy(); // 接口回调(向上转型)
        MemberStrategy intermediateMemberStrategy = new IntermediateMemberStrategy();
        MemberStrategy advanceMemberStrategy = new AdvanceMemberStrategy();

        // 用户选择不同策略
        MemberContext primaryContext = new MemberContext(primaryMemberStrategy);
        MemberContext intermediateContext = new MemberContext(intermediateMemberStrategy);
        MemberContext advanceContext = new MemberContext(advanceMemberStrategy);

        //计算一本300块钱的书
        System.out.println("普通会员的价格:"+ primaryContext.qoutePrice(300,1));// 普通会员:300
        System.out.println("中级会员的价格:"+ intermediateContext.qoutePrice(300,1));// 中级会员 270
        System.out.println("高级会员的价格:"+ advanceContext.qoutePrice(300,1));// 高级会员240
    }
}
interface MemberStrategy {
    // 一个计算价格的抽象方法
    //price商品的价格 n商品的个数
    public double calcPrice(double price, int n);
}
// 普通会员——不打折
class PrimaryMemberStrategy implements MemberStrategy { // 实现策略
    //重写策略方法具体实现功能
    @Override
    public double calcPrice(double price, int n) {
        return price * n;
    }
}
// 中级会员 打百分之10的折扣
class IntermediateMemberStrategy implements MemberStrategy{
    @Override
    public double calcPrice(double price, int n) {
        double money = (price * n) - price * n * 0.1;
        return money;
    }
}
// 高级会员类 20%折扣
class AdvanceMemberStrategy implements MemberStrategy{
    @Override
    public double calcPrice(double price, int n) {
        double money = price * n - price * n * 0.2;
        return money;
    }
}
/**
 * 负责和具体的策略类交互
 * 这样的话,具体的算法和直接的客户端调用分离了,使得算法可以独立于客户端独立的变化。
 */

// 上下文类/环境类
class MemberContext {
    // 用户折扣策略接口
    private MemberStrategy memberStrategy;
    // 注入构造方法
    public MemberContext(MemberStrategy memberStrategy) {
        this.memberStrategy = memberStrategy;
    }
    // 计算价格
    public double qoutePrice(double goodsPrice, int n){
        // 通过接口变量调用对应的具体策略
        return memberStrategy.calcPrice(goodsPrice, n);
    }
}