美文网首页
策略模式的实际实现

策略模式的实际实现

作者: 帮我的鸵鸟盖个章 | 来源:发表于2020-12-07 18:00 被阅读0次

    现在有一个添加售后单的 操作,根据售后的类型分为:维修,退款,补发,换新等。

    使用策略模式,能避免使用大量的if else,不用频繁的去做判断,代码也会显得比较简洁,逻辑清晰。

    这里使用抽象类和接口结合的方法,类似于策略模式,对于该类似场景,非常适用。

    步骤如下:

    1. 定义售后类型枚举;
    2. 定义接口类,定义添加方法;
    3. 定义抽象类,实现上面的接口;
      1. 抽象类定义枚举,对应实现类serviceName
      2. 定义get()方法,根据枚举返回对应的实现类;(此处为实际实现类);
      3. 定义公共方法接口(数据检查);
    4. 根据售后类型,定义若干实现类,继承上面的抽象类;
      1. 实现抽象类的公共方法接口
      2. 实现接口定义的添加方法

    demo

    接口

    import com.aftersale.constant.AfterSaleAddTypeEnum;
    
    public interface IAddAfterSaleRegisterService {
    
        public Boolean addAfterSale(AfterSaleAddTypeEnum addTypeEnum);
    
    }
    

    抽象类

    import com.aftersale.constant.AfterSaleAddTypeEnum;
    import com.aftersale.service.IAddAfterSaleRegisterService;
    import com.common.exception.ServiceException;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    
    import java.util.*;
    
    @Slf4j
    public abstract class AbstractAddAfterSaleRegisterService implements IAddAfterSaleRegisterService {
        // 这个引入很重要
        @Autowired
        private Map<String, AbstractAddAfterSaleRegisterService> map;
    
        /**
         * 枚举: 增加类型-服务名称
         */
        private enum AddTypeServiceName {
            /**
             * 维修
             */
            REPAIR(AfterSaleAddTypeEnum.REPAIR, "addRepairService"),
            /**
             * 补发
             */
            REISSUE(AfterSaleAddTypeEnum.REPAIR, "addReissueService"),
    
            ;
            public AfterSaleAddTypeEnum addTypeEnum;
            public String serviceName;
    
            private AddTypeServiceName(AfterSaleAddTypeEnum addTypeEnum, String serviceName) {
                this.addTypeEnum = addTypeEnum;
                this.serviceName = serviceName;
            }
    
            public static AddTypeServiceName with(AfterSaleAddTypeEnum addTypeEnum) {
                if (null == addTypeEnum) {
                    return null;
                }
                for (AddTypeServiceName m : AddTypeServiceName.values()) {
                    if (m.addTypeEnum.equals(addTypeEnum)) {
                        return m;
                    }
                }
                return null;
            }
        }
    
        private AbstractAddAfterSaleRegisterService getService(AfterSaleAddTypeEnum addTypeEnum) {
            AddTypeServiceName serviceNameEnum = AddTypeServiceName.with(addTypeEnum);
            if (null == serviceNameEnum) {
                log.error(String.format("不支持的售后登记添加类型[%s]", addTypeEnum.getCode()));
                throw ServiceException.build(String.format("不支持的售后登记添加类型[%s]", addTypeEnum.getCode()));
            }
            AbstractAddAfterSaleRegisterService service = this.map.get(serviceNameEnum.serviceName);
            if (null == service) {
                log.error(String.format("不支持的服务[%s]", serviceNameEnum.serviceName));
                throw ServiceException.build(String.format("不支持的服务[%s]", serviceNameEnum.serviceName));
            }
            return service;
        }
    
        /**
         * 登记前数据检查
         * @param addTypeEnum
         * @return
         */
        public abstract Boolean checkBeforeAdd(AfterSaleAddTypeEnum addTypeEnum);
    
        /**
         * 添加
         * @param addTypeEnum
         * @return
         */
        public abstract Boolean add(AfterSaleAddTypeEnum addTypeEnum);
    
        @Override
        public Boolean addAfterSale(AfterSaleAddTypeEnum addTypeEnum) {
            Boolean checkResult = this.getService(addTypeEnum).checkBeforeAdd(addTypeEnum);
            if (checkResult){
                return this.getService(addTypeEnum).add(addTypeEnum);
            }
            return true;
        }
    
    }
    

    实现类

    @Primary默认实现

    这个默认实现,是写了一个实际售后的类型之外的情况,默认抛出错误。

    结合抽象类的。由于有多个类都实现了接口,spring不知道注入哪一个,所以@primary的作用就是告诉spring,优先考虑注入哪一个。

     @Autowired
        private Map<String, AbstractAddAfterSaleRegisterService> map;
    

    使用。这个地方需要自己理解哦~

    import com.aftersale.constant.AfterSaleAddTypeEnum;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.context.annotation.Primary;
    import org.springframework.stereotype.Service;
    
    @Service("deafultRepairService")
    @Primary
    @Slf4j
    public class DefaultRepairServiceImpl extends AbstractAddAfterSaleRegisterService {
    
        @Override
        public Boolean checkBeforeAdd(AfterSaleAddTypeEnum addTypeEnum) {
            log.error("无法识别的售后登记类型");
            return false;
        }
    
        @Override
        public Boolean add(AfterSaleAddTypeEnum addTypeEnum) {
            log.error("无法识别的售后登记类型");
            return false;
        }
    
    }
    
    

    具体实现1

    import com.aftersale.constant.AfterSaleAddTypeEnum;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Service;
    
    
    @Service("addReissueService")
    @Slf4j
    public class AddReissueServiceImpl extends AbstractAddAfterSaleRegisterService {
    
        @Override
        public Boolean checkBeforeAdd(AfterSaleAddTypeEnum addTypeEnum) {
            log.info("xxx");
            return true;
        }
    
        @Override
        public Boolean add(AfterSaleAddTypeEnum addTypeEnum) {
            log.info("xxx");
            return true;
        }
    
    }
    

    具体实现2

    import com.aftersale.constant.AfterSaleAddTypeEnum;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Service;
    
    @Service("addRepairService")
    @Slf4j
    public class AddRepairServiceImpl extends AbstractAddAfterSaleRegisterService {
    
        @Override
        public Boolean checkBeforeAdd(AfterSaleAddTypeEnum addTypeEnum) {
            log.info("xxx");
            return true;
        }
    
        @Override
        public Boolean add(AfterSaleAddTypeEnum addTypeEnum) {
            log.info("xxx");
            return true;
        }
    
    }
    

    具体使用时,只需要正常的注入接口即可。

    相关文章

      网友评论

          本文标题:策略模式的实际实现

          本文链接:https://www.haomeiwen.com/subject/hsptgktx.html