设计模式采用模板模式加策略模式加工厂模式
模板模式简述:创建模板接口 父类实现模板接口 子类继承父类 子类决定是否采用父类模板内容
策略模式简述:创建一个决策类 多个子类继承或实现父类同一接口 由决策类决定采用那个子接口
工厂模式:多个子类继承父类 根据子类名称向上转换父类 实现子类方法
应用场景 用户参加多个活动 多个活动保存和展示不同数据
使用ActivityAbstractExecutor创建要决策的接口
ActivityAbstractExecutor抽象类实现决策接口对每个决策创建模板 完成模板模式
多个子级接口继承ActivityAbstractExecuto 实现策略模式 由于是继承父类 每个子级接口可决定是否实现父类接口
创建AgentActivityEnum枚举类 记录子级接口
创建ActivityFactory工厂接口 遍历枚举将id和接口名放入map中
根据传入的值来决定父类实现哪个子类接口
public interface ActivityTemplate {
public void execute();
}
// 这个是抽象策略
public abstract class ActivityAbstractExecutor implements ActivityTemplate{
@Override
public void execute(){
}
}
//不同业务继承
@Service("goldMemberExecutor")
public class GoldMemberExecutor extends ActivityAbstractExecutor {
/***
*黄金会员业务逻辑
*@param
*@return: void
*@author: 小清新
*@Date: 2022-09-26 10:11
**/
@Override
public void execute() {
//业务代码
System.out.println("这里是黄金会员");
}
}
@Service("silverMemberExecutor")
public class SilverMemberExecutor extends ActivityAbstractExecutor {
/***
*白银会员业务逻辑
*@param []
*@return: void
*@author: 小清新
*@Date: 2022-09-26 10:12
**/
@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<>();
//遍历枚举添加到map中
static {
AgentActivityEnum[] activityEnums = AgentActivityEnum.values();
for (AgentActivityEnum activityEnum : activityEnums) {
beanNames.put(activityEnum.getActivityId(), activityEnum.getBeanName());
}
}
/**通过Map注入,通过 spring bean 的名称作为key动态获取对应实例 这个地方可以学习下,Spring在注入的时候是可以根据类型注入的。**/
@Resource
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 {
@Resource
private ActivityFactory activityFactory;
@GetMapping("/strategy/test")
public String get(){
activityFactory.execute(AgentActivityEnum.GOLD_ACTIVITY.getActivityId());
activityFactory.execute(AgentActivityEnum.SILVER_ACTIVITY.getActivityId());
return "123123123";
}
}