❓库房地址:github.com/Chengyunlai…
作者:Chengyunlai 语雀 (yuque.com)
邮箱:yunlai_cheng@163.com
1. 介绍
运用布景:依据某些条件匹配相应子完成类的逻辑,见图 1-1
防止:运用IF-ELSE
来处理这样的逻辑。原因:不便于后续晋级迭代的维护,能够细心考虑一下,如果考虑不出来还有有疑问,能够提出问题:为什么不便于后续晋级迭代。
图 1-1
2. 实战
布景: 大模型的布景下,我司有两个事务:
- ChatGPT3_5;
- ChatGPT4_0
现在需求依据用户付费的状况,判别用户到底挑选哪个模型
架构设计图:
全体架构设计如 图 1-2 所示,从Application
运用 ChatContext
这个类,传入 User
,让其(ChatContext
)调用getReplyInfo
,依据 User
的条件来执行ChatService
的完成类。
我知道,许多朋友肯定想在ChatContext
的getReplyInfo
这个办法中运用IF-ELSE
的办法来控制到底是具体调用3_5
还是4_0
,咱们防止运用这样的办法,之前说了:这样不便于拓宽代码。
解决的办法是运用枚举类,先上代码,然后去考虑为什么运用枚举类就能够解决逻辑分支的判别了。
2.1. 为什么用枚举类
package top.chengyunlai.architecture.chat;
import java.util.Objects;
/**
* @author Chengyunlai
* @description: TODO
* @date 2023/7/25
*/
public enum ChatEnum {
CHAT_3_5(1,"chat3"),
CHAT_4_0(2,"chat4");
private Integer flag;
private String serverName;
ChatEnum(Integer flag, String serverName) {
this.flag = flag;
this.serverName = serverName;
}
public Integer getFlag() {
return flag;
}
public void setFlag(Integer flag) {
this.flag = flag;
}
public String getServerName() {
return serverName;
}
public void setServerName(String serverName) {
this.serverName = serverName;
}
public static String getStrategyServiceByType(Integer type) {
for (ChatEnum d : ChatEnum.values()) {
if (Objects.equals(type, d.getFlag())) {
return d.getServerName();
}
}
// 兜底处理
return "chat3";
}
}
解读: 11 行和 12 行定义了两个枚举类型,flag
是条件:匹配用户传入的条件;serverName
是对应的服务名(Spring 容器称号),这样的定义就方便后边只需求经过值就能拿到对应的服务称号了。
然后咱们封装了一个办法getStrategyServiceByType
,在 38 行。ChatEnum.values()
拿出咱们定义的所有的枚举(flag,serverName)
,然后经过增强 for 循环去判别传入进来的类型去匹配对应的值。
当然兜底处理是返回"chat3"
长处: 这样做的好处就是,新增ChatService
子类的时分,只需求新增一个枚举即可。
2.2. ChatContext 的妙用
咱们知道在 ChatContext 需求去调用不同的 ChatService 完成类,有没有什么好的办法将他们注入进来呢?
- 经过枚举类,获取取得对应容器的姓名:String
- 那么经过这个姓名就应该能拿到这些容器对应的实例,Yes,Spring 帮咱们能做到这一点,要害点就在这个 Map 方式的注入
@Autowired
private Map<String,ChatService> chatServiceMap;
经过 IDEA 东西咱们能够发现,它指向了两个实例(实例运用@Service
注解润饰),这说明运用主动注入的办法 + Map 的办法实际上已经做到了(key
:容器名,value
:容器实例)。
接下去要考虑的就是,怎么调配枚举类去取对应的 key 即可。
也就是getReplyInfo
办法
public String getReplyInfo(User user){
// 经过 Map 拿到姓名对应的容器实例
return chatServiceMap.get(
// 经过枚举取得对应的容器姓名
ChatEnum.getStrategyServiceByType(
// 条件
user.getIsChatGPTType()
)
).getReplyInfo();
}
3. 代码
懂了这个重要的枚举类,咱们就来开发剩余的代码。
3.1. ChatService
package top.chengyunlai.architecture.chat;
public interface ChatService {
String getReplyInfo();
}
3.2. ChatServiceImpl3_5
package top.chengyunlai.architecture.chat.impl;
import org.springframework.stereotype.Service;
import top.chengyunlai.architecture.chat.ChatService;
/**
* @author Chengyunlai
* @description: TODO
* @date 2023/7/25
*/
@Service("chat3")
public class ChatServiceImpl3_5 implements ChatService {
@Override
public String getReplyInfo() {
return "chat3.5";
}
}
3.3. ChatServiceImpl4_0
package top.chengyunlai.architecture.chat.impl;
import org.springframework.stereotype.Service;
import top.chengyunlai.architecture.chat.ChatService;
/**
* @author Chengyunlai
* @description: TODO
* @date 2023/7/25
*/
@Service("chat4")
public class ChatServiceImpl4_0 implements ChatService {
@Override
public String getReplyInfo() {
return "chat4.0";
}
}
3.4. User 类
package top.chengyunlai.architecture.chat;
import lombok.Data;
/**
* @author Chengyunlai
* @description: TODO
* @date 2023/7/25
*/
public class User {
// 是否开启 ChatGPT4,1 为不开启;2 为开启
private Integer chatGPTType;
public void setChatGPTType(Integer chatGPTType) {
this.chatGPTType = chatGPTType;
}
public Integer getIsChatGPTType(){
return this.chatGPTType;
}
}
3.5. 枚举类
见上
3.6. ChatContext
package top.chengyunlai.architecture.chat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
/**
* @author Chengyunlai
* @description: 对话上下文,归于对话中间件,依据条件挑选对应的真实对话服务
* @date 2023/7/25
*/
@Service
public class ChatContext {
@Autowired
private Map<String,ChatService> chatServiceMap;
public String getReplyInfo(User user){
// 经过 Map 拿到姓名对应的容器实例
return chatServiceMap.get(
// 经过枚举取得对应的容器姓名
ChatEnum.getStrategyServiceByType(
// 条件
user.getIsChatGPTType()
)
).getReplyInfo();
}
}
如果本文对你有协助的话,记住点个赞再走呀。愿你在技能学习的路上不断的突飞猛进!