原文链接: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值,可以设置为常量。