1.前言 对于大多数多种类型的逻辑代码,我们一般的做法一般是通过if来进行判断,然后再{}里进行逻辑代码的编写,如下述 package org.example.designpattern.strategy; public class LoginNo
1.前言
对于大多数多种类型的逻辑代码,我们一般的做法一般是通过if来进行判断,然后再{}里进行逻辑代码的编写,如下述
package org.example.designpattern.strategy;public class LoginNoDesign {
/**
* 登录方法, 不使用策略模式时, 对于流程的扩展如新增一种登录方式只能添加if
*
* @param username 用户名
* @param password 密码
* @param type 登录方式
*/
public void login(String username, String password, String type){
if ("mobile".equals(type)) {
// 手机号登录
System.out.println("手机号登录成功");
} else {
// 用户名密码登录
System.out.println("用户名密码登录成功");
}
}
}
但这种代码给整个方法增添了一种臃肿,往往一个方法需要大几十甚至上百行代码。
二.策略模式介绍
策略模式是行为模式的一种,也是消除if的重要手段,通过对于同类逻辑的不同策略来实现替代,如我们有多种登陆方式,那么可以先定义某种type对应某种策略,在使用时通过type来获取对应执行策略。
三.代码实现
package org.example.designpattern.strategy;public interface ILogin {
/**
* 登录方法
*
* @param username 用户名
* @param password 密码
* @param type 登录方式
*/
void login(String username, String password, String type);
}
package org.example.designpattern.strategy;
public class MobileLogin implements ILogin{
@Override
public void login(String username, String password, String type){
System.out.println("手机号登录成功");
}
}
package org.example.designpattern.strategy;
public class UsernameLogin implements ILogin{
@Override
public void login(String username, String password, String type){
System.out.println("用户名密码登录成功");
}
}
测试
package org.example.designpattern.strategy;import org.junit.Test;
public class StrategyTests {
@Test
public void test(){
LoginNoDesign loginNoDesign = new LoginNoDesign();
loginNoDesign.login("root", "root", "username");
// 策略模式
ILogin login = new MobileLogin();
login.login("13903291525", "", "mobile");
}
}
对比
通过类型将各自实现分开,这样将原来的耦合的代码分开,在某种类型逻辑需要修改维护时也不需要测试其他已经跑通的逻辑。
扩展
结合工厂模式,预定义对应类型所执行的策略
package org.example.designpattern.strategy;import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class LoginServiceFactory {
private static Map<String, ILogin> loginMap = new ConcurrentHashMap<>();
static {
loginMap.put("mobile", new MobileLogin());
loginMap.put("username", new UsernameLogin());
}
public static ILogin getLoginService(String type){
return loginMap.get(type);
}
}
测试
package org.example.designpattern.strategy;import org.junit.Test;
public class StrategyTests {
@Test
public void test(){
LoginNoDesign loginNoDesign = new LoginNoDesign();
loginNoDesign.login("root", "root", "username");
// 策略模式
ILogin login = new MobileLogin();
login.login("13903291525", "");
// 结合工厂
ILogin login1 = LoginServiceFactory.getLoginService("mobile");
login1.login("13903291525", "");
}
}
四.总结
策略模式并不复杂,通过策略模式可以优化掉代码中的大量if,可以极大的提高系统的扩展性