设计模式之策略模式

定义一系列的算法,把他们一个个封装起来,并且使他们可以相互替代。本模式使得算法可独立于使用它的客户而变化!

痛点

策略模式可以很好解决众多if问题
如以下:

package com.tao.YanMoDesignPattern.Strategy.notPattern;

/**
 * @Author Mi_Tao
 * @Date 2023/7/22
 * @Description 价格管理,完成计算向客户所报价格的功能
 * @Version 1.0
 **/
public class Price {

    public double quoto(double goodsPrice,String customerType){
        if ("普通客户".equals(customerType)){
            System.out.println("对于新客户或者普通客户,没有折扣!");
        } else if ("老客户".equals(customerType)) {
            System.out.println("对于老客户,一律折扣5%!");
            return goodsPrice*(1-0.05);
        } else if ("大客户".equals(customerType)) {
            System.out.println("对于大客户,一律折扣10%!");
            return goodsPrice*(1-0.1);
        }
        return 0.0;
    }
}

先看一下标准的策略模式如何实现
上层接口,定义好行为

package com.tao.YanMoDesignPattern.Strategy.pattern;

/**
 * @Author Mi_Tao
 * @Date 2023/7/22
 * @Description 策略,定义算法的接口
 * @Version 1.0
 **/
public interface Strategy {

    public void algorithmInterface();
}

package com.tao.YanMoDesignPattern.Strategy.pattern;

/**
 * @Author Mi_Tao
 * @Date 2023/7/22
 * @Description
 * @Version 1.0
 **/
public class ConcreteStartegbA implements Strategy{
    @Override
    public void algorithmInterface() {
        // 具体的算法实现
    }
}

package com.tao.YanMoDesignPattern.Strategy.pattern;

/**
 * @Author Mi_Tao
 * @Date 2023/7/22
 * @Description
 * @Version 1.0
 **/
public class ConcreteStartegbB implements Strategy{
    @Override
    public void algorithmInterface() {
        // 具体的算法实现
    }
}

package com.tao.YanMoDesignPattern.Strategy.pattern;

/**
 * @Author Mi_Tao
 * @Date 2023/7/22
 * @Description
 * @Version 1.0
 **/
public class ConcreteStartegbC implements Strategy{
    @Override
    public void algorithmInterface() {
        // 具体的算法实现
    }
}

核心实现

package com.tao.YanMoDesignPattern.Strategy.pattern;

/**
 * @Author Mi_Tao
 * @Date 2023/7/22
 * @Description 上下文对象,通常会持有一个具体的策略对象
 * @Version 1.0
 **/
public class Context {

    // 持有一个具体的策略对象
    private Strategy strategy;

    /**
     * 上下文对客户端提供的操作接口,可以有参数和返回值
     */
    public void contextInterface(){
        // 通常会转调具体的策略对象进行算法运算
        strategy.algorithmInterface();
    }
}

问题应用策略模式来解决

package com.tao.YanMoDesignPattern.Strategy.caseChange;

/**
 * @Author Mi_Tao
 * @Date 2023/7/22
 * @Description 策略,定义计算报价算法的接口
 * @Version 1.0
 **/
public interface Strategy {

    /**
     * 计算应报的价格
     * @param goodsPrice
     * @return 计算出来的,应给客户的报价
     */
    public double calcPrice(double goodsPrice);
}

package com.tao.YanMoDesignPattern.Strategy.caseChange;


/**
 * @Author Mi_Tao
 * @Date 2023/7/22
 * @Description
 * @Version 1.0
 **/
public class OldCusomerStategy implements Strategy {

    @Override
    public double calcPrice(double goodsPrice) {
        System.out.println("老客户,5%折扣");
        return goodsPrice*(1-0.05);
    }
}

package com.tao.YanMoDesignPattern.Strategy.caseChange;


/**
 * @Author Mi_Tao
 * @Date 2023/7/22
 * @Description
 * @Version 1.0
 **/
public class NormalCusomerStategy implements Strategy {

    @Override
    public double calcPrice(double goodsPrice) {
        System.out.println("普通客户,没有折扣");
        return goodsPrice;
    }
}

package com.tao.YanMoDesignPattern.Strategy.caseChange;


/**
 * @Author Mi_Tao
 * @Date 2023/7/22
 * @Description
 * @Version 1.0
 **/
public class LargeCusomerStategy implements Strategy {

    @Override
    public double calcPrice(double goodsPrice) {
        System.out.println("大客户,10%折扣");
        return goodsPrice*(1-0.1);
    }
}

package com.tao.YanMoDesignPattern.Strategy.caseChange;

/**
 * @Author Mi_Tao
 * @Date 2023/7/22
 * @Description 价格管理,主要完成计算向客户所报价格的功能
 * @Version 1.0
 **/
public class Price {

    /**
     * 持有一个具体的策略对象
     */
    private Strategy strategy = null;

    /**
     * 构造方法,传入一个具体的策略对象
     * @param strategy
     */
    public Price(Strategy strategy) {
        this.strategy = strategy;
    }

    /**
     * 报价,计算客户的报价
     * @param goodsPrice 商品销售原价
     * @return 计算出来的,应该给客户的保教
     */
    public double quote(double goodsPrice){
        return this.strategy.calcPrice(goodsPrice);
    }

}

测试类

package com.tao.YanMoDesignPattern.Strategy.caseChange;

/**
 * @Author Mi_Tao
 * @Date 2023/7/22
 * @Description
 * @Version 1.0
 **/
public class Client {

    public static void main(String[] args) {
        // 1、选择并创建需要使用的策略对象
        Strategy strategy = new LargeCusomerStategy();
        // 2、创建上下文
        Price ctx = new Price(strategy);
        //3、计算报价
        double quote = ctx.quote(1000);
        System.out.println("向客户报价:"+quote);
    }


}

设计模式之策略模式_第1张图片

设计模式之策略模式_第2张图片
设计模式之策略模式_第3张图片
别提有多么舒服,只要改变实现的策略就可以进行逻辑的切换!

策略模式的中心不是如何实现算法,而是如何组织,调用这些算法, 从而让程序结构更灵活,具有更好的维护性和扩展性。

设计模式之策略模式_第4张图片
设计模式之策略模式_第5张图片

经典的策略模式调用顺序

设计模式之策略模式_第6张图片
设计模式之策略模式_第7张图片

除此之外还可以解决:容错问题(上传文件是中途失败,下次要如何恢复到失败的问题。实现模板方法模式)

经典的策略模式UML图

设计模式之策略模式_第8张图片
设计模式之策略模式_第9张图片

策略模式的本质: 分离算法,选择实现

何时使用策略模式

设计模式之策略模式_第10张图片

你可能感兴趣的:(设计模式,设计模式,策略模式,bash)