1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > java-抽象工厂模式+工厂方法模式+策略模式简单应用实战(登录场景)

java-抽象工厂模式+工厂方法模式+策略模式简单应用实战(登录场景)

时间:2024-01-23 10:24:26

相关推荐

java-抽象工厂模式+工厂方法模式+策略模式简单应用实战(登录场景)

前言

设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。使用设计模式的目的:为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 设计模式使代码编写真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。策略模式是oop中最著名的设计模式之一,是对方法行为的抽象,可以归类为行为设计模式,也是oop中interface经典的应用。其特点简单又实用,是我最喜欢的模式之一。策略模式定义了一个拥有共同行为的算法族,每个算法都被封装起来,可以互相替换,独立于客户端而变化。策略模式本身的实现比较简单,但是结合单例模式+简单工厂模式+注解+反射,可以构造出近乎完善的策略模式,彻底的消除if-else。工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现

大家假设这样一个场景,比如很多类型分别处理不同的业务逻辑,这些类型以后可能会持续增加到很多很多,最简单的办法就是是一直使用if else,这样会是我们的代码维护变得越来发咋,但根据“开-闭原则”的宗旨:对扩展开放,对修改关闭。后面就想到使用工厂模式+策略模式替代ifelse;

业务场景:

我们常见的登录业务,是每个系统都必不可少的登录:可以分为如下几种登录方式:1、 账号密码登录2、 手机号验证码登录3、 手机号一键登录4、 微信登录这时候我们按照常规的开发不周的话就会使用到很多的if else 如下:@ApiOperation(value = "登录", notes = "用户登录")@ApiImplicitParams({@ApiImplicitParam(name = "username", value = "用户名(手机号)", required = true, paramType = "query"),@ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "query"),@ApiImplicitParam(name = "loginType", value = "登录方式", defaultValue = "password:密码 code:验证码 onekey:手机号一键登陆", required = true, paramType = "query")})@PostMapping("/login")public Result login(@RequestParam(value = "username") String username,@RequestParam(value = "password") String password,@RequestParam(value = "loginType") int loginType) {if(loginType == 1){System.out.println("账号密码方式登录!!!");}else if(loginType == 2){System.out.println("手机号验证码方式登录!!!");}if(loginType == 3){System.out.println("手机号一键登录!!!");}else {System.out.println("登录方式错误!!!");}return Result.ok();// return loginService.login(dto.getLoginType(), dto.getUsername(), dto.getPassword(), null);}当使用抽象工厂模式+工厂方法模式+策略模式 这些设计模式结合使用的话,就会使我们的代码变得非常简洁,维护起来也非常简单,下面直接上改进实现步骤

具体结构:

1、登录类型自动义注解类

import java.lang.annotation.*;/*** 登录类型自动义注解类*/@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public @interface LoginChannel {/*** 登录方式 code* @return 规定的code*/String code();}

2、登录类型code常量类

/*** 登录方式code常量类*/public final class LoginChannelCode {private LoginChannelCode() {throw new AssertionError("不能产生实例");}/** 密码方式 登录 */public static final String PASSWORD_LOGIN_CODE = "password";/** 验证码 登录 */public static final String VERIFCODE_LOGIN_CODE = "code";/** 一键登录 */public static final String ONEKEY_LOGIN_CODE = "onekey";}

3、LoginService登录接口入口类

import com.whcloud.wmp.utils.Result;/*** 登录接口*/public interface LoginService {/*** 登录* @param loginType 登录方式* @param userName 用户名* @param password 密码* @param code 验证码* @return*/Result login(String loginType, String userName, String password, String code);}

响应结果类:import com.alibaba.fastjson.annotation.JSONField;import com.fasterxml.jackson.annotation.JsonIgnore;import mon.collect.Maps;import com.whcloud.wmp.domain.Enum.ErrorCode;import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import lombok.Data;import java.io.Serializable;import java.util.Map;/*** @author*/@ApiModel(value = "响应结果")@Datapublic class Result<T> implements Serializable {private static final long serialVersionUID = -6190689122701100762L;/*** 响应编码*/@ApiModelProperty(value = "响应编码:0-请求处理成功")private Integer code = 0;/*** 提示消息*/@ApiModelProperty(value = "提示消息")private String message;/*** 请求路径*/@ApiModelProperty(value = "请求路径")private String path;/*** 响应数据*/@ApiModelProperty(value = "响应数据")private T data;/*** http状态码*/private Integer httpStatus;/*** 附加数据*/@ApiModelProperty(value = "附加数据")private Map<String, Object> extra;/*** 响应时间*/@ApiModelProperty(value = "响应时间")private Long timestamp = System.currentTimeMillis();@JSONField(serialize = false, deserialize = false)@JsonIgnorepublic Integer getHttpStatus() {return httpStatus;}@JSONField(serialize = false, deserialize = false)@JsonIgnorepublic boolean isOk() {return this.code == ErrorCode.OK.getCode();}public static Result ok() {return new Result().code(ErrorCode.OK.getCode());}public static Result failed() {return new Result().code(ErrorCode.FAIL.getCode());}public Result code(Integer code) {this.code = code;return this;}public Result msg(String message) {if (message == null) {message = "";}// this.message = i18n(message,message);this.message = message;return this;}public Result data(T data) {this.data = data;return this;}public Result path(String path) {this.path = path;return this;}public Result httpStatus(int httpStatus) {this.httpStatus = httpStatus;return this;}public Result put(String key, Object value) {if (this.extra == null) {this.extra = Maps.newHashMap();}this.extra.put(key, value);return this;}}

4、登录接口适配器

import com.whcloud.wmp.utils.Result;/*** 登录接口适配器*/public abstract class LoginAdapter implements LoginService {@Overridepublic Result login(String loginType, String userName, String password, String code) {return new Result();}}

5、登录方式 代理类

import com.whcloud.wmp.utils.Result;import lombok.extern.slf4j.Slf4j;import org.springframework.util.ObjectUtils;import java.util.Map;/*** 登录方式 代理类*/@Slf4jpublic class LoginDelegate extends LoginAdapter {@Overridepublic Result login(String loginType, String userName, String password, String code) {LoginService loginService = getLoginService(loginType);if(ObjectUtils.isEmpty(loginService)){return Result.failed().msg("登录方式错误!!!");}return loginService.login(loginType, userName, password, code);}private Map<String, LoginService> map;public LoginDelegate(Map<String, LoginService> map) {log.info("初始化登录方式====>{}种--{}", map.size(), map);this.map = map;}/*** @param loginType 登录方式* @return*/private LoginService getLoginService(String loginType) {if (map.containsKey(loginType)) {return map.get(loginType);}return null;}}

6、登录方式 工厂类

import org.springframework.beans.factory.FactoryBean;import org.springframework.beans.factory.InitializingBean;import org.springframework.lang.NonNull;import java.util.HashMap;import java.util.List;import java.util.Map;/*** 登录方式 工厂类*/public class LoginFactoryBean implements FactoryBean<LoginService>, InitializingBean {private LoginService loginService;@NonNullprivate List<LoginService> loginServiceList;public List<LoginService> getLoginServiceList() {return loginServiceList;}public void setLoginServiceList(@NonNull List<LoginService> loginServiceList) {this.loginServiceList = loginServiceList;}/*** 初始化方法* @throws Exception 异常*/@Overridepublic void afterPropertiesSet() throws Exception {Map<String, LoginService> map = new HashMap<>(loginServiceList.size() << 1);for (LoginService r : loginServiceList) {LoginChannel channel = r.getClass().getAnnotation(LoginChannel.class);if (channel == null) { continue; }map.put(channel.code(), r);}loginService = new LoginDelegate(map);}@Overridepublic LoginService getObject() throws Exception {return loginService;}@Overridepublic Class<?> getObjectType() {return loginService.getClass();}}

7、登录方式 config配置类(这个是关键)

import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Primary;import java.util.List;/*** 登录方式 config配置类*/@Configurationpublic class LoginChannelConfiguration {@Bean@Primarypublic LoginFactoryBean repayFactoryBean(List<LoginService> list) {LoginFactoryBean factoryBean = new LoginFactoryBean();factoryBean.setLoginServiceList(list);return factoryBean;}}

8,、具体的登录方法实现类(这里之写了三种,如有增加只需要增加一个实现类即可,注意的是的类上的自定义注解 @LoginChannel(code = LoginChannelCode.VERIFCODE_LOGIN_CODE) ),

(1)账号密码登录实现类

import com.whcloud.wmp.channel.LoginAdapter;import com.whcloud.wmp.channel.LoginChannel;import com.whcloud.wmp.channel.LoginChannelCode;import com.whcloud.wmp.utils.Result;import org.ponent;import org.springframework.util.StringUtils;@Component@LoginChannel(code = LoginChannelCode.PASSWORD_LOGIN_CODE)public class PasswordLogin extends LoginAdapter {@Overridepublic Result login(String loginType, String userName, String password, String code) {//用户名登录方式一些参数验证逻辑if(StringUtils.isEmpty(userName) || StringUtils.isEmpty(password) ){return Result.failed().msg("用户名密码不能为空!!!");}if(!"admin".equals(userName) || !"111111".equals(password) ){return Result.failed().msg("用户名或密码错误!!!");}return Result.ok().msg("密码方式登陆成功!!!");}}

(2)手机号验证码登录实现类

import com.whcloud.wmp.channel.LoginAdapter;import com.whcloud.wmp.channel.LoginChannel;import com.whcloud.wmp.channel.LoginChannelCode;import com.whcloud.wmp.utils.Result;import org.ponent;import org.springframework.util.StringUtils;@Component@LoginChannel(code = LoginChannelCode.VERIFCODE_LOGIN_CODE)public class VerifCodeLogin extends LoginAdapter {@Overridepublic Result login(String loginType, String userName, String password, String code) {//验证码登录方式一些参数验证逻辑if(StringUtils.isEmpty(userName) || StringUtils.isEmpty(code) ){return Result.failed().msg("手机号或验证码不能为空!!!");}return Result.ok().msg("验证码方式登陆成功!!!");}}

(3)手机号一键登录实现类

import com.whcloud.wmp.channel.LoginAdapter;import com.whcloud.wmp.channel.LoginChannel;import com.whcloud.wmp.channel.LoginChannelCode;import com.whcloud.wmp.utils.Result;import org.ponent;import org.springframework.util.StringUtils;@Component@LoginChannel(code = LoginChannelCode.ONEKEY_LOGIN_CODE)public class OnkeyLogin extends LoginAdapter {@Overridepublic Result login(String loginType, String userName, String password, String code) {//一键登录方式一些参数验证逻辑if(StringUtils.isEmpty(userName)){return Result.failed().msg("手机号不能为空!!!");}return Result.ok().msg("一键登录方式登陆成功!!!");}}

9、Controller接口入口

@Autowiredprivate LoginService loginService;@ApiOperation(value = "登录", notes = "用户登录")@ApiImplicitParams({@ApiImplicitParam(name = "username", value = "用户名(手机号)", required = true, paramType = "query"),@ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "query"),@ApiImplicitParam(name = "code", value = "验证码", required = true, paramType = "query"),@ApiImplicitParam(name = "loginType", value = "登录方式", defaultValue = "password:密码 code:验证码 onekey:手机号一键登陆", required = true, paramType = "query")})@PostMapping("/login")public Result login(@RequestParam(value = "username") String username,@RequestParam(value = "password") String password,@RequestParam(value = "code") String code,@RequestParam(value = "loginType") String loginType) {// if(loginType == 1){// System.out.println("账号密码方式登录!!!");// }else if(loginType == 2){// System.out.println("手机号验证码方式登录!!!");// }if(loginType == 3){// System.out.println("手机号一键登录!!!");// }else {// System.out.println("登录方式错误!!!");// }// return Result.ok();/** 改进后 **/Result result = loginService.login(loginType, username, password, code);return result;}

10、实现效果

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。