策略模式配合java8的应用

策略模式配合java8的应用

在用java编写业务代码的过程中,经常会碰到一个业务有不同种的实现。典型的如用户登录,登录入口只有一个,但是要匹配微信、网易、QQ、支付宝、新浪微博等不同的登录渠道。各种业务场景的具体实现又各不相同,有的实现细节业务非常复杂。如果不合理的编码,会导致代码观感很差,影响阅读和维护。今天以这个场景来探讨下策略模式配合java8如何实现优雅编码,代码如下:

1、定义登录请求对象,具体参数不做过多探讨,这里只标识登录的渠道码
public class LogingRequest {
    
    

	private String loginTypeCode;

	/** 其他业务参数 **/

	public String getLoginTypeCode() {
    
    
		return loginTypeCode;
	}

	public void setLoginTypeCode(String loginTypeCode) {
    
    
		this.loginTypeCode = loginTypeCode;
	}

}
2、一般程序员可能不加思索,按业务逻辑就开始编码,代码应该是这样的
// 普通程序员的写法
	public void loginWithIfElse(LogingRequest logingRequest) {
    
    
		if ("wechat".equals(logingRequest.getLoginTypeCode())) {
    
    
			// 微信登录的逻辑,
			/**
			 * 一大堆逻辑 $$$$$&^&^&^&%&%&&^&^&^& erwerewrwrewr 2343243242
			 */
			System.out.println("从微信渠道登录");
		} else if ("qq".equals(logingRequest.getLoginTypeCode())) {
    
    
			// qq登录的逻辑
			/**
			 * 一大堆逻辑 $$$$$&^&^&^&%&%&&^&^&^& erwerewrwrewr 2343243242
			 */
			System.out.println("从QQ渠道登录");
		} else if ("netease".equals(logingRequest.getLoginTypeCode())) {
    
    
			// 网易登录的逻辑
			/**
			 * 一大堆逻辑 $$$$$&^&^&^&%&%&&^&^&^& erwerewrwrewr 2343243242
			 */
			System.out.println("从网易渠道登录");
		} else if ("sina".equals(logingRequest.getLoginTypeCode())) {
    
    
			// 新浪微博登录的逻辑
			/**
			 * 一大堆逻辑 $$$$$&^&^&^&%&%&&^&^&^& erwerewrwrewr 2343243242
			 */
			System.out.println("从新浪微博渠道登录");
		} else if ("alipay".equals(logingRequest.getLoginTypeCode())) {
    
    
			// 支付宝登录的逻辑
			/**
			 * 一大堆逻辑 $$$$$&^&^&^&%&%&&^&^&^& erwerewrwrewr 2343243242
			 */
			System.out.println("从支付宝渠道登录");
		}
	}

这样写出来的代码很长,很难看理解,考虑到各登录渠道里还有很复杂的逻辑,也会有很多if+esle,眼睛都会看花,到时候估计不光别人维护你代码会骂娘,你自己看的都一头大。

3、有经验的程序员会抽取一个公共的接口,不同的登录渠道在实现接口后,在自己类中维护和登录逻辑,代码如下
public interface LoginService {
    
    
	
	void login(LogingRequest logingRequest);

}

public class WeChatLoginService implements LoginService {
    
    

	public void login(LogingRequest logingRequest) {
    
    
		/**一大堆逻辑
		 * $$$$$&^&^&^&%&%&&^&^&^&
		 * erwerewrwrewr
		 * 2343243242
		 */
		System.out.println("从微信渠道登录");
	}

}

public class QQLoginService implements LoginService {
    
    

	public void login(LogingRequest logingRequest) {
    
    
		/**一大堆逻辑
		 * $$$$$&^&^&^&%&%&&^&^&^&
		 * erwerewrwrewr
		 * 2343243242
		 */
		System.out.println("从QQ渠道登录");
	}

}

public class NeteaseLoginService implements LoginService {
    
    

	public void login(LogingRequest logingRequest) {
    
    
		/**一大堆逻辑
		 * $$$$$&^&^&^&%&%&&^&^&^&
		 * erwerewrwrewr
		 * 2343243242
		 */
		System.out.println("从网易渠道登录");
	}

}

public class SinaLoginService implements LoginService {
    
    

	public void login(LogingRequest logingRequest) {
    
    
		/**一大堆逻辑
		 * $$$$$&^&^&^&%&%&&^&^&^&
		 * erwerewrwrewr
		 * 2343243242
		 */
		System.out.println("从新浪微博渠道登录");
	}

}

public class AlipayLoginService implements LoginService {
    
    

	public void login(LogingRequest logingRequest) {
    
    
		/**一大堆逻辑
		 * $$$$$&^&^&^&%&%&&^&^&^&
		 * erwerewrwrewr
		 * 2343243242
		 */
		System.out.println("从支付宝渠道登录");
	}

}


	// 把具体实现分接口实现
	public void loginWithInterface(LogingRequest logingRequest) {
    
    
		if ("wechat".equals(logingRequest.getLoginTypeCode())) {
    
    
			new WeChatLoginService().login(logingRequest);
		} else if ("qq".equals(logingRequest.getLoginTypeCode())) {
    
    
			new QQLoginService().login(logingRequest);
		} else if ("netease".equals(logingRequest.getLoginTypeCode())) {
    
    
			new NeteaseLoginService().login(logingRequest);
		} else if ("sina".equals(logingRequest.getLoginTypeCode())) {
    
    
			new SinaLoginService().login(logingRequest);
		} else if ("alipay".equals(logingRequest.getLoginTypeCode())) {
    
    
			new AlipayLoginService().login(logingRequest);
		}
	}
4、除了这,你还是不喜欢这么多if+else,怎么办,接下来就是我要说的策略模式,建立一个枚举来维护各接口实现,并实现策略路由
public enum LoginTypeEnum {
    
    

	WECHAT("wechat", WeChatLoginService::new, "微信登录"), QQ("qq", QQLoginService::new, "qq登录"),
	NETEASE("netease", NeteaseLoginService::new, "网易登录"), SINA("sina", SinaLoginService::new, "微博登录"),
	ALIPAY("alipay", AlipayLoginService::new, "支付宝登录");

	private String code;

	private Supplier<LoginService> loginService;

	private String desc;

	public String getCode() {
    
    
		return code;
	}

	public void setCode(String code) {
    
    
		this.code = code;
	}

	public String getDesc() {
    
    
		return desc;
	}

	public void setDesc(String desc) {
    
    
		this.desc = desc;
	}

	private LoginTypeEnum(String code, Supplier<LoginService> loginService, String desc) {
    
    
		this.code = code;
		this.loginService = loginService;
		this.desc = desc;
	}

	public Supplier<LoginService> getLoginService() {
    
    
		return loginService;
	}

	public void setLoginService(Supplier<LoginService> loginService) {
    
    
		this.loginService = loginService;
	}

	public static LoginTypeEnum getByLoginTypeCode(String loginTypeCode) {
    
    
		return Stream.of(LoginTypeEnum.values()).filter(x -> x.getCode().equals(loginTypeCode)).findAny()
				.orElseThrow(() -> new RuntimeException("登录类型编码错误"));
	}

}

5、最后的业务类,三种方式的写法
public class LoginServiceBiz {
    
    

	// 普通程序员的写法
	public void loginWithIfElse(LogingRequest logingRequest) {
    
    
		if ("wechat".equals(logingRequest.getLoginTypeCode())) {
    
    
			// 微信登录的逻辑,
			/**
			 * 一大堆逻辑 $$$$$&^&^&^&%&%&&^&^&^& erwerewrwrewr 2343243242
			 */
			System.out.println("从微信渠道登录");
		} else if ("qq".equals(logingRequest.getLoginTypeCode())) {
    
    
			// qq登录的逻辑
			/**
			 * 一大堆逻辑 $$$$$&^&^&^&%&%&&^&^&^& erwerewrwrewr 2343243242
			 */
			System.out.println("从QQ渠道登录");
		} else if ("netease".equals(logingRequest.getLoginTypeCode())) {
    
    
			// 网易登录的逻辑
			/**
			 * 一大堆逻辑 $$$$$&^&^&^&%&%&&^&^&^& erwerewrwrewr 2343243242
			 */
			System.out.println("从网易渠道登录");
		} else if ("sina".equals(logingRequest.getLoginTypeCode())) {
    
    
			// 新浪微博登录的逻辑
			/**
			 * 一大堆逻辑 $$$$$&^&^&^&%&%&&^&^&^& erwerewrwrewr 2343243242
			 */
			System.out.println("从新浪微博渠道登录");
		} else if ("alipay".equals(logingRequest.getLoginTypeCode())) {
    
    
			// 支付宝登录的逻辑
			/**
			 * 一大堆逻辑 $$$$$&^&^&^&%&%&&^&^&^& erwerewrwrewr 2343243242
			 */
			System.out.println("从支付宝渠道登录");
		}
	}

	// 把具体实现分接口实现
	public void loginWithInterface(LogingRequest logingRequest) {
    
    
		if ("wechat".equals(logingRequest.getLoginTypeCode())) {
    
    
			new WeChatLoginService().login(logingRequest);
		} else if ("qq".equals(logingRequest.getLoginTypeCode())) {
    
    
			new QQLoginService().login(logingRequest);
		} else if ("netease".equals(logingRequest.getLoginTypeCode())) {
    
    
			new NeteaseLoginService().login(logingRequest);
		} else if ("sina".equals(logingRequest.getLoginTypeCode())) {
    
    
			new SinaLoginService().login(logingRequest);
		} else if ("alipay".equals(logingRequest.getLoginTypeCode())) {
    
    
			new AlipayLoginService().login(logingRequest);
		}
	}

	// 采用java8配置策略模式实现登录自动路由到具体实现方法上
	public void loginWithJava8(LogingRequest logingRequest) {
    
    
		      		LoginTypeEnum.getByLoginTypeCode(logingRequest.getLoginTypeCode()).getLoginService().get().login(logingRequest);
	}
6、测试结果
public // 测试类
class Test {
    
    

	public static void main(String[] args) {
    
    
		LoginServiceBiz loginServiceBiz = new LoginServiceBiz();
		LogingRequest logingRequest = new LogingRequest();
		logingRequest.setLoginTypeCode("wechat");
			System.out.println("=======用最普通的写法开始登录=========");
		loginServiceBiz.loginWithIfElse(logingRequest);
		System.out.println("=======用最普通的写法登录成功=========");
		System.out.println();
		System.out.println("=======用接口分离的写法开始登录=========");
		loginServiceBiz.loginWithInterface(logingRequest);
		System.out.println("=======用接口分离的写法登录成功=========");
		System.out.println();
		System.out.println("=======用策略模式java8的写法开始登录=========");
		loginServiceBiz.loginWithJava8(logingRequest);
		System.out.println("=======用策略模式java8写法登录成功=========");

	}

}

执行结果:

=======用最普通的写法开始登录=========
从微信渠道登录
=======用最普通的写法登录成功=========

=======用接口分离的写法开始登录=========
从微信渠道登录
=======用接口分离的写法登录成功=========

=======用策略模式java8的写法开始登录=========
从微信渠道登录
=======用策略模式java8写法登录成功=========

猜你喜欢

转载自blog.csdn.net/m0_53085735/article/details/112969996
今日推荐