Java解耦的最佳方式-策略工厂模式

前言

在实际开发中,单独使用一种模式可能无法更完美解决问题,需要多种模式结合使用,比如发消息的时候,有多种消息类型可以支持,但是不同的消息类型有不同的处理逻辑,如果仅仅使用其中一种的话,并不能很好的解决问题,本期采用策略工厂模式给大家演示一下如何在代码中更好的解耦。

一、自定义消息处理注解?

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MessageHandler {
    int messageType() default 0;
}

二、定义消息处理类

1.定义策略接口

public interface Strategy {
    void system();
}

2.定义策略接口实现类

以下@MessageHandler(messageType = value)中的value值可以换成枚举类里定义的,不过要求是常量:

@Slf4j
@Service
@MessageHandler(messageType = 1)
public class MessageA implements Strategy {
    @Override
    public void system() {
        log.info("MessageA");
    }
}
@Slf4j
@Service
@MessageHandler(messageType = 2)
public class MessageB implements Strategy {
    @Override
    public void system() {
        log.info("MessageB");
    }
}

@Slf4j
@Service
@MessageHandler(messageType = 3)
public class MessageC implements Strategy {
    @Override
    public void system() {
        log.info("MessageC");
    }
}

3.定义消息类型枚举

@Getter
@AllArgsConstructor
public enum MessageTypeEnum {
    MESSAGE_A(1, "MESSAGE_A"),
    MESSAGE_B(2, "MESSAGE_B"),
    MESSAGE_C(3, "MESSAGE_C");

    private Integer code;

    private String msg;

    public static MessageTypeEnum getMessageTypeEnum(int code) {
        for (MessageTypeEnum messageTypeEnum : MessageTypeEnum.values()) {
            if (messageTypeEnum.getCode() == code) {
                return messageTypeEnum;
            }
        }
        return null;
    }
}

三、创建策略的工厂类

/**
 * 策略工厂类
 *
 * @author Songsong
 * @date 2020-09-14 21:18
 */
@Service
public class StrategyFactory implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    private ImmutableMap<Integer, Strategy> strategyMap;

    private static ImmutableSet.Builder<Integer> builder = ImmutableSet.builder();

    @PostConstruct
    public void init() {
        Map<String, Object> beanMap = applicationContext.getBeansWithAnnotation(MessageHandler.class);
        Map<Integer, Strategy> map = beanMap.values().stream()
                .collect(Collectors.toMap(
                        v -> {
                            MessageHandler messageHandler = v.getClass().getAnnotation(MessageHandler.class);
                            int messageType = messageHandler.messageType();
                            MessageTypeEnum messageTypeEnum = MessageTypeEnum.getMessageTypeEnum(messageType);
                            if (Objects.isNull(messageTypeEnum)) {
                                throw new IllegalArgumentException("message type error:" + messageType);
                            }
                            builder.add(messageHandler.messageType());
                            return messageHandler.messageType();
                        },
                        v -> (Strategy) v
                ));
        strategyMap = ImmutableMap.<Integer, Strategy>builder().putAll(map).build();
    }
    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public Strategy getStrategy(Integer templateHandler) {
        return strategyMap.get(templateHandler);
    }

    public ImmutableMap<Integer, Strategy> getMaps() {
        return strategyMap;
    }
}

四、项目使用

@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class StrategyTest {

	@Resource
	private StrategyFactory strategyFactory;

	@Test
	public void test() {
		strategyFactory.getStrategy(MessageTypeEnum.MESSAGE_A.getCode()).system();
	}

}

预期输出:MessageA,我们来看看效果:
在这里插入图片描述

结果符合预期,完美!!!

总结

以上就是策略工厂的使用,用于解决不同的消息类型处理不同的逻辑的业务场景,有其他类似的场景也可以使用以上方法,可以代替大量的if else、swith case等判断操作,用户代码逻辑中的解耦很实用,希望以上介绍可以帮助到你!!!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值