《设计模式》之策略模式

策略模式定义

比如对象的某个行为,在不同场景有不同实现方式,可以将这些行为的具体实现定义为一组策略,每个实现类实现种策略,在不同场景使用不同的实现,并且可以自由切换策略。

策略模式结构

策略模式需要一个策略接口,不同的策略实现不同的实现类,在具体业务环境中仅持有该策略接口,根据不同的场景使用不同的实现类即可。

面向接口编程,而不是面向实现。

优点

1、干掉繁琐的 if、switch 判断逻辑;

2、代码优雅、可复用、可读性好;

3、符合开闭原则(对修改关闭, 对扩展开放),扩展性好、便于维护;

缺点

1、策略如果很多的话,会造成策略类膨胀;

2、使用者必须清楚所有的策略类及其用途;

策略模式代码示例

  • 基础登录接口

    //基础登录接口
    public interface BaseLoginService {
    void login(BaseLoginContext context);
    }

  • 策略上下文实现

    @Data
    public class BaseLoginContext {
    private String userName;

    复制代码
      private String password;
    
      private BaseLoginService baseLoginService;
    
      public BaseLoginContext(String userName, String password, BaseLoginService baseLoginService) {
          this.userName = userName;
          this.password = password;
          this.baseLoginService = baseLoginService;
      }
    
      public void login(){
          baseLoginService.login(this);
      }

    }

  • 定义具体的策略实现类

  1. 实现类1

    public class SimpleLoginServiceImpl implements BaseLoginService {
    @Override
    public void login(BaseLoginContext context) {
    System.out.println("简单登录,当前登录的人:" + context.getUserName() + ",密码:" + context.getPassword());
    }
    }

  2. 实现类2

    public class HardLoginServiceImpl implements BaseLoginService {
    @Override
    public void login(BaseLoginContext context) {
    System.out.println("复杂登录,当前登录的人:" + context.getUserName() + ",密码:" + context.getPassword());
    }
    }

  • 调用

    public static void main(String[] args) {
    BaseLoginService simple = new SimpleLoginServiceImpl();
    BaseLoginContext simpleContext = new BaseLoginContext("simple","simple",simple);
    simpleContext.login();

    复制代码
          BaseLoginService hard = new HardLoginServiceImpl();
          BaseLoginContext hardContext = new BaseLoginContext("hard","hard",hard);
          hardContext.login();
      }
  • 结果

扩展策略

方式1

在策略的算法实现上添加自己需要的数据的方式

复制代码
public class CommonLoginServiceImpl implements BaseLoginService {

    private String userId;

    public CommonLoginServiceImpl(String userId) {
        this.userId = userId;
    }

    public String getUserId() {
        return userId;
    }

    @Override
    public void login(BaseLoginContext context) {
        System.out.println("复杂登录,当前登录的人:" + context.getUserName() + ",账号:" + getUserId() + ",密码:" + context.getPassword());
    }
}
  • 调用

    public static void main(String[] args) {
    BaseLoginService simple = new SimpleLoginServiceImpl();
    BaseLoginContext simpleContext = new BaseLoginContext("simple","simple",simple);
    simpleContext.login();

    复制代码
          BaseLoginService hard = new HardLoginServiceImpl();
          BaseLoginContext hardContext = new BaseLoginContext("hard","hard",hard);
          hardContext.login();
    
          BaseLoginService common = new CommonLoginServiceImpl("001");
          BaseLoginContext commonContext = new BaseLoginContext("common","common",common);
          commonContext.login();
      }
  • 结果

方式2

扩展上下文的方式

复制代码
public class NewLoginContext extends BaseLoginContext{
    private String userId;

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public NewLoginContext(String userName, String password, String userId, BaseLoginService baseLoginService) {
        super(userName, password, baseLoginService);
        this.userId = userId;
    }
}
  • 实现类

    public class CommonLoginServiceImpl implements BaseLoginService {

    复制代码
      private String userId;
    
      public CommonLoginServiceImpl(String userId) {
          this.userId = userId;
      }
    
      public String getUserId() {
          return userId;
      }
    
      @Override
      public void login(BaseLoginContext context) {
          NewLoginContext newLoginContext = (NewLoginContext)context;

    // System.out.println("common1登录,当前登录的人:" + context.getUserName() + ",账号:" + getUserId() + ",密码:" + context.getPassword());
    System.out.println("common2登录,当前登录的人:" + context.getUserName() + ",账号:" + newLoginContext.getUserId() + ",密码:" + context.getPassword());
    }
    }

  • 调用

    public static void main(String[] args) {
    BaseLoginService simple = new SimpleLoginServiceImpl();
    BaseLoginContext simpleContext = new BaseLoginContext("simple","simple",simple);
    simpleContext.login();

    复制代码
          BaseLoginService hard = new HardLoginServiceImpl();
          BaseLoginContext hardContext = new BaseLoginContext("hard","hard",hard);
          hardContext.login();

    // BaseLoginService common1 = new CommonLoginServiceImpl("001");
    // BaseLoginContext commonContext1 = new BaseLoginContext("common","common",common1);
    // commonContext1.login();

    复制代码
          BaseLoginService common2 = new CommonLoginServiceImpl("001");
          NewLoginContext commonContext2 = new NewLoginContext("common","common","002",common2);
          commonContext2.login();
      }
  • 结果

相关推荐
缺点内向4 小时前
Java:创建、读取或更新 Excel 文档
java·excel
带刺的坐椅5 小时前
Solon v3.4.7, v3.5.6, v3.6.1 发布(国产优秀应用开发框架)
java·spring·solon
四谎真好看6 小时前
Java 黑马程序员学习笔记(进阶篇18)
java·笔记·学习·学习笔记
桦说编程6 小时前
深入解析CompletableFuture源码实现(2)———双源输入
java·后端·源码
java_t_t6 小时前
ZIP工具类
java·zip
lang201509287 小时前
Spring Boot优雅关闭全解析
java·spring boot·后端
pengzhuofan8 小时前
第10章 Maven
java·maven
百锦再8 小时前
Vue Scoped样式混淆问题详解与解决方案
java·前端·javascript·数据库·vue.js·学习·.net
刘一说8 小时前
Spring Boot 启动慢?启动过程深度解析与优化策略
java·spring boot·后端
壹佰大多8 小时前
【spring如何扫描一个路径下被注解修饰的类】
java·后端·spring