策略模式簡潔的實現(xiàn)方式,你知道嗎?
if else 太多了
最近跟著公司的大佬開發(fā)了一款IM系統(tǒng),類似QQ和微信哈,就是聊天軟件。我們有一部分業(yè)務邏輯是這樣的。
if (msgType = "文本") {
// dosomething
} else if(msgType = "圖片") {
// doshomething
} else if(msgType = "視頻") {
// doshomething
} else {
// doshomething
}
就是根據(jù)消息的不同類型有不同的處理策略,每種消息的處理策略代碼都很長,如果都放在這種if else代碼快中,代碼很難維護也很丑,所以我們一開始就用了策略模式來處理這種情況。
策略模式還挺簡單的,就是定義一個接口,然后有多個實現(xiàn)類,每種實現(xiàn)類封裝了一種行為。然后根據(jù)條件的不同選擇不同的實現(xiàn)類。
實現(xiàn)過程
消息對象,當然真實的對象沒有這么簡單,省略了很多屬性。
@Data
@AllArgsConstructor
public class MessageInfo {
// 消息類型
private MsgTypeEnum type;
// 消息內(nèi)容
private String content;
}
消息類型是一個枚舉類。
public enum MsgTypeEnum {
TEXT(1, "文本"),
IMAGE(2, "圖片"),
VIDEO(3, "視頻");
public final int code;
public final String name;
MsgTypeEnum(int code, String name) {
this.code = code;
this.name = name;
}
}
定義一個消息處理策略接口。
public interface MessageStrategy {
void handleMessage(MessageInfo messageInfo);
}
有2個消息處理接口,分別處理不同的消息。
處理文本消息
@Service
@MsgTypeHandler(value = MsgTypeEnum.TEXT)
public class TextMessageStrategy implements MessageStrategy {
@Override
public void handleMessage(MessageInfo messageInfo) {
System.out.println("處理文本消息 " + messageInfo.getContent());
}
}
處理圖片消息;
@Service
@MsgTypeHandler(value = MsgTypeEnum.IMAGE)
public class ImageMessageStrategy implements MessageStrategy {
@Override
public void handleMessage(MessageInfo messageInfo) {
System.out.println("處理圖片消息 " + messageInfo.getContent());
}
}
可以看到上面我們用了一個MsgTypeHandler注解來表明策略類是用來處理哪種消息的?
@Documented
@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MsgTypeHandler {
MsgTypeEnum value();
}
至此,所有代碼就已經(jīng)寫完了,來跑一下測試代碼;
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {
private Map<MsgTypeEnum, MessageStrategy> messageStrategyMap;
@Resource
private void setMessageStrategyMap(List<MessageStrategy> messageStrategies) {
messageStrategyMap = messageStrategies.stream().collect(
Collectors.toMap(item -> AnnotationUtils.findAnnotation(item.getClass(), MsgTypeHandler.class).value(), v -> v));
}
@Test
public void contextLoads() {
MessageInfo messageInfo = new MessageInfo(MsgTypeEnum.TEXT, "這是一個文本消息");
MessageStrategy messageStrategy = messageStrategyMap.get(messageInfo.getType());
// 處理文本消息 這是一個文本消息
messageStrategy.handleMessage(messageInfo);
}
}
在setMessageStrategyMap方法上加@Resource注解,將消息類型及其對應的策略類保存到map中,當消息來臨的時候就能從map中獲取到對應的策略類,然后處理消息。