java设计模式之【工厂模式+策略模式】
思想: 假如我们要买汽车,我们不在乎汽车的运输,组建过程。只需要告诉经销商我要哪辆车就可以了。即:所有事情都交给工厂底层去做,我只管调用。
例子: 我现在有个需求,是商品会搞活动,每个月都有不同的活动。我可以if else,也可以case when但是这样可能一年12个判断。
用法: 1.抽象执行器 下面这个是我的商品活动执行器,不管你每个月的活动都要走这个抽象方法
public abstract class ActivityAbstractExecutor { public abstract void execute(); }
2.活动配置枚举类
public enum AgentActivityEnum { NOVEMBER_ACTIVITY(1L, "novemberActivityExecutor", "11月运营活动"); 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; } }
3.工厂(service直接调用层)
@Slf4j @Service public class ActivityFactory { //所有的活动类实例都存到一个map中。key为商品活动ID,value为某个活动对应的类 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动态获取对应实例 @Autowired private Map<String, ActivityAbstractExecutor> executorMap; //工厂层执行器 public void execute(Long activityId) { String beanName = beanNames.get(activityId); if (StrUtil.isEmpty(beanName)) { return; } //决定最终走哪个类的执行器 ActivityAbstractExecutor executor = executorMap.get(beanName); if (executor == null) { return; } executor.execute(); } }
4.具体的活动实现类
@Slf4j @Service("novemberActivityExecutor") public class NovemberActivityExecutor extends ActivityAbstractExecutor { @Override public void execute() { //业务代码 } }
扩展维护 如果以后加了12月活动,1月活动,直接维护新的类就可以了。解耦比较好,也方便阅读。
下一篇:
用python实现快速排序法