《设计模式》之策略模式

策略模式定义

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

策略模式结构

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

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

优点

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();
      }
  • 结果

相关推荐
新之助小锅1 小时前
java版连接汇川PLC,发送数据,读取数据,保持重新链接,适用安卓
android·java·python
无糖冰可乐213 小时前
IDEA多java版本切换
java·ide·intellij-idea
合作小小程序员小小店3 小时前
web开发,在线%超市销售%管理系统,基于idea,html,jsp,java,ssh,sql server数据库。
java·前端·sqlserver·ssh·intellij-idea
brucelee1863 小时前
IntelliJ IDEA 设置 Local History 永久保留
java·ide·intellij-idea
Pluto_CSND5 小时前
Java中的静态代理与动态代理(Proxy.newProxyInstance)
java·开发语言
o0向阳而生0o5 小时前
112、23种设计模式之命令模式(20/23)
设计模式·命令模式
将编程培养成爱好6 小时前
C++ 设计模式《外卖骑手状态系统》
c++·ui·设计模式·状态模式
猿太极6 小时前
设计模式学习(3)-行为型模式
c++·设计模式
百***46456 小时前
Java进阶-在Ubuntu上部署SpringBoot应用
java·spring boot·ubuntu
serve the people6 小时前
Prompts for Chat Models in LangChain
java·linux·langchain