设计模式:Strategy--策略模式

本文深入探讨了策略模式,一种设计模式,用于定义一系列可互换的算法,使得算法可以在不影响客户端的情况下进行替换。策略模式通过创建策略接口和其实现类,允许用户在运行时选择合适的算法,从而提高代码的灵活性和可维护性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

策略模式

感觉类似于桥接模式,只是具体区别还需要再研究

策略模式定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响到使用算法的客户。需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口,设计一个抽象类(可有可无,属于辅助类),提供辅助函数,关系图如下

Strategy:策略(算法)抽象
ConcreteStrategy: 各种策略的具体实现
Context:策略的外部封装类,或者说策略的容器类,根据不同的策略执行不同的行为
        ,策略是由外部环境决定的。

 

优点:1提供了管理相关算法的办法,策略类的等级结构定义了一个算法或行为族,恰当的用继承
            可以把公共的代码转移到父类里面避免重复代码。
    2 提供了可以替换继承关系的办法,继承可以处理多种算法或行为,如果不用策略模式,那么使用算法或者行为的环境就可能会有一些子类。每个子类提供
    一个不同的算法或行为,但是这样一来算法或行为使用者就和算法本身混在一起。决定
    使用哪种算法或算法蔡旭哪一种行为的逻辑就和算法逻辑混在一起,从而不吭呢再独立演化。继承使动态改变算法或行为变成不可能。
    
    3 避免使用多重条件转移语句
缺点
    1 客户端必须知道所有的策略类,并自行决定使用哪个策略类,这就意味着客户端必须理解这些算法区别,以便适时选择
    恰当的算法类,换言之,策略模式只适用于客户端知道所有算法或行为的额情况
    2策略模式会造成很多策略类,有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的。这样策略类实例可以被不同的客户端使用
    换言之,可以使用享元模式来减少对象的使用

 

三个实例 

实例一代码:

     策略模式的决定权在用户,系统本身提供不同算法的实现,新增或者删除算法,对各种算法做封装。因此,策略模式多用在算法决策系统中,外部用户只需要决定用哪个算法即可。

一个接口
public interface ICalculator {

    public int calculate(String exp);
}
*****************************************************************************8
三个实现类:
/**
 *  减法
 */
public class Minus extends AbstractCalculator implements ICalculator {
    @Override
    public int calculate(String exp) {
        int arrayInt[] = split(exp,"-");
        return arrayInt[0]-arrayInt[1];
    }
}

*****************************************************************************8

/**
 * 加法
 */
public class Plus extends AbstractCalculator implements ICalculator {

    @Override
    public int calculate(String exp) {
        int arrayInt[] = split(exp,"\\+");
        return arrayInt[0]+arrayInt[1];
    }
}
*****************************************************************************8


/**
 * 乘法
 */

public class Multiply extends AbstractCalculator implements ICalculator {
    @Override
    public int calculate(String exp) {
        int arrayInt[] = split(exp,"\\*");
        return arrayInt[0]*arrayInt[1];
    }
}
*****************************************************************************8

//抽象类:辅助类
public abstract class AbstractCalculator {

    public int[] split(String exp,String opt){
        String array[] = exp.split(opt);
        int arrayInt[] = new int[2];
        arrayInt[0] = Integer.parseInt(array[0]);
        arrayInt[1] = Integer.parseInt(array[1]);
        return arrayInt;
    }
}

*****************************************************************************8


/**
 * 策略模式的决定权在用户,系统本身提供不同算法的实现,
*新增或者删除算法,对各种算法做封装。
*因此,策略模式多用在算法决策系统中,
*外部用户只需要决定用哪个算法即可。
 */
public class MainCLass {
    public static void main(String[] args) {
        String exp = "2+8";
        ICalculator iCalculator = new Plus();
        int result = iCalculator.calculate(exp);
        System.out.println(result);
    }
}


测试结果:
10


 

 

实例二:

public interface Strategy {
    //加密算法
    public void encrypt();
}

****************************************************

public class MdD5Strategy implements Strategy {
    @Override
    public void encrypt() {
        System.out.println("使用MD5加密");
    }
}
****************************************************


public class AESStrategy implements Strategy {
    @Override
    public void encrypt() {
        System.out.println("使用AES加密");
    }
}
****************************************************


public class Context {
    private Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public void encrypt() {
        strategy.encrypt();
    }
}
****************************************************

/**
 * 根据传入不同的算法去执行不同的算法
 *
 */

public class MainClass {
    public static void main(String[] args) {
        //具体实现从这里new出来传进去,然后执行具体实现的策略
        Strategy strategy = new MdD5Strategy();
        Context context = new Context(strategy);
        context.encrypt();

        Strategy strategy1 = new AESStrategy();
        Context context1 = new Context(strategy1);
        context1.encrypt();
    }
}
****************************************************
测试结果:
使用MD5加密
使用AES加密

实例三:

 

public interface Strategy {
    public double coust(double num);
}

*************************************************

/**
 * 打八折
 *
 */

public class StrategyA implements Strategy{
    @Override
    public double coust(double num) {
        return num*0.8;
    }
}
*************************************************


/**
 * 满200减50活动
 */
public class StrategyB implements Strategy{
    @Override
    public double coust(double num) {
        if(num >= 200){
            return num -50;
        }
        return num;
    }
}

*************************************************


public class Context {
    private Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }


    public double con(double num){
           return strategy.coust(num);
    }
}
*************************************************
测试结果:
160.0



/**
 * 根据不同的价格执行不同的促销活动
 *
 */
public class MainCLass {
    public static void main(String[] args) {
        Strategy strategy  = new StrategyA();
        //实际策略是从这里传进去的
        Context context = new Context(strategy);
        double result = context.con(200);
        System.out.println(result);
    }
}

总结:

在接口实现中具体实现策略,用接口父类调用,实际执行子类中的代码。

一切的设计模式都是类模式和对象模式,也就是继承或者持有对象引用来达到设计的目的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值