优化大量 if else 的 Java 代码

在编写 Java 代码时,经常会遇到大量的 if else 语句,这会导致代码可读性差、维护困难等问题。本文将介绍如何优化这样的代码,并提供一个具体的示例。

问题描述

假设我们有一个简单的图书管理系统,包含以下几个实体类:Book、User 和 Library。其中,Library 类负责管理图书,User 类代表图书的借阅者,Book 类代表图书本身。在该系统中,我们需要根据用户类型和借阅期限来计算用户借阅图书的费用。

当前的代码实现如下所示:

public class Library {
    public double calculateRent(User user, Book book) {
        double rent = 0;

        if (user.getType().equals("student")) {
            if (user.getRentDays() < 7) {
                rent = 1.0;
            } else {
                rent = 2.0;
            }
        } else if (user.getType().equals("teacher")) {
            if (user.getRentDays() < 14) {
                rent = 1.5;
            } else {
                rent = 3.0;
            }
        } else {
            rent = 4.0;
        }

        return rent;
    }
}

上述代码中使用了大量的嵌套 if else 语句,这样的实现方式存在以下问题:

  1. 可读性差:嵌套的 if else 语句使得代码难以理解和维护。
  2. 可扩展性差:当新增用户类型或者修改计费规则时,需要修改大量的代码。
  3. 可测试性差:由于代码逻辑过于复杂,测试覆盖率较低。

为了解决这些问题,我们可以采用策略模式来优化代码。

优化方案

策略模式(Strategy Pattern)是一种行为设计模式,它定义了一系列的算法,并将每个算法封装成具有共同接口的单独类。在本例中,我们可以将不同用户类型的计费规则抽象成不同的策略类。

首先,我们定义一个 RentStrategy 接口,用于表示用户的计费策略:

public interface RentStrategy {
    double calculateRent(User user);
}

然后,我们实现三个具体的计费策略类:StudentRentStrategy、TeacherRentStrategy 和 DefaultRentStrategy。

public class StudentRentStrategy implements RentStrategy {
    @Override
    public double calculateRent(User user) {
        if (user.getRentDays() < 7) {
            return 1.0;
        } else {
            return 2.0;
        }
    }
}

public class TeacherRentStrategy implements RentStrategy {
    @Override
    public double calculateRent(User user) {
        if (user.getRentDays() < 14) {
            return 1.5;
        } else {
            return 3.0;
        }
    }
}

public class DefaultRentStrategy implements RentStrategy {
    @Override
    public double calculateRent(User user) {
        return 4.0;
    }
}

接下来,我们修改 Library 类的实现:

public class Library {
    private RentStrategy rentStrategy;

    public void setRentStrategy(RentStrategy rentStrategy) {
        this.rentStrategy = rentStrategy;
    }

    public double calculateRent(User user) {
        return rentStrategy.calculateRent(user);
    }
}

最后,我们可以使用如下方式调用 Library 类:

public class Main {
    public static void main(String[] args) {
        Library library = new Library();

        User student = new User("student", 5); // 学生用户,借阅期限为 5 天
        library.setRentStrategy(new StudentRentStrategy());
        double studentRent = library.calculateRent(student);
        System.out.println("Student Rent: " + studentRent);

        User teacher = new User("teacher", 10); // 教师用户,借阅期限为 10 天
        library.setRentStrategy(new TeacherRentStrategy());
        double teacherRent = library.calculateRent(teacher);
        System.out.println("Teacher Rent: " + teacherRent);

        User otherUser = new User("other", 15); // 其他用户,借阅期限为 15 天
        library.setRentStrategy(new DefaultRentStrategy());
        double otherUserRent = library.calculateRent(otherUser);
        System