浅谈Java常见设计模式(五)

lgli

共 2718字,需浏览 6分钟

 · 2021-04-30

星辰闹成一串 月色笑成一弯
傻傻望了你一晚 怎么看都不觉得烦  爱自己不到一半 心都在你身上  只要能让你快乐 我可以拿一切来换

在SpringMVC三层架构的项目中,已然习惯于前端写一个请求,后端对应有个controller来执行这个请求的模式了,那么今天就先仿制下这个模式。

那么首先,需要有一个统一的入口来收集这些请求,所有需要处理的请求都先要传入到这个入口中,然后这个入口类会根据获取到的请求的类型,分配到对相应的控制器去处理。
这里简化下这个过程,程序接收到一个字符串参数,然后根据这个参数,对应找到自己的处理器
首先定义两个处理器AController、BController实现公共接口Controller

29e34c60fa695bc829d22e5ee571deb4.webp


AController、BController

14b21a691a519e358c895091525ce71e.webp


6f866656f6d41402c9ed6f65204c8558.webp


然后是这个Dispatch:

be94e56a753894b491952a863e4d11ac.webp


客户端调用:

b73499c511fd68ba4a8d96340d10a455.webp


这里,根据request的请求url,经过Dispatch接收处理,然后分配到对应的处理器中处理。

让我们看下类图:

6ff43851642985dd21dc5d362285b2cf.webp


这里Dispatch,持有多个Controller的实现,然后接收到具体的任务,下发到具体的实现中去,这就是一个简单的委派(Delegate)。

委派模式,其实并非23种设计模式中的一种,但是它的实用性,却体现在很多的框架中,比如我们所以熟知的SpringMVC,其中有个DispatchServlet就是一个委派的较好体现,当web端的请求到达后端,通过DispatchServlet分发给不同的Controler处理。


上述过程,其实还通过另外一种方式来实现---策略,这里根据请求的关键字,调用响应的处理器处理,可以类比的把这些处理器,当做一个一个的策略,相应的,根据关键字,得到响应的策略

下面通过这种方式来实现下这个过程:
首先有一个抽象的Strategy:

935982d6c947db544e4d9823de1493e1.webp



然后这里模拟了3种策略,分别是A、B和一个空的策略

921296a7a5cf81e07cc94a6282b2a693.webp


3d841fdc22c613b6a8caa502fbf915db.webp


还有一个空的策略:


a76608b9ddddf19d6f9a032058e4112e.webp


然后这里需要一个统一执行器根据不同的策略来执行请求:

890769b3550a115f0120d505da0d7f6e.webp


看下测试类:

aabd159a41d6c71fdb1b8649589f2d25.webp


根据不同的关键字,来选择不同的策略,同时执行响应的策略。

这里,把这种模式称为策略模式:

62e15efab69837dd2ff118c6539a02d2.webp


上述代码,其实可以利用前面说到的一些设计模式,进行一定的优化,比如根据关键字选择什么策略的时候,完全可以使用工厂模式来实现。

那么改造下上述过程,3种策略不变,这里新建一个策略工厂类StrategyFactory:

package com.lgli.behavior.delegatestrategy.v3;

import java.util.HashMap;import java.util.Map;
/** * * 策略工厂 * @author lgli */

public class StrategyFactory {
private static final StrategyFactory strategyFactory = new StrategyFactory();
private static final ControllerStrategy EMPTY_STRATEGY = new EControllerStrategy();
private StrategyFactory(){}
private static final Map<String,ControllerStrategy> map = new HashMap<>();
static { map.put(StrategyKey.A.name(), new AControllerStrategy()); map.put(StrategyKey.B.name(), new BControllerStrategy()); map.put(StrategyKey.EMPTY.name(), new EControllerStrategy()); }
public static StrategyFactory getInstance(){ return strategyFactory; }
public ControllerStrategy getStrategy(String key){ ControllerStrategy controllerStrategy = map.get(key); return controllerStrategy == null ? EMPTY_STRATEGY : controllerStrategy; }
enum StrategyKey{ A,B,EMPTY }
}

策略工厂使用饿汉式单例,然后先将所有的策略全部缓存起来


对外提供实例化工厂实例方法getInstance和根据key获取对应的策略方法getStrategy


请求处理器类DealController<委派类>:


package com.lgli.behavior.delegatestrategy.v3;

/** * @author lgli */public class DealController {
private static final DealController dealController = new DealController();
private DealController(){}
public static DealController getInstance(){ return dealController; }
public void deal(String key){ StrategyFactory strategyFactory = StrategyFactory .getInstance(); ControllerStrategy strategy = strategyFactory .getStrategy(key); strategy.deal();    }}

然后测试类:

c574823d733a7aa3a4734945e240c933.webp


这个时候,代码就简单明了许多了。。。。。。也比较好维护些了。



欢迎多多指教

点个赞再走了,谢谢!


浏览 27
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报