You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

读取含Employee子类信息的多行文件,现有代码求优化方案

优化员工数据加载代码的实用建议

看起来你已经搞定了基础的员工数据读取和泛型集合存储功能,但肯定是觉得当前的实现可能有点臃肿(比如一堆条件判断创建子类对象),想让代码更优雅、易维护对吧?结合你的场景——Employee父类下有三个子类,从文件读取每行不同格式的数据并实例化对应的对象——我给你几个实际项目里常用的优化思路:

1. 用工厂模式封装对象创建逻辑,让加载方法更清爽

把判断员工类型、创建对应子类对象的逻辑抽离到一个专门的工厂类里,这样loadData方法只需要专注于读取文件和调用工厂,代码结构更清晰,以后加新的员工类型也不用大改加载方法。

举个例子:

// 专门负责创建员工对象的工厂类
public class EmployeeFactory {
    public static Employee createEmployee(String[] dataParts) {
        // 假设每行数据的第4个字段是员工类型标识(比如HOURLY/SALARY/COMMISSION)
        String empType = dataParts[3];
        
        switch(empType) {
            case "HOURLY":
                return new Hourly(dataParts[0], dataParts[1], dataParts[2], 
                    Double.parseDouble(dataParts[4]), Double.parseDouble(dataParts[5]));
            case "SALARY":
                return new Salary(dataParts[0], dataParts[1], dataParts[2], 
                    Double.parseDouble(dataParts[4]));
            case "COMMISSION":
                return new Commission(dataParts[0], dataParts[1], dataParts[2], 
                    Double.parseDouble(dataParts[4]), Double.parseDouble(dataParts[5]));
            default:
                throw new IllegalArgumentException("不认识的员工类型: " + empType);
        }
    }
}

// 优化后的loadData方法
public void loadData(File inFile) throws IOException {
    // 用try-with-resources自动关闭Scanner,避免忘记关资源导致泄漏
    try (Scanner in = new Scanner(inFile)) {
        List<Employee> employees = new ArrayList<>();
        
        while (in.hasNextLine()) {
            String line = in.nextLine().trim();
            if (line.isEmpty()) continue; // 跳过空行
            
            // 假设数据用逗号分隔,拆分每行成字段数组
            String[] dataParts = line.split(",");
            Employee emp = EmployeeFactory.createEmployee(dataParts);
            employees.add(emp);
        }
    }
}

这里用try-with-resources是个小细节,比手动写finally关闭Scanner更安全省心。

2. 让每个子类自己负责解析数据,解耦更彻底

可以给每个Employee子类加一个静态的工厂方法,让子类自己处理数据解析和对象创建,工厂类只需要调用对应子类的方法就行。这样每个类只管好自己的事,符合单一职责原则。

比如Hourly子类可以这么写:

public class Hourly extends Employee {
    // 父类继承来的构造方法
    public Hourly(String name, String empNum, String dept, double hourlyRate, double hoursWorked) {
        super(name, empNum, dept);
        // 初始化子类自己的字段
    }

    // 静态方法:从数据数组创建Hourly对象
    public static Hourly fromData(String[] dataParts) {
        return new Hourly(dataParts[0], dataParts[1], dataParts[2], 
            Double.parseDouble(dataParts[4]), Double.parseDouble(dataParts[5]));
    }
}

然后工厂类就可以简化成:

public class EmployeeFactory {
    public static Employee createEmployee(String[] dataParts) {
        String empType = dataParts[3];
        
        return switch(empType) {
            case "HOURLY" -> Hourly.fromData(dataParts);
            case "SALARY" -> Salary.fromData(dataParts);
            case "COMMISSION" -> Commission.fromData(dataParts);
            default -> throw new IllegalArgumentException("不认识的员工类型: " + empType);
        };
    }
}

以后新增员工类型,只需要加对应的子类和在工厂里加一行case就行,改动很小。

3. 用映射表替代冗长的switch/case(进阶优化)

如果以后员工类型越来越多,一堆switch/case会显得很乱,这时候可以用一个Map来存储“类型标识”和对应的创建逻辑,代码会更简洁,扩展性也更好:

public class EmployeeFactory {
    // 提前把所有员工类型的创建逻辑存在Map里
    private static final Map<String, Function<String[], Employee>> EMPLOYEE_CREATORS = Map.of(
        "HOURLY", Hourly::fromData,
        "SALARY", Salary::fromData,
        "COMMISSION", Commission::fromData
    );

    public static Employee createEmployee(String[] dataParts) {
        String empType = dataParts[3];
        // 从Map里拿对应的创建函数
        Function<String[], Employee> creator = EMPLOYEE_CREATORS.get(empType);
        
        if (creator == null) {
            throw new IllegalArgumentException("不认识的员工类型: " + empType);
        }
        
        return creator.apply(dataParts);
    }
}

以后加新类型,只需要在Map里加一组键值对就行,完全不用修改createEmployee的逻辑,完美符合开闭原则。

几个额外的小建议

  • 异常处理:解析数值的时候(比如parseDouble)容易抛出NumberFormatException,建议在工厂方法里捕获或者包装成自定义异常,方便上层处理错误数据。
  • 数据验证:创建对象前先检查一下数据是否完整(比如字段数量够不够、数值是否合法),别创建出无效的员工对象。
  • 面向接口编程:尽量用List<Employee>而不是ArrayList<Employee>来声明集合,以后想换成其他List实现(比如LinkedList)也不用改代码。

内容的提问来源于stack exchange,提问作者Shah Bari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:17:05