java设计模式之:策略模式+工厂模式整合案例实战(一)

avatar
作者
筋斗云
阅读量:2

本文介绍项目中常用的策略模式+工厂模式的案例,该案例是针对策略类比较少的情况下一篇会讲解策略类比较多的案例,下面直接开始:

案例1:项目中对系统中的客户和销售进行事件通知(短信、邮件、钉钉)

首先要有通知的策略接口,接口里面要有一个方法就是通知的方法

public interface PushChannelStrategy{    // 通知方法    SendResult send(MessagePushParam param,BaseMsg baseMsg);  }

有了接口那必然有实现类,三个实现类短信、邮件、钉钉

短信:

@Slf4j @Component public class SmsPushChannelStrategy implements PushChannelStrategy{    @Autowired    private NoticeClient noticeClient;        @Override    public SendResult send(MessagePushParam param,BaseMsg baseMsg){        //1、before send check        //2、send sms        NoticeResult noticeResult=noticeClient.sendSms(xxxx);        sendResult.setMessageStatus(MessageStatusEnum.SUCCESS);        return sendResult;    } }

邮件:

@Slf4j @Component public class EmailPushChannelStrategy implements PushChannelStrategy{    @Autowired    private NoticeClient noticeClient;        @Override    public SendResult send(MessagePushParam param,BaseMsg baseMsg){        //1、before send check        //2、send email        Email emailMsg=(Email)baseMsg;        NoticeResult noticeResult=noticeClient.sendEmail(xxxx);        sendResult.setMessageStatus(MessageStatusEnum.SUCCESS);        return sendResult;    } }

钉钉:

@Slf4j @Component public class DingTalkPushChannelStrategy implements PushChannelStrategy{    @Autowired    private DingTalkClient dingTalkClient;        @Override    public SendResult send(MessagePushParam param,BaseMsg baseMsg){        //1、before send check        //2、send ding talk        SendResult sendResult=dingTalkClient.send(xxx);        // 其他结果参数组装        return sendResult;    } }

然后通过策略工厂来获取具体的策略类:(由于只有三个策略类,所以通过注入的方式对channel进行判断)

@Component public class PushChannelStrategyFactory{     @Autowired      private DingTalkPushChannelStrategy dingTalkPushChannelStrategy;     @Autowired     private SmsPushChannelStrategy smsPushChannelStrategy;     @Autowired     private EmailPushChannelStrategy emailPushChannelStrategy;          public PushChannelStrategy getStrategy(PushChannel pushChannel){         switch(pushChannel){            case DING_TALK:               return dingTalkPushChannelStrategy;            case SMS:               return smsPushChannelStrategy;            case EMAIL:               return emailPushChannelStrategy;            default:               throw new RuntimeException("不支持的类型");            }      } }

当然策略工厂针对策略实现类比较少的情况还可以这样写:

@Component public class PushChannelStrategyFactory2{     @Autowired     private DingTalkPushChannelStrategy dingTalkPushChannelStrategy;     @Autowired     private SmsPushChannelStrategy smsPushChannelStrategy;     @Autowired     private EmailPushChannelStrategy emailPushChannelStrategy;          private static final Map<PushChannel,PushChannelStrategy> pushChannelBuilderMap=new HashMap<>();          @PostConstruct     public void init(){         pushChannelBuilderMap.put(PushChannel.SMS,smsPushChannelStrategy);         pushChannelBuilderMap.put(PushChannel.Email,emailPushChannelStrategy);         pushChannelBuilderMap.put(PushChannel.DING_TALK,dingTalkPushChannelStrategy);       }     Public PushChannelStrategy getStrategy(PushChannel PushChannel){       if(PushChannel==null){           return null;        }        return pushChannelBuilderMap.get(PushChannel);     } }        

用到的枚举类:

@Getter public enum PushChannel{    SMS("sms","短信"),    EMAIL("email","邮件"),    DING_TALK("dingTalk","钉钉");        private final String value;        PushChannel(String value,String desc){       this.value=value;     }     public static PushChannel getPushChannel(String pushChannel){       if(pushChannel==null){          return null;       }       for(PushChannel channel:PushChannel.values()){         if(pushChannel.equals(channel.getValue())){            return channel;        }    }     return null;   } }    

在使用的时候通过策略工厂里面的方法获取具体的策略类:

@Slf4j @Service  public class MessagePushService{      @Autowired      private PushChannelStrategyFactory pushChannelStrategyFactory;      @Autowired      private MessageRecordRepository messageRecordRepository;            public ResultDTO<Boolean> pushSync(MessagePushCommand command){         MessagePushParam messagePushParam =MessagePushAssembler.convert(command);         //1,业务逻辑处理         //2、根据渠道进行触达         PushChannel pushChannel=messagePushParam.getChannel();         if(pushChannel==null){           throw new MessagePushException(xxx);         }         //3、获取具体的策略类         PushChannelStrategy pushChannelStrategy=pushChannelStrategyFactory.getStrategy(pushChannel);         SendResult sendResult=PushChannelStrategy.send(messagePushParam,xxx);         //4,记录落库         return ResultDTO.getSuccessResult(true);     }  }

到此该版本的策略模式+工厂模式就结束了,欢迎点评和指出不足之处。

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!