MST

星途 面试题库

面试题:Java项目里依赖倒置原则的深度理解与实践

在一个Java企业级项目中,高层模块依赖于底层模块,现在要求遵循依赖倒置原则(DIP)对代码进行重构。请描述重构思路,以及如何通过接口和抽象类来实现高层模块与底层模块之间的解耦,同时给出关键代码示例。
36.0万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

重构思路

  1. 定义抽象:识别高层模块与底层模块之间的交互点,针对这些交互定义抽象接口或抽象类。这些抽象应涵盖高层模块对底层模块的核心需求操作。
  2. 高层依赖抽象:让高层模块依赖于这些抽象,而不是直接依赖具体的底层模块实现类。这样,高层模块只需关注抽象所定义的行为,而无需关心底层模块的具体实现细节。
  3. 底层实现抽象:底层模块实现上述定义的抽象接口或继承抽象类,通过这种方式,底层模块可以自由变化其具体实现,只要保持对抽象的实现一致性,就不会影响到高层模块。

通过接口和抽象类解耦的方式

  1. 接口方式:定义接口,包含高层模块需要的方法。底层模块实现该接口,高层模块通过接口来引用底层模块实例。
  2. 抽象类方式:定义抽象类,包含高层模块需要的抽象方法。底层模块继承该抽象类并实现抽象方法。高层模块通过抽象类的引用操作底层模块实例。

关键代码示例

  1. 接口方式
    • 定义接口
public interface DatabaseAccess {
    String getData();
}
- **底层模块实现接口**:
public class MySQLDatabase implements DatabaseAccess {
    @Override
    public String getData() {
        return "Data from MySQL";
    }
}
- **高层模块依赖接口**:
public class BusinessLogic {
    private DatabaseAccess databaseAccess;

    public BusinessLogic(DatabaseAccess databaseAccess) {
        this.databaseAccess = databaseAccess;
    }

    public void processData() {
        String data = databaseAccess.getData();
        System.out.println("Processing data: " + data);
    }
}
- **测试代码**:
public class Main {
    public static void main(String[] args) {
        DatabaseAccess mySQLDatabase = new MySQLDatabase();
        BusinessLogic businessLogic = new BusinessLogic(mySQLDatabase);
        businessLogic.processData();
    }
}
  1. 抽象类方式
    • 定义抽象类
public abstract class DatabaseAccess {
    public abstract String getData();
}
- **底层模块继承抽象类**:
public class OracleDatabase extends DatabaseAccess {
    @Override
    public String getData() {
        return "Data from Oracle";
    }
}
- **高层模块依赖抽象类**:
public class BusinessLogic {
    private DatabaseAccess databaseAccess;

    public BusinessLogic(DatabaseAccess databaseAccess) {
        this.databaseAccess = databaseAccess;
    }

    public void processData() {
        String data = databaseAccess.getData();
        System.out.println("Processing data: " + data);
    }
}
- **测试代码**:
public class Main {
    public static void main(String[] args) {
        DatabaseAccess oracleDatabase = new OracleDatabase();
        BusinessLogic businessLogic = new BusinessLogic(oracleDatabase);
        businessLogic.processData();
    }
}