聊聊设计模式——策略模式

目录

策略模式的定义

优点

缺点

策略模式结构说明

工作流程

代码示例

应用场景

本质

设计原则

与其他设计模式的关系

开源框架中的应用


策略模式的定义

定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式算法的变化,不会影响到使用算法的客户。

优点

  1. 灵活性:策略模式允许在运行时切换算法,提供了灵活性,使客户端可以根据需求选择不同的策略。

  2. 可维护性:每个策略都被封装在独立的类中,使得代码更易于维护和扩展。

  3. 解耦:策略模式将算法的实现与使用算法的客户端解耦,客户端只需要关心选择合适的策略即可。

缺点

  1. 增加类的数量:引入策略模式会增加类的数量,特别是在有多个策略的情况下。

  2. 客户端必须了解所有策略:客户端需要知道所有可用的策略,并在运行时选择合适的策略,可能会增加客户端的复杂性。

策略模式结构说明

  1. 策略接口(Strategy Interface):定义了一组算法的通用接口,通常包含一个执行算法的方法。

  2. 具体策略类(Concrete Strategy):实现策略接口,提供具体的算法实现。

  3. 上下文类(Context):维护一个策略对象,并在需要时调用策略对象的方法。上下文类通常允许客户端动态地切换策略。

工作流程

  1. 客户端创建一个上下文对象,并将一个具体的策略对象传递给上下文。

  2. 当客户端需要使用算法时,它调用上下文的方法,上下文将请求委派给策略对象执行。

  3. 不同的策略对象可以实现不同的算法,客户端可以根据需求选择不同的策略对象。

代码示例

策略模式解耦的是策略的定义、创建和使用。简单的例子,吃午饭是吃麻辣烫还是套饭简餐。

1.创建抽象策略接口Lunch.

public interface Lunch {
    void eat();
}

2.创建具体策略吃麻辣烫或者吃套饭简餐

public class MaLaTang implements Lunch {
    public void eat(){
        System.out.println("吃个麻辣烫吧...");
    }
}
public class TaoFan implements Lunch {
    public void eat(){
        System.out.println("吃个套饭吧...");
    }
}

3.创建上下文对象,可以理解为策略的使用者,包含策略的引用。

public class Person {
    private Lunch lunch;
    public Person(Lunch lunch) {
        this.lunch = lunch;
    }
    public void dinner(){
        System.out.println("中午吃什么呢?");
        this.lunch.eat();
    }
}

4.客户端指定使用哪种策略,或者动态的决定策略(需要通过工厂传入type获取策略)。

    public static Lunch getLunch(String type){
        if (type == null || type.isEmpty()){
            throw  new IllegalArgumentException("参数不能为空.");
        }
        // 这里使用的是简单工厂,if-else直接用了
        if (type.equals("A")) {
            return new MaLaTang();
        } else if (type.equals("B")) {
            return new TaoFan();
        } else {
            return null;
        }
    }
}
public class Client {
    public static void main(String[] args) throws IOException {
        // 静态指定使用什么策略
        Person person = new Person(new MaLaTang());
        person.dinner();
        
        // 动态判断使用什么策略
        System.out.println("================配置文件读取===============");
        Properties props = new Properties();
        FileInputStream in = new FileInputStream("D:\\config.properties");
        props.load(in);
        String type = props.getProperty("lunch_type");
        Person person1 = new Person(LunchFactory.getLunch(type));
        person1.dinner();
    }
}

config.properties放在D盘下为了方便,就配了个lunch_type

应用场景

  1. 当需要在运行时选择算法时,可以使用策略模式。例如,根据用户的选择来应用不同的排序算法。

  2. 当一个类有多个行为变种,且这些变种通过条件语句组织在一起时,可以使用策略模式将每个变种封装为一个独立的策略类。

  3. 当希望隐藏复杂的算法实现细节,使代码更易于维护和扩展时,策略模式非常有用。

本质

        策略模式的本质是定义一系列算法,将每个算法封装到独立的策略类中,使得它们可以相互替换。

设计原则

        开闭原则(Open-Closed Principle):策略模式遵循开闭原则,允许在不修改客户端代码的情况下添加新的策略类。

与其他设计模式的关系

        策略模式与状态模式有些相似,因为它们都允许对象在不同状态下采取不同的行为。不同之处在于,状态模式是根据对象的内部状态来切换行为,而策略模式是根据客户端的选择来切换行为。

开源框架中的应用

  1. Spring框架 - Spring AOP(面向切面编程)

    • Spring AOP是Spring框架的一部分,它采用策略模式来支持不同的切面(Aspect)。

    • Spring AOP允许开发人员定义不同的通知(Advice)策略,如前置通知、后置通知、异常通知等,然后将这些通知与切入点关联起来。

  2. Slf4j - 日志输出策略

    • Simple Logging Facade for Java(Slf4j)是一个Java日志门面,它允许开发人员使用不同的底层日志实现(如Log4j、Logback、JUL等)。

    • Slf4j使用策略模式来将日志输出委托给不同的底层日志库,使得应用程序可以在不同的环境中轻松切换日志实现。

  3. Spring Security框架 - 认证和授权策略

    • Spring Security是用于身份验证和授权的框架,它使用策略模式来支持不同的认证和授权策略。

    • 开发人员可以选择不同的认证和授权策略,例如基于用户名和密码的认证、基于令牌的认证、基于角色的授权等,以满足应用程序的安全需求。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Elaine202391

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值