使用策略模式 + 工厂类替换过多的IF ELSE

这里写自定义目录标题

    • 项目中的痛点
    • 定义策略模式接口
    • 具体学习任务类型实现任务基本策略接口
    • 学习任务策略工厂类
    • 建立Facade类,并使用Spring进行管理
    • 具体调用的地方

项目中的痛点

	项目中存在一个任务中的逻辑,有GO语言转成的Java的微服务工厂,学习任务部分,涉及太多业务的耦合,
需要根据学习任务类型、科目、业务线区分,各自存在自己的逻辑,一直以来的实现方式是使用if else
的方式实现,存在一个很大隐患,不熟悉的同事修改一个地方,就影响到了其他的业务线。这里急需一个更加
优雅的实现方式。

定义策略模式接口

/**
 * 学习任务策略模式接口
 * @date 2020年3月19日
 */
public interface FeedStrategy {

	/**
	 * 生成FeedContent的执行的方法,根据具体类型执行对应子类的方法,
	 * 所以实际实现中会执行对应子类的方法
	 * @return
	 */
	public PushBeanDto genFeedPush(Content content, JPushCurriculumVO curriculumVo); 
}

具体学习任务类型实现任务基本策略接口

/**
 * 课前预习策略
 * @date 2020年3月19日
 */
 public class FeedKQYXStrategy implements FeedStrategy {
	@Override
	public PushBeanDto genFeedPush(Content content, JPushCurriculumVO curriculumVo) {
		PushBeanDto pushBean = new PushBeanDto();
		// do something for yourself star
		
		// do something for yourself end
		return pushBean;
	}
}

学习任务策略工厂类

/**
 * 学习任务策略工厂类
 * 
 * @date 2020年3月19日
 */
@Slf4j
public class FeedStrategyFoctory {
	public static FeedStrategy getStrategy(FeedTypeEnum typeEnum){
		FeedStrategy strategy = null;
		try {
			String className = FeedStrategyEnum.getClassNameById(typeEnum.getId());
			log.info("Feed Push getStrategy className={}", className);
			strategy = (FeedStrategy) Class.forName(className).newInstance();
		} catch (Exception e) {
			log.warn("生成学习任务推送信息失败, ", e);
		}
		
		return strategy;
	}
}


/**
 * 用枚举类来存放具体的学习任务类型和对应的实现策略类的绑定关系
 */
 enum FeedStrategyEnum { 
	STRATEGY_KHZY(FeedTypeEnum.NOTICE_KHZY.getId(),"com.xxx.app.strategy.feed.FeedKHZYStrategy"),
	STRATEGY_KQYX(FeedTypeEnum.NOTICE_KQYX.getId(),"com.xxx.app.strategy.feed.FeedKQYXStrategy"),;

	private String id;
    private String className;
    
	public String getId() {
		return id;
	}

	public String getClassName() {
		return className;
	}

	FeedStrategyEnum(String id, String className){
		this.id = id;
		this.className = className;
	}
	
	public static String getClassNameById(String id){
		if(StringUtils.isNotBlank(id)){
			for (FeedStrategyEnum e : FeedStrategyEnum.values()) {
				if(e.id.equals(id)){
					return e.getClassName();
				}
			}
		}
		
		return null;
	}
}

建立Facade类,并使用Spring进行管理

/**
 * 学习任务推送信息Facade, 分离推送策略生成与业务
 * 代码,实现与业务代码逻辑分离,降低耦合度,策略边和业务
 * 变化都不需要修改业务代码
 * 
 * @date 2020年3月19日
 */
@Component
public class FeedStrategyFacade {
	
	/**
	 * 执行具体的逻辑
	 * @param typeEnum
	 * @param content
	 * @param curriculumVo
	 * @return
	 */
	public PushBeanDto doGenFeedPush(FeedTypeEnum typeEnum,Content content, JPushCurriculumVO curriculumVo){
		PushBeanDto pushBean = null;
		FeedStrategy strategy = FeedStrategyFoctory.getStrategy(typeEnum);
		if(strategy != null){
			pushBean = strategy.genFeedPush(content, curriculumVo);
		} else {
			pushBean = new PushBeanDto();
		}
		
		return pushBean;
	}
}

具体调用的地方

@Autowired
private FeedStrategyFacade feedStrategyFacade;

feedStrategyFacade.doGenFeedPush(feedTypeEnum, content, curriculumVo);

你可能感兴趣的:(JAVA)