策略模式
策略模式在源代码中通常以Strategy
、Policy
、Handler
结尾,其中大多数以后2者为多,比如在JUC中,创建ThreadPoolExecutor
对象需要一个RejectedExecutionHandler
对象,该接口就是典型的策略模式接口。他有几个子类,比如DiscardOldestPolicy
、AbortPolicy
等。
应用场景:JUC
创建
ThreadPoolExecutor
对象需要一个RejectedExecutionHandler
对象,改接口就是一种策略模式,拥有不同的实现,每个实现都代表着一种不同的拒绝策略。
策略工厂消除ifelse
Spring策略工厂方式一
相关设计模式:
策略
工厂
享元
spring Bean生命周期方法
模板方法
消息类型枚举,是判别策略的维度:
public enum MessageType {
TYPE_A,
TYPE_B,
TYPE_C,
;
}
策略接口 MqSenderStrategy
,实现Spring生命周期方法,用于在初始化后注册策略实现到Factory中:
public interface MqSenderStrategy extends InitializingBean{
void send(String message);
}
抽象策略,可以引入模板方法模式,实现公共的业务逻辑:
public abstract class AbstractMqSenderStrategy implements MqSenderStrategy {
protected abstract MessageType getMessageType();
// 使用生命周期方法注册到工厂类中
// 也可以使用@PostConstuct
@Override
public void afterPropertiesSet() throws Exception {
MqSenderStrategyFactory.registrySender(getMessageType(), this);
}
/**
* 发送模板代码封装
*/
@Override
public void send(String message) {
// Connection c = new Connection(); 创建连接
// c.connect()
doSend(message);
// c.disconnect(); 断开连接
}
protected abstract void doSend(String message);
}
策略实现:
@Component
public class ASenderStrategy extends AbstractMqSenderStrategy {
@Override
protected MessageType getMessageType() {
return MessageType.TYPE_A;
}
@Override
public void doSend(String message) {
}
}
工厂类:
public class MqSenderStrategyFactory {
private static final ConcurrentHashMap<MessageType, MqSenderStrategy> SENDER_MAP;
static {
SENDER_MAP = new ConcurrentHashMap<>(MessageType.values().length);
}
public static void registrySender(MessageType messageType, MqSenderStrategy mqSenderStrategy) {
if (messageType == null) {
throw new RuntimeException("注册Sender到Factory失败,消息类型不可为null");
}
if (SENDER_MAP.get(messageType) != null) {
throw new RuntimeException("相同类型的消息处理策略只能注册到Factory一次");
}
SENDER_MAP.put(messageType, mqSenderStrategy);
}
public static MqSenderStrategy getSender(MessageType messageType) {
return SENDER_MAP.get(messageType);
}
}
Spring策略工厂方式二
与方式一相比:
Factory类加入Spring IoC
策略类使用Autowrid机制自动加入到Factory中,而不是通过生命周期钩子主动注入,策略类更简洁,与Factory耦合更小
使用List存储策略实现类,然后可以通过
@Order
注解控制策略实现类的优先级(当策略选择条件复杂时,有可能多个策略同时满足,这个可以通过优先级处理)
策略接口不需要集成生命周期函数,需要暴露getMessageType方法供工厂类使用 :
public interface MqSenderStrategy {
MessageType getMessageType();
void send(String message);
}
策略实现:
@Component
@Order(1)
@Lazy
public class ASenderStrategy extends AbstractMqSenderStrategy {
@Override
protected MessageType getMessageType() {
return MessageType.TYPE_A;
}
@Override
public void doSend(String message) {
}
}
策略工厂加入IoC,并且注入所有实现进入:
public class MqSenderStrategyFactory {
@Autowried
private List<MqSenderStrategy> sendList;
private static final ConcurrentHashMap<MessageType, MqSenderStrategy> SENDER_MAP;
static {
SENDER_MAP = new ConcurrentHashMap<>(MessageType.values().length);
}
// 工厂对象创建完毕,初始化策略工厂
@PostConstruct
public void registrStrategy() {
sendList.forEach(e - > SENDER_MAP.put(e.getMessageType()));
}
public static MqSenderStrategy getSender(MessageType messageType) {
return SENDER_MAP.get(messageType);
}
}
最后更新于
这有帮助吗?