策略模式简洁的实现方式,你知道吗?

开发 前端
策略模式还挺简单的,就是定义一个接口,然后有多个实现类,每种实现类封装了一种行为。然后根据条件的不同选择不同的实现类。

if else 太多了

最近跟着公司的大佬开发了一款IM系统,类似QQ和微信哈,就是聊天软件。我们有一部分业务逻辑是这样的。

if (msgType = "文本") {
// dosomething
} else if(msgType = "图片") {
// doshomething
} else if(msgType = "视频") {
// doshomething
} else {
// doshomething
}

就是根据消息的不同类型有不同的处理策略,每种消息的处理策略代码都很长,如果都放在这种if else代码快中,代码很难维护也很丑,所以我们一开始就用了策略模式来处理这种情况。

策略模式还挺简单的,就是定义一个接口,然后有多个实现类,每种实现类封装了一种行为。然后根据条件的不同选择不同的实现类。

实现过程

消息对象,当然真实的对象没有这么简单,省略了很多属性。

@Data
@AllArgsConstructor
public class MessageInfo {

// 消息类型
private MsgTypeEnum type;
// 消息内容
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();
}

至此,所有代码就已经写完了,来跑一下测试代码;

@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中获取到对应的策略类,然后处理消息。

责任编辑:武晓燕 来源: Java识堂
相关推荐

2024-02-05 12:08:07

线程方式管理

2023-02-13 08:10:40

Gateway网关Spring

2023-04-23 09:50:50

@BeanSpring

2023-04-28 12:37:59

Spring@Bean使用方式

2019-02-12 11:15:15

Spring设计模式Java

2024-05-20 10:37:08

Rust模式通信

2023-12-12 08:41:01

2023-02-27 07:56:55

IngressKubernetes

2024-06-12 08:05:06

2019-12-02 10:16:46

架构设计模式

2018-07-04 11:02:23

无线传输模式

2024-07-03 08:33:08

2022-09-29 15:32:58

云计算计算模式

2024-09-18 07:00:00

消息队列中间件消息队列

2021-10-14 06:52:47

算法校验码结构

2019-12-12 09:23:29

Hello World操作系统函数库

2022-03-10 08:25:27

JavaScrip变量作用域

2021-02-06 21:57:40

Debug模式Release

2022-01-19 13:57:22

ymlSpringSnakeYml

2024-04-07 00:00:00

ESlint命令变量
点赞
收藏

51CTO技术栈公众号