springboot中工厂+策略模式实际应用

之前只是在各种博客和书籍上看到设计模式使用的理论知识,今天在项目中,正好遇到了这种需求,于是想着用这俩种模式实战一下,没想到成功了,记录一下,也欢迎各位大兄弟们继续给出好的建议。

需求:

有一个列表的数据,数据里有状态一栏,但是不同角色看到的状态值不一样。

原先处理方法:

对于各种新手小伙伴来说,是不是要各种if判断角色code,然后在不同的if里,去修改状态的文本值?类似于这样:

if(roleCodeConfig.getSSFAGLY().equals(roleCode)){
            reqPageVo.setStatus("展示的数据");
        }
        if(roleCodeConfig.getYWBMGLY().equals(roleCode)){
            reqPageVo.setStatus("展示的数据");
        }
        if(roleCodeConfig.getSSXJ().equals(roleCode)){
            reqPageVo.setStatus("展示的数据");
        }
        if(roleCodeConfig.getZXGLY().equals(roleCode)){
            reqPageVo.setStatus("展示的数据");
        }

当遇到代码里根据某个字段的不同值去判断走不同逻辑的时候,我们就应该要想到是不是可以用工厂+策略的设计模式去解决这个问题。逐渐摈弃掉if,else的写法,这样我们才能再每次的一点点进步中逐渐提高嘛,博主也是在外包公司里,所以代码都得自己去摸索着优化,可参考的大神代码少之又少。下面进入正式的改造流程及思路。

改造之后:

1.首先要想到不同的角色都需要改这个状态,那将改状态这个单独拎出来,成为一个接口方法,然后各种角色的实现类,去实现这个方法。如下:

public interface StatusStrategy {
    /**
     * 展示数据
     */
    List<DictValue> displayStatus();

}

2.然后有多少个角色去展示,就建多少个角色的实现类。

我这里有4个角色,所以新建了4个实现类,如图

每个实现类的代码如下:

@Component
public class BusinessAdminStrategy implements StatusStrategy {
    @Override
    public List<DictValue> displayStatus() {
        List<DictValue> dictValues = initStatus();
        //根据value过滤数据,是需要value为1,2,3的数据
        return dictValues.stream().filter(dictValue -> SysCode.TEMPSTATUS.WAIT_APPLY.equals(dictValue.getValue())
                || SysCode.TEMPSTATUS.WAIT_EVALUATE.equals(dictValue.getValue())
                || SysCode.TEMPSTATUS.EVALUATED.equals(dictValue.getValue())).collect(Collectors.toList());
    }

}
@Component
public class CarryOutAdminStrategy implements StatusStrategy {
    @Override
    public List<DictValue> displayStatus() {
        List<DictValue> dictValues = initStatus();
        //根据value过滤数据,是需要value为1,2,3的数据
        return dictValues.stream().filter(dictValue -> SysCode.TEMPSTATUS.WAIT_APPLY.equals(dictValue.getValue())
                || SysCode.TEMPSTATUS.WAIT_EVALUATE.equals(dictValue.getValue())
                || SysCode.TEMPSTATUS.EVALUATED.equals(dictValue.getValue())).collect(Collectors.toList());
    }
}

后面俩个都是类似的,就不一一列出了,在这实现类里,需要注意的也就注意下@Component这个注解,这个千万不能漏,漏完spring就找不到他的实例了。到这,策略模式应该是完成了,接下来就是把工厂模式加入进来了。

3.新建工厂类,将实现类的调用交给工厂来管理,代码如下:

@Component
public class StatusStrategyFactory {
    private final Map<String, StatusStrategy> map = Maps.newHashMap();

    @Autowired
    public StatusStrategyFactory(List<StatusStrategy> statusStrategyList) {
        for (StatusStrategy statusStrategy : statusStrategyList) {
            map.put(statusStrategy.getClass().getName(), statusStrategy);
        }
    }

    public StatusStrategy getStrategy(String strategyName) {
        return map.get(strategyName);
    }
}

解析下这个类里需要注意的地方:

1.还是@Component这个注解,这个和上面所说的内容一样。

2.map的作用,这个看代码应该能得知,就是为了将实现类做成一一映射关系,方便业务代码能通过key获取到对应的实现类。

3.@Autowird,这个注解一定要加哦,加完之后,map的键值对就会自动维护好,而不需要我们再逐一的去put操作。

到这里工厂模式+策略模式就相当于是已经搭建完成了。

4.最后在业务代码中进行调用就完事了,接下来给出具体的实例代码哈

首先,维护一个常量类(其实这里的魔法值也可以改为从配置文件或枚举类里获取,来保证所有的常量出口统一,小伙伴们可以自行去优化一下):

public class SysCode {

    public static final Map<String, String> ROLECODE_IMPL =
            new ImmutableMap.Builder<String, String>()
                    .put("leader", LeaderAdminStrategy.class.getName())
                    .put("business", BusinessAdminStrategy.class.getName())
                    .put("carryOut", CarryOutAdminStrategy.class.getName())
                    .put("center", CenterAdminStrategy.class.getName())
                    .build();
}

然后再业务代码里进行调用

到这就结束了,是不是代码一下就简洁了好多,而且也方便后期的维护,后续如果有新需求是根据不同角色来操作的话,是不是可以把方法写进策略的接口里,然后不同的角色实现类再去各自实现,就不同再写老多老多的ifelse了,即使新加了角色,我们也可以不用再改老代码,直接维护策略接口和新增新角色的实现类就行了,对吧。

结束:

        觉得有用的小伙伴点个关注和喜欢一下吧,不定时会分享一些简单有用的编码小技巧,大神绕路,勿喷~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值