代码优雅之路-如何优雅的去除冗杂的if-else语句

java的优雅就在于设计模式

每天各种谈论设计模式,可是在日常写代码中,仍然是crud boy,那么我们如何使用设计模式运用在日常工作中呢。

本文使用策略工厂模式进行去除冗杂的if-else语句,让工作中的代码看起来更加优雅。

先叙述场景,在监控告警系统中,往往需要通过多种通道向告警成员发送警报,例如:企业微信告警,手机短信告警,邮箱告警,语音告警等多种告警方式。
那么我们最初的做法是什么呢?

 public interface AlertWayService {

    void call(String recevier,Alert alert, String title);

}

定义一个发送告警的接口,然后通过判断是那种告警方式,选择调用哪个service实现类。
代码如下:

String alertWay = null;
        if("weChat".equals(alertWay)){
            //调用微信接口实现类发送微信
        }else if ("sms".equals(alertWay)){
            //短信
        }else if("email".equals(alertWay)){
            //邮箱
        }else if("voice".equals(alertWay)){
            //语音
        }

这样的代码仿佛结构清晰,一眼看懂,但是其弊端也非常明显

1.代码拓展性不强,如果要加入一个新的通道方式,极其不方便。
2.大量的if-else语句使得代码阅读难度较高。
3.代码逻辑性不强。
4.在code-review环节容易被喷。

那么我们如何优雅的通过设计模式解决这种冗杂代码呢?

这里我们使用策略工厂模式进行解决。

先上代码

public class AlertServiceStrategyFactory {
    private static Map<String, AlertWayService> services = Maps.newConcurrentMap();

    public static AlertWayService getAlertWay(String alertWay) {
        return services.get(alertWay);
    }

    public static void register(String alertWay, AlertWayService alertWayService) {
        if (Assert.StringAssert.isNotEmpty(alertWay)) {
            services.put(alertWay, alertWayService);
        }
    }
}

这里我们使用策略工厂进行注册通道和通道接口。

通过Map进行存储通道字段和通道接口,并进行绑定。

通道接口还是那个接口

public interface AlertWayService {

    void call(String recevier,Alert alert, String title);

}

关键在实现类中。

@Service
@Slf4j
public class EmailAlertWayServiceImpl implements AlertWayService, InitializingBean {

    @Autowired
    private InnerNoticeClient innerNoticeClient;

    @Override
    public void call(String recevier,Alert alert, String title) {
        innerNoticeClient.callEmile(recevier, WeChatTemplate.getEmileTmpl(alert,title),alert.getStatus());
    }

    @Override
    public void afterPropertiesSet() {
        AlertServiceStrategyFactory.register(NotificationTypeEnums.EMAIL.getValue(),this);
    }
}

service实现类中实现了InitializingBean接口,并在afterpropertiesSet中进行注册绑定通道和通道接口,通过register让AlertServiceStrategyFactory中的services这个map初始化了四种通道方式。

InitializingBean接口的详细使用可以参考其他优秀的博客。

当我们完成了这一系列的定义后,那么我们如何使用呢?

 alertWay.forEach((k1) -> AlertServiceStrategyFactory.getAlertWay(k1).call(v,alert, titleOfTreeInfo));

这里通过遍历alertWay的方式进行获取通道,调用AlertServiceStrategyFactory中的getAlertWay方法 通过alertWay中定义的通道形式,有策略的进行调用相应的通道接口,实现了优雅的使用策略工厂模式进行有效的去除if-else。

end

优雅的代码往往只需要几行…

你可能感兴趣的:(代码优雅之路)