美文网首页程序员基础知识
[代码结构设计]根据不同条件使用不同实现类的业务代码设计

[代码结构设计]根据不同条件使用不同实现类的业务代码设计

作者: 东西的南北 | 来源:发表于2018-10-21 21:38 被阅读11次

场景

此时有一个场景,需要设计一个根据不同的状态和条件采用不同的业务处理方式。

这样大家可能不是太理解。举个例子,现在大街小巷上的商户都采用了聚合支付的支付方式,聚合支付也就是商户柜台前放了一个支持支付宝、微信、京东钱包、银联等等的二维码,用户可以通过任意一款支付APP进行支付。

解决思路

思路①

对每个支付渠道进行定义枚举类型

public enum PayWay {
    ALI_PAY,

    WECHAT_PAY;
}

然后在每个对应的service上定义注解,表示对应哪种支付方式

@Pay(PayWay.ALI_PAY)
public class AliPayServiceImpl implements PayService  {}

但是仔细思考后,还是存在一些问题

  1. 如果增加一个支付方式后还需要修改,PayWay这个枚举类型
  2. 在程序中,仍需要根据不同的条件做if else判断PayWay,增加支付方式还是得修改原有的判断逻辑。伪代码如下
if("xxx" == "aliPay"){
    
} else if("xxx" == "wechatPay"){
    
}
//如果增加支付方式还是得增加else if

思路②

在思路①中存在一些问题,首当其冲的就是if else判断问题。先思考一下这个if else的作用是什么?

答:根据思路①描述,这个if else是用来确定采用哪种支付方式。

我们可以将这块代码抽离出来,让对应的业务实现类实现自己的逻辑实现,然后根据返回值true 或者false决定是否过滤掉这个业务实现类。接口定义如下,SupportBean是封装的一个实体

boolean isSupport(SupportBean supportBean);

然后在各个业务实现类都实现自己的isSupport方法,伪代码如下

@Override
public boolean isSupport(SupportBean supportBean) {
    if (supportBean.getType() == "xxx"){
        return true;
    }
    
    return false;
}

设计

注:只提供一个架子

接口定义

Service接口定义,一个业务执行方法execute(参数自行添加),一个isSupport方法(返回true或者false

public interface Service {

    void execute();

    boolean isSupport(SupportBean supportBean);
}

业务实现类

这里execute方法只是在控制台打印字符串。isSupport方法对SupportBean中的supportNum进行取余,判断余数是否等于0,是则返回true。

类似的实现还有两个,这里就不贴出来了。

@Component
public class AServiceImpl implements Service {
    @Override
    public void execute() {
        System.out.println("A execute");
    }

    @Override
    public boolean isSupport(SupportBean supportBean) {
        return supportBean.getSupportNum() % 3 == 0;
    }
}

接下来在定义一个帮助类

帮助类

@Component
public class Helper {

    @Autowired
    private List<Service> services;

    public void execute(SupportBean supportBean){

        Service s = services.stream()
                .filter((service) -> service.isSupport(supportBean))
                .findFirst()//NPE异常
                .orElse(null);


        if (s != null){
            s.execute();
        }
    }
}

通过工具类的execute方法来获取对应的业务实现类执行的结果,以及对传入的参数进行校验处理等。

需要注意的是Lambda表达式的findFirst()会出现NullPointException异常。因为filter对list进行过滤,会存在过滤完list的长度为0,如果此时在调用findFirst则会抛出NullPointException。可以将上面的代码修改为如下代码,这样就可以避免NPE了

Service s = services.stream()
        .filter((service) -> service.isSupport(supportBean))
        .map(Optional::ofNullable)
        .findFirst()
        .flatMap(Function.identity())
        .orElse(null);

测试

添加一个springboot测试类和一个测试方法。

在contextLoads测试中调用帮助类Helper的execute方法

@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {

    @Autowired
    private Helper Helper;

    @Test
    public void contextLoads() {
        Helper.execute(new SupportBean(3));
    }

}

测试结果

A execute

扩展

在Lambda表达式中是先将业务实现类进行过滤,然后获取第一个业务实现类并执行。

如果此时过滤存在多个业务实现类,而又不能确定优先级,这时需要如何进行扩展呢?

其实很简单,先在Service接口中定义一个getPriority方法

int getPriority();

然后各自的实现类实现对应的getPriority方法

接着修改Lambda表达式即可,在filter后增加sorted方法即可对业务实现类进行排序

Service s = services.stream()
        .filter((service) -> service.isSupport(supportBean))
        .sorted(Comparator.comparing(Service::getPriority))
        .map(Optional::ofNullable)
        .findFirst()
        .flatMap(Function.identity())
        .orElse(null);

总结

整个大体框架基本都搭建完成,如需扩展只需要增加对应的业务实现类,而不用去修改其他类的代码。就连之前设计的枚举都可以不用,可扩展性大大提升。如需使用,只需修改对应的入参和对应的名称即可。
Github地址
如果对你有收获,欢迎star、欢迎fork
如果你也有类似的经验,欢迎加入,一起共建

相关文章

  • [代码结构设计]根据不同条件使用不同实现类的业务代码设计

    场景 此时有一个场景,需要设计一个根据不同的状态和条件采用不同的业务处理方式。 这样大家可能不是太理解。举个例子,...

  • Day11

    一. 设计模型之模板模型 定义使用接口制定规则,然后子类根据实现不同的方法内部代码实现类暴露的可用方法必须和接口中...

  • 3.php流程控制

    条件控制语句 条件控制语句是根据条件选择执行不同的代码片段。条件控制语句分为四类:1)if 语句 -- 在条件...

  • HTML--模板代码实现

    1.业务场景 有时候我们希望一段代码动态变化的,根据不同的条件显示不同的内容或者样式。这时候我们需要模板代码来帮我...

  • 流程控制-分支结构

    顺序结构: 由上而下的执行代码 分支结构:在由上而下的执行代码过程中,根据不同的条件执行不同的代码 常见分支结构:...

  • 面对复杂业务,if-else coder 如何升级?

    简介: 针对业务在不同场景下的差异,我们常常会习惯性地使用 if-else 来实现不同的业务逻辑,久而久之代码越来...

  • spring常用注解-@Conditional条件注册bean

    @Conditional可以根据代码中设置的条件装载不同的bean,比如说当一个接口有两个实现类时,我们要把这个接...

  • Python 3的编程基础

    条件语句 条件语句是一种根据条件执行不同代码的语句,如果条件满足则执行一段代码,否则执行其他代码。Python中条...

  • 从0到1学习网络安全 【PHP基础-If...Else】

    PHP If...Else 语句 条件语句用于根据不同条件执行不同动作。 PHP 条件语句 在您编写代码时,经常会...

  • lo.PHP if条件语句 switch语句

    if...else语句 条件语句用于根据不同条件执行不同动作。当您编写代码时,您常常需要为不同的判断执行不同的动作...

网友评论

    本文标题:[代码结构设计]根据不同条件使用不同实现类的业务代码设计

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