怎么减少if语句

本文介绍了如何优化含有大量if语句的代码,包括提前return避免else、使用三目运算符、switch case、枚举、表驱动法结合策略模式、以及策略模式与工厂模式的组合应用。通过这些方法,可以提高代码的可读性和可维护性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文链接:https://blog.csdn.net/qq_33591903/article/details/105240966

怎么减少if语句

项目初期,代码比较简单,脉络清晰。可随着bug或者新需求的出现,状态变得越来越多,只能不停的加else来区分,久而久之,判断的次数越来越多,嵌套的层数也越来越深,变得难以维护。

那么有什么方法可以优化if else 结构呢?

1.提前return,减少else判断

优化前:

private int handlePre1(boolean flag) {
    if (flag) {
        //do something
    } else {
        //do something
        return -1;
    }
    return 0;
}

优化后:

private int handlePre1(boolean flag) {
    if(!flag){
		//do something
        return -1;
    }
    //do something
    return 0;
}

使用三目运算符

优化前:

private int handlePre2(boolean flag) {
    if (flag) {
        return 0;
    } else {
        return 1;
    }
}

优化后:

private int handlePre2(boolean flag) {
    return flag?0:1;
}

第三种方法:使用switch case

优化前:

private String getCn(String en) {
    String cn;
    if ("student".equals(en)) {
        cn = "学生";
    } else if ("teacher".equals(en)) {
        cn = "教师";
    } else {
        cn = "未知";
    }
    return cn;
}

优化后:

private String getCn(String en) {
    String cn;
    switch(en) {
        case "student":
            return "学生";
        case "teacher":
            return "教师";
        default:
            return "未知";
    }
}

第四种方法:使用枚举

如果上一例中的student、teacher是常量的话,最好是定义在枚举里。

public enum CnEnum {

    STUDENT("student", "学生"),
    TEACHER("teacher", "教师"),
    UNKNOWN("unKnown", "未知");

    private String en;
    private String cn;

    public String getEn() {
        return en;
    }

    public String getCn() {
        return cn;
    }

    CnEnum(String en, String cn) {
        this.en = en;
        this.cn = cn;
    }

    static String of(String en) {
        for (CnEnum temp : CnEnum.values()) {
            if (temp.getEn().equals(en)) {
                return temp.getCn();
            }
        }
        return CnEnum.valueOf("UNKNOWN").getCn();
    }
}

第五种方法:表驱动法+策略模式

表驱动法是指我们可以将信息存在于表中,从表中取,而不必用if else逻辑去寻找,大可以将这里的“表”理解为一种容器。

例如我们可以将每月的天数存在数组中,需要时,直接从数组中获取,而不是用if else输出。

或者依据不同的字符串,执行不同的处理逻辑。if else版本如下:

    String profession = "student";
    if ("student".equals(profession)) {
       //do something
    } else if ("teacher".equals(profession)) {
        //do something
    } else if ("programmer".equals(profession)) {
        //do something
    }

在这种情况下,使用表驱动法后,可以让Student、Teacher等类实现某一个共同的接口,在实现方法里,书写各自的逻辑。然后利用Spring强大的自动注入,会注入到Map<组件名称,组件实例>的map里,之后直接根据组件名称来获取到对应的实例,最后调用各自的逻辑

先定义一个接口

public interface UserService {

    //返回用户的主要任务
    String task();

}

两个实现类

@Service("student")
public class StudentServiceImpl implements UserService {
    @Override
    public String task() {
        return "学习";
    }
}
@Service("teacher")
public class TeacherServiceImpl implements UserService {
    @Override
    public String task() {
        return "教书";
    }
}

实现动态调用的核心类

@Service
public class UserContext {

    @Autowired
    Map<String, UserService> userMap;
     
    public UserService getUserService(String type) {
        return userMap.get(type);
    }

}
Spring会自动地将形如(@Service后面的名称,实现该接口的类)注入到该userMap中

在启动后,userMap中就存在两个元素,(“student”,StudentServiceImpl)与(“teacher”,TeacherServiceImpl)

getUserService方法返回userMap中key=type的UserService对象

实体类

public class User {

    private String type;
     
    private String task;
     
    public String getType() {
        return type;
    }
     
    public void setType(String type) {
        this.type = type;
    }
     
    public String getTask() {
        return task;
    }
     
    public void setTask(String task) {
        this.task = task;
    }

}

Controller层接口

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    UserContext userContext;
     
    @PostMapping("/getTask")
    public String getTask(@RequestBody User user) {
        UserService userService = userContext.getUserService(user.getType());
        return userService.task();
    }

}

第七种方法:策略模式+工厂模式

首现给定以下的一个场景,传入一个职业,输出职业的主要工作

一般我们会这么写:

    String profession = "student";
    if ("student".equals(profession)) {
        System.out.println("学习");
    } else if ("teacher".equals(profession)) {
        System.out.println("教书");
    } else if ("programmer".equals(profession)) {
        System.out.println("写代码");
    }
    //.......以后可能会加上各种各样的职业

每增加一个职业都会多一个ifelse判断,代码可读性差,日后难以维护。

现在使用策略模式+工厂模式来改造它。

  • 首先定义一个职业接口,里面定义一个输出职责的方法
  • 之后每增加一种职业,都实现职业接口,实现输出职责的方法(策略模式)
  • 接着定义一个工厂类,用来根据具体情况生产各种职业类(工厂模式)

职业接口:

public interface Profession {

//输出职责
void output();

}
实现类:

public class Student implements Profession {

    @Override
    public void output() {
        System.out.println("学习");
    }

}


public class Teacher implements Profession {

    @Override
    public void output() {
        System.out.println("教书");
    }

}


public class Programmer implements Profession {

    @Override
    public void output() {
        System.out.println("写代码");
    }

}

工厂类:

public class ProfessionFactory {

    private static Map<String, Profession> map = new HashMap<>();
    //未知职业
    private static final Profession DEFAULT_PROFESSION = new DefaultProfession();
     
    static {
        map.put("student", new Student());
        map.put("teacher", new Teacher());
        map.put("default", DEFAULT_PROFESSION);
    }
     
    public static Profession getProfession(String s) {
        Profession profession = map.get(s);
        return profession == null ? DEFAULT_PROFESSION : profession;
    }
     
    static class DefaultProfession implements Profession {
     
        @Override
        public void output() {
            System.out.println("职责未知");
        }
     
    }

}

优化后:

Profession profession = ProfessionFactory.getProfession("student");
profession.output();

之后每增加一种职业,只要实现Profession接口就好,并在ProfessionFactory中注册自己。使用策略模式+工厂模式,再也不需要为日益增长的if else头疼了。

当然,这里的key值,可以设置为常量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值