项目中用到的设计模式

Spring-涉及到的设计模式汇总

一、单例

项目配置:配置在Spring容器中的Bean几乎都是单例,比如Controller、Service、Facade、Dao这些无状态的Bean。

RSA加解密用到的BouncyCastleProvider,使用饿汉式单例

二、代理模式

项目配置:Shiro权限管理、Spring事务管理器、线程池异步注解

1、利用注解AOP解决后台管理系统用户操作日志记录;
接口请求响应参数打印、参数校验、MDC线程追踪、统一异常处理
2、利用Mybatis的Interceptor接口,来实现读写分离

三、享元模式

项目配置:常量池的String对象、缓存、数据库连接池、线程池

利用Mybatis的Interceptor接口,来实现读写分离的时候,将某个语句对应某个库缓存到ConcurrentHashMap中,如果存在则直接取,不存在则保存。

四、观察者模式

工具框架自带:ZOOKEEPER的WATCHER、REDIS发布订阅

消息队列发布订阅、SPRING的ApplicationEventhe ApplicationListener

五、模板方法模式

框架:
MYBATIS:BaseExecutor和SimpleExecutor等子类,还有BaseTypeHandler和所有的子类例如IntegerTypeHandler

protected abstract int doUpdate(MappedStatement ms, Object parameter) throws SQLException;

    protected abstract List doFlushStatements(boolean isRollback) throws SQLException;

    protected abstract  List doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds,
            ResultHandler resultHandler, BoundSql boundSql) throws SQLException;

渠道系统对接第三方接口运用模板方法:

1、调用验证组件验证请求参数
2、拼装请求报文,并根据特定编码将报文转换为byte[]数组
3、调用通信组件发起HTTP请求
4、处理响应的二进制报文
5、返回响应

基本上对接大部分第三方接口都是这种模式,因此需要继承重写的主要就是第2、4步骤,验证组件和通信组件可以另外配置一个工厂,其中的流程异常全部都在父类中

validator.validate(req)
byte[] request = buildRequestBytes(req)
byte[] response = transferHandler.send(request)
resp = resolveResponse(response)
return response

银行ABS系统:

封包、解包、赎回、转让、调整接口,处理方法都是:
1、数据库插入一条处理中调用记录
2、异步任务处理
3、构造返回响应
所以需要重写的只有第二步实际任务处理


项目中用到的设计模式_第1张图片
image.png

另外4个接口的任务处理也有同样的步骤:
1、下载FTP文件
2、文件处理
3、更新数据库调用记录处理后的状态
实际上需要重写的也只有第二步文件处理


项目中用到的设计模式_第2张图片
image.png

六、工厂+策略模式

解锁新姿势:探讨复杂的 if-else 语句“优雅处理”的思路

额度系统针对不同资方有不同额度策略,举个简单例子,就还款而言,有的循环额度资方还款恢复额度,而有的是半循环额度资方还款不恢复用户额度,还有的资方可能还款时候还要做某些操作。正常情况肯定免不了if-else或者switch来选择处理方式,当策略变多的时候代码就会比较繁杂。因此采用这俩种模式来解决if-else问题。

接口
public abstract class AbstractRepaymentCallbackHandler {
public abstract void increase(DTO dto);
} 

多个实现类及重写方法,这边瞎写一下
public class Handler1 extends AbstractRepaymentCallbackHandler{
...
}
public class Handler2 extends AbstractRepaymentCallbackHandler{
...
}
public class Handler3 extends AbstractRepaymentCallbackHandler{
...
}
工厂 把上面三个类及对应名称put进去,这些都是Spring的Bean
public class HandlerProcessor{
private Map repaymentCallbackHandlerMap = new HashMap<>()

publi void increase(CompanyInfo company,DTO dto){
 repaymentCallbackHandlerMap.get(company.getRepaymentCallbackHandler()).increase(dto);
}
}

数据库保存资方对应处理器关系,比如资方ID 1 -> "handler1" 等等

这样最终在需要调用increase的时候就只要handlerProcessor.increase就行了,已经做好了配置,不用管什么资方用什么处理器。另外get那一部可以拆分,没配置的资方取一个默认处理器。

另外Spring环境的工厂还可以这样注入:

/**
 * UC API降级处理器工厂
 *
 * @Date 2020/12/26
 **/
@Component
public class DegradeHandlerFactory implements ApplicationContextAware {

    private Map degradeHandlerFactory;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        Map beansMap = applicationContext.getBeansOfType(UcApiDegradeHandler.class);
        degradeHandlerFactory = beansMap.values()
                .stream()
                .collect(Collectors.toMap(UcApiDegradeHandler::getHandlerKey, Function.identity()));
    }

    /**
     * 获取对应接口的降级处理器
     *
     * @param handlerKey
     * @return
     */
    public UcApiDegradeHandler getHandler(String handlerKey) {
        return degradeHandlerFactory.get(handlerKey);
    }
}

七、适配器

Mybatis日志适配器:具体的可以关注这几个类
org.apache.ibatis.logging.LogFactory
Log
Slf4jImpl
事实上可以理解为:LogFactory工厂按照各种日志实现类的优先级去尝试加载一种日志实现类,所有日志操作都抽象为Log接口,然后Log接口的方法实现(比如Slf4jImpl)再去调用真正的日志实现。这里目的就是为了各种不同的日志实现提供一个统一的接入接口
Mybatis日志适配器

八、建造者模式

Lombok @Builder

你可能感兴趣的:(项目中用到的设计模式)