策略模式結(jié)合spring使用最佳實戰(zhàn),老程序員才這么寫

策略模式結(jié)合spring使用
我們在項目中經(jīng)常會遇到if else 特別多的情況,比如前端傳了一個type,不同type 數(shù)據(jù)處理的流程邏輯也不相同,正常情況我們會怎么做呢?就會像下面一樣:
if("aa".equals(type)){
//一頓處理
}else if("bb".equals(type)){
//又是一頓處理
}else if(){
}else if(){
}else if(){
}
當然了,自己寫的呢我們自己肯定可以看懂了,無所謂啦但是如果讓別人看到肯定是這樣了:

但是大家都不想寫出這樣的代碼,這時有人就會說了:"沒辦法啊,剛開始產(chǎn)品給出的需求沒有這么多的邏輯 隨著產(chǎn)品的需求的迭代,項目時間緊只能在原有的代碼上if else了,我們也是無辜的啊!"
確實這是沒法避免的 所以一種就是靠自己的項目經(jīng)驗在開始寫的時候就知道后續(xù)有可能出現(xiàn)這種情況,第二種就是在邏輯判斷多的時候及時重構(gòu)代碼(最苦逼了)
說了這么多接下來就是帶著大家怎么解決這種 if else多的問題了 這里我使用的是策略模式

成品代碼如下 controller 層
@PostMapping("/action")
public String action(@RequestBody ActionVO actionVO){
//大致就是這個思想 具體的細節(jié) 需要 你們自己補充啦 什么日志 異常啥的 自己處理一下 愛你們
ActionHandler actionHandler = actionHandlerFactory.getRoutMap().get(actionVO.getType());
if(actionHandler!=null){
actionHandler.handler(actionVO);
}
return "success";
public class ActionHandlerFactory {
private static Map<Byte, ActionHandler> ROUT_MAP;
@Autowired
private TeacherActionHandler teacherActionHandler;
@Autowired
private UserActionHandler userActionHandler;
@PostConstruct
private void init(){
ROUT_MAP= ImmutableMap.<Byte,ActionHandler>builder()
.put(ActionEnum.USER.getType(),userActionHandler)
.put(ActionEnum.TEACHER.getType(),teacherActionHandler).build();
}
public Map<Byte,ActionHandler> getRoutMap(){
return ROUT_MAP;
}
}

真的沒有 if else 了,其實是將真正執(zhí)行代碼的handler放在了map中 這樣是不是變得優(yōu)雅了不少啊!

你想變得更加優(yōu)雅嗎 如果你想變得更加優(yōu)雅 我?guī)憷^續(xù)研究像我這次的執(zhí)行業(yè)務(wù)邏輯的代碼 類的繼承結(jié)構(gòu)圖如下
RequestHandler
public interface RequestHandler<T> {
public void handler(T t);
public void write(T t);
public void read(T t);
public abstract class ActionHandler implements RequestHandler<ActionVO> {
@Override
public void handler(ActionVO actionVO) {
read(actionVO);
write(actionVO);
insert(actionVO);
}
@Override
public void write(ActionVO actionVO) {
}
@Override
public void read(ActionVO actionVO) {
}
public abstract void insert(ActionVO actionVO);
}
這里使用了一個模板模式 這樣的話我們真正的業(yè)務(wù)邏輯執(zhí)行類只需要繼承這個ActionHandler 重寫里面自己想要的方法就可以了
public class UserActionHandler extends ActionHandler{
@Override
public void insert(ActionVO actionVO) {
// 就是寫 Ctrl+V
System.out.println("im user");
}
@Override
public void write(ActionVO actionVO) {
super.write(actionVO);
//自己邏輯 就是 Ctrl+C
}
@Override
public void read(ActionVO actionVO) {
super.read(actionVO);
//自己的邏輯 卡卡就是干
}
附帶一下這個demo引入的jar
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>21.0</version>
</dependency>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
</dependencies>
用了上述兩種設(shè)計模式,這樣再一看是不是代碼更加的優(yōu)雅,更加的易讀了,而且在以后 改每個模塊的業(yè)務(wù)邏輯的時候只需要改自己的handler就可以,也不會影響到其他的代碼。
以上就是我個人的理解哈哈哈

如果有什么寫的不對的地方歡迎大家給我留言指正!
