设计模式-工厂模式优化

  在项目的应用里,有很多功能都是通过前端传过来的key,去判断走哪一个处理类。一开始的时候是一个简单工厂模式的变型,用if..else的判断来做处理的分发,根据参数得到对应的类之后,直接执行了对应的方法。所以严格的说,这是简单工厂模式加策略模式。

 个人理解:

 (1)简单工厂模式是把创建对象的权利交给了工厂,由工厂根据传入的参数来返回用户需要的对象。然后用户拿到对象再去自己执行方法。

(2)策略模式则是由用户来负责创建对象,然后把对象传给策略类,由策略类来执行对应的方法,返回参数。

  例如下面这种代码:

 @Component

public class testFactory {

    @Resource

    private Handle1 handle1;

    @Resource

    private Handle2 handle2;

    ...

    public ResultDTO getParameter(String key, String value, ContextDTO contextDto, Object response) {

        ResultDTO resultDTO = null;

        if (StringUtils.isBlank(key) || StringUtils.isBlank(value)) {

            resultDTO = ResultDTO.fail("key,value格式非法");

        } else if ("key1".equals(key)) {

            resultDTO = handle1.generate(contextDto, response);

        } else if ("key2".equals(key)) {

            resultDTO = handle2.generate(contextDto, response);

        }

        ...

        }else {

            resultDTO = ResultDTO.fail("key: " + key + "不合法,未找到此上下文值");

        }

        return resultDTO;

    }

}

    为了引用端的方便,直接在工厂类里面注入所需要的bean,并且根据传入的参数,选择使用哪一种bean的genearte方法并执行。一开始的服务不多的时候,这样写影响不大。但是后期这种处理类越来越多,代码变得很冗长,并且单纯的if..else的添加逻辑是违背“开闭原则”,对扩展开放,对修改关闭。所以后期想办法对这块做了优化。

  1.首先是给每一个handle处理类都加了一个getKey()的方法

   (1)接口定义增加方法

 public interface HandleService {

    String generate(ContextDTO contextDto, Object response);

    /**

     * 返回handle方法对应的key

     * @return

     */

    String getKey();

}

(2)每个handle方法增加getKey方法

 @Service

public class Handle1 implements HandleService {

    private static final Logger log = LoggerFactory.getLogger(Handle1.class);

    @Override

    public String generate(ContextDTO ContextDto, Object response){

        System.out.println("执行generate方法");

    }

    @Override

    public String getGenerateKey(){

        return GenerateKeyEnum.KEY1.getGenerateKey();

    }

}

(3)key用枚举类或者常量来收口。这样方便维护和理解。

public enum GenerateKeyEnum {

    KEY1("key1","key1"),

    KEY2("key2","key2");

    private String generateKey;

    private String generateVal;

    GenerateKeyEnum(String generateKey,String generateVal){

        this.generateKey = generateKey;

        this.generateVal = generateVal;

    }

    public static GenerateKeyEnum getEnumByName(String generateKey,String generateVal){

        for (GenerateKeyEnum generateKeyEnum : GenerateKeyEnum.values()) {

            if (generateKeyEnum.getGenerateKey().equals(generateKey) && generateKeyEnum.getGenerateVal().equals(generateVal)) {

                return generateKeyEnum;

            }

        }

        return null;

    }

    public String getGenerateVal() {

        return generateVal;

    }

    public String getGenerateKey() {

        return generateKey;

    }

    public void setGenerateKey(String generateKey) {

        this.generateKey = generateKey;

    }

    public void setGenerateVal(String generateVal) {

        this.generateVal = generateVal;

    }

}

2.然后是对工厂类的修改:

 @Component

public class StrategyFactory {

    private static final Map<String, HandleService> handleServiceMap = new HashMap<>();

    @Resource

    private Set< HandleService > handleServiceSet;

    @PostConstruct

    private void init() {

        if (handleServiceSet != null) {

            handleServiceSet.forEach(handleService ->

                handleServiceMap.put(handleService.getKey(), handleService)

            );

        }

    }

    public HandleService getHandleService(String key) {

        return handleServiceMap.get(key);

    }

    public ResultDTO getParameter(String key, String value, ContextDTO contextDto, Object response) {    

        if (StringUtils.isBlank(key) || StringUtils.isBlank(value)) {

            return ServiceResultDTO.fail("key,value格式非法");

        } else {

            HandleService handleService = getHandleService(key);

            if (handleService == null) {

                return ResultDTO.fail("key: " + key + "不合法,未找到bean");

            }

            return handleService.generate(contextDto, response);

        }

    }

}

  在这里,直接用注解的方式把所有的service全部注入到set集合中,然后将set中的内容放到map里面,方便获取。因为类初始化后,开始注入bean,而注解的顺序@Autowired > @PostConstruct > @PreDestroy,从而可以保证map中有值。

 1.每当需要加一个处理类的时候,只需要新增处理类,并且在枚举类中维护一个key即可,不要修改工厂类,代码变的更加简洁,易于维护。

 2.灵活的组合各种设计模式和运用注解,可以让项目的代码更清晰。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值