策略(Strategy)模式+工厂(Factory)模式
描述
策略模式很多时候都伴随着工厂模式一起使用。
比较拗口的说明
- 抽象策略(Strategy)类:公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
- 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。
- 环境(Context)类:持有一个策略类的引用,最终给客户端调用。
从实际使用场景中更快的来理解。
场景
- 不同等级的会员享受不同等级的服务。
// 这个是抽象策略
public abstract class ActivityAbstractExecutor {
public abstract void execute();
}
//黄金会员执行业务逻辑
@Service("goldMemberExecutor")
public class GoldMemberExecutor extends ActivityAbstractExecutor {
@Override
public void execute() {
//业务代码
System.out.println("这里是黄金会员");
}
}
//白银会员执行业务逻辑
@Service("silverMemberExecutor")
public class SilverMemberExecutor extends ActivityAbstractExecutor {
@Override
public void execute() {
//业务代码
System.out.println("这里是白银会员");
}
}
// 这是个枚举类,包含所有的会员类型
public enum AgentActivityEnum {
GOLD_ACTIVITY(1L, "goldMemberExecutor", "黄金会员活动"),
SILVER_ACTIVITY(2L, "silverMemberExecutor", "白银会员活动");
private final Long activityId;
private final String beanName;
private final String desc;
AgentActivityEnum(Long activityId, String beanName, String desc) {
this.beanName = beanName;
this.activityId = activityId;
this.desc = desc;
}
public Long getActivityId() {
return activityId;
}
public String getBeanName() {
return beanName;
}
public String getDesc() {
return desc;
}
}
// 这个是工厂启动时候扫入所有的会员服务
@Service
public class ActivityFactory {
//所有的会员服务类实例都存到一个map中。key为会员ID,value为某个会员的bean名称
private static final Map<Long, String> beanNames = new ConcurrentHashMap<>();
static {
AgentActivityEnum[] activityEnums = AgentActivityEnum.values();
for (AgentActivityEnum activityEnum : activityEnums) {
beanNames.put(activityEnum.getActivityId(), activityEnum.getBeanName());
}
}
//通过Map注入,通过 spring bean 的名称作为key动态获取对应实例 这个地方可以学习下,Spring在注入的时候是可以根据类型注入的。
@Autowired
private Map<String, ActivityAbstractExecutor> executorMap;
//工厂层执行器
public void execute(Long activityId) {
String beanName = beanNames.get(activityId);
if (null == beanName) {
return;
}
//决定最终走哪个类的执行器
ActivityAbstractExecutor executor = executorMap.get(beanName);
if (executor == null) {
return;
}
executor.execute();
}
}
// 这个是工厂启动时候扫入所有的会员服务
@RestController
public class MainTest {
@Autowired
private ActivityFactory activityFactory;
@GetMapping("/strategy/test")
public String get(){
activityFactory.execute(AgentActivityEnum.GOLD_ACTIVITY.getActivityId());
activityFactory.execute(AgentActivityEnum.SILVER_ACTIVITY.getActivityId());
return "123123123";
}
}
在编写业务代码中经常可以使用的设计模式
网友评论