目录
前情提要
策略模式
什么是策略模式
本业务场景中的几种策略
策略类2
工厂模式
什么是工厂模式
本业务场景中的工厂类
工厂与策略类能结合的关键 -->策略枚举类
SpringUtils类:(从spring中获取实例的工具类)
最终调用类
最后总结
前情提要
项目需要在后台管理动态切换查询机票或者火车票的三方服务供应商,每一个供应商就代表了不同的一套策略(不过流程是大致相似的 查询-下单或者改签 -出票).
策略模式
什么是策略模式
策略模式是一种比较简单的,也叫作政策模式.其定义如下:定义一组算法,将每个算法都封装起来,并且使它们之间可以互相转换.它使用的就是面向对象的继承和多态机制.
--摘自 设计模式之禅
本业务场景中的几种策略
策略模式是一种比较简单的,也叫作政策模式.其定义如下:定义一组算法,将每个算法都封装起来,并且使它们之间可以互相转换.它使用的就是面向对象的继承和多态机制.
--摘自 设计模式之禅
本业务场景中的几种策略
首先是策略抽象接口类
public interface IProvideStrategy {
ResultVO queryTicketList(QueryTicketParam param);
ResultVO bookoneTicket();
ResultVO changeTicket();
ResultVO issueoneTicket();
}
其次是具体的策略类 (请注意策略类都实现了刚才上面的策略抽象接口类 并且用@Component注解 交给spring管理方便后面的工厂类在spring中获取动态代理的实例)
策略类1
@Component
public class CasCcFlightStrategy implements IProvideStrategy {
@Resource
private CasCcHttpClient casCcHttpClient;
@Override
public ResultVO queryTicketList(QueryTicketParam param) {
return new ResultVO(ResultEnum.SUCCESS,"查询策略1成功");
}
@Override
public ResultVO bookoneTicket() {
return null;
}
@Override
public ResultVO changeTicket() {
return null;
}
@Override
public ResultVO issueoneTicket() {
return null;
}
}
策略类2
@Component
public class SpeedFlightStrategy implements IProvideStrategy {
@Resource
private SpeedHttpClient speedHttpClient;
@Override
public ResultVO queryTicketList(QueryTicketParam param) {
return new ResultVO(ResultEnum.SUCCESS,"策略类2查询成功");
}
@Override
public ResultVO bookoneTicket() {
return null;
}
@Override
public ResultVO changeTicket() {
return null;
}
@Override
public ResultVO issueoneTicket() {
return null;
}
}
工厂模式
什么是工厂模式
定义一个用于创建对象的接口,让子类决定实例化那一个类.工厂方法使一个类的实例化延迟到其子类.
--摘自 设计模式之禅
本业务场景中的工厂类
什么是工厂模式
定义一个用于创建对象的接口,让子类决定实例化那一个类.工厂方法使一个类的实例化延迟到其子类.
--摘自 设计模式之禅
本业务场景中的工厂类
定义一个用于创建对象的接口,让子类决定实例化那一个类.工厂方法使一个类的实例化延迟到其子类.
--摘自 设计模式之禅
注意 @Component 注解把此工厂类交给spring管理
重载方法可以决定你具体获取的策略类示例是由库里的存储关系决定 还是由前台传参直接决定
@Component
public class ProvideStrategyFactory {
@Resource
private VipProvidersMapper providersMapper;
public IProvideStrategy getProvideStrategy(Integer cId, Integer type){
List strategyCode = providersMapper.selectByConferenceIdAndType(cId,type);
if (CommonUtils.isEmpty(strategyCode) || strategyCode.size() > 1){
throw new ServiceException(ResultEnum.SYS_OPERATE_FAIL.getCode(),"服务商配置错误");
}
Class clazz = ProvideFactoryEnum.getFactory(strategyCode.get(0));
return SpringUtils.getBean(clazz);
}
public IProvideStrategy getProvideStrategy(ProvideFactoryEnum factoryEnum){
Class clazz = ProvideFactoryEnum.getFactory(factoryEnum.name());
return SpringUtils.getBean(clazz);
}
}
工厂与策略类能结合的关键 -->策略枚举类
public enum ProvideFactoryEnum {
speedFlight(SpeedFlightStrategy.class),
casCcFlight(CasCcFlightStrategy.class),
speedTrain(SpeedTrainStrategy.class);
private final Class clazz;
ProvideFactoryEnum(Class clazz) {
this.clazz = clazz;
}
public static Class getFactory(String name){
return ProvideFactoryEnum.valueOf(name).clazz;
}
}
SpringUtils类:(从spring中获取实例的工具类)
@Component
public final class SpringUtils implements BeanFactoryPostProcessor
{
private static ConfigurableListableBeanFactory beanFactory;
@Override
public void postProcessBeanFactory(@NotNull ConfigurableListableBeanFactory beanFactory) throws BeansException
{
SpringUtils.beanFactory = beanFactory;
}
@SuppressWarnings("unchecked")
public static T getBean(String name) throws BeansException
{
return (T) beanFactory.getBean(name);
}
public static T getBean(Class clz) throws BeansException
{
return beanFactory.getBean(clz);
}
public static boolean containsBean(String name)
{
return beanFactory.containsBean(name);
}
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException
{
return beanFactory.isSingleton(name);
}
public static Class> getType(String name) throws NoSuchBeanDefinitionException
{
return beanFactory.getType(name);
}
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException
{
return beanFactory.getAliases(name);
}
@SuppressWarnings("unchecked")
public static T getAopProxy(T invoker)
{
return (T) AopContext.currentProxy();
}
}
最终调用类
@Service
public class TripServiceProvideServiceImpl implements TripServiceProvideService {
@Resource
private ProvideStrategyFactory strategyFactory;
@Override
public ResultVO queryTicket(QueryTicketParam param) {
IProvideStrategy provideStrategy = strategyFactory.getProvideStrategy(param.getcId(),param.getType());
return provideStrategy.queryTicketList(param);
}
}
最后总结
@Component
public final class SpringUtils implements BeanFactoryPostProcessor
{
private static ConfigurableListableBeanFactory beanFactory;
@Override
public void postProcessBeanFactory(@NotNull ConfigurableListableBeanFactory beanFactory) throws BeansException
{
SpringUtils.beanFactory = beanFactory;
}
@SuppressWarnings("unchecked")
public static T getBean(String name) throws BeansException
{
return (T) beanFactory.getBean(name);
}
public static T getBean(Class clz) throws BeansException
{
return beanFactory.getBean(clz);
}
public static boolean containsBean(String name)
{
return beanFactory.containsBean(name);
}
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException
{
return beanFactory.isSingleton(name);
}
public static Class> getType(String name) throws NoSuchBeanDefinitionException
{
return beanFactory.getType(name);
}
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException
{
return beanFactory.getAliases(name);
}
@SuppressWarnings("unchecked")
public static T getAopProxy(T invoker)
{
return (T) AopContext.currentProxy();
}
}
最终调用类
@Service
public class TripServiceProvideServiceImpl implements TripServiceProvideService {
@Resource
private ProvideStrategyFactory strategyFactory;
@Override
public ResultVO queryTicket(QueryTicketParam param) {
IProvideStrategy provideStrategy = strategyFactory.getProvideStrategy(param.getcId(),param.getType());
return provideStrategy.queryTicketList(param);
}
}
最后总结
通过业务逻辑分析 如果需要通过多个第三方完成同样的事(大体上的流程相同,比如支付业务,动态切换服务商等等)就可以采用此策略工厂的设计模式 首先抽象出来策略接口 定义一系列你需要完成的接口 其次根据业务建立不同的策略实现类 实现自己的独立逻辑 最后通过service层就可以调用工厂类从枚举类中拿到真正的策略实例 做到策略的实时动态切换.
本文是真正把策略工厂的设计模式与spring结合在一起的 不是好多博客那种纸上谈兵,如果你有更好的办法欢迎评论区留言



