MST

星途 面试题库

面试题:Java接口与抽象类在框架中的应用 - 高级难度

假设你正在开发一个可扩展性强的日志框架,描述如何合理地运用Java接口和抽象类来设计其核心架构,以满足不同日志输出格式(如文本、JSON)和存储方式(如文件、数据库)的需求,同时要考虑框架的可维护性和可测试性。
50.4万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
  1. 定义日志输出格式接口
    • 定义一个LogFormat接口,该接口包含一个方法用于将日志信息转换为特定格式。
    public interface LogFormat {
        String format(String message);
    }
    
    • 实现具体的日志输出格式类,如文本格式和JSON格式。
      • 文本格式
      public class TextLogFormat implements LogFormat {
          @Override
          public String format(String message) {
              return message;
          }
      }
      
      • JSON格式
      import com.google.gson.Gson;
      
      public class JsonLogFormat implements LogFormat {
          private Gson gson = new Gson();
          @Override
          public String format(String message) {
              return gson.toJson(new {message = message});
          }
      }
      
  2. 定义日志存储方式接口
    • 定义一个LogStorage接口,该接口包含一个方法用于存储日志信息。
    public interface LogStorage {
        void store(String formattedMessage);
    }
    
    • 实现具体的日志存储方式类,如文件存储和数据库存储。
      • 文件存储
      import java.io.FileWriter;
      import java.io.IOException;
      
      public class FileLogStorage implements LogStorage {
          private String filePath;
          public FileLogStorage(String filePath) {
              this.filePath = filePath;
          }
          @Override
          public void store(String formattedMessage) {
              try (FileWriter writer = new FileWriter(filePath, true)) {
                  writer.write(formattedMessage + "\n");
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
      
      • 数据库存储
      import java.sql.Connection;
      import java.sql.DriverManager;
      import java.sql.PreparedStatement;
      import java.sql.SQLException;
      
      public class DatabaseLogStorage implements LogStorage {
          private String jdbcUrl;
          private String username;
          private String password;
          public DatabaseLogStorage(String jdbcUrl, String username, String password) {
              this.jdbcUrl = jdbcUrl;
              this.username = username;
              this.password = password;
          }
          @Override
          public void store(String formattedMessage) {
              String insertQuery = "INSERT INTO logs (message) VALUES (?)";
              try (Connection connection = DriverManager.getConnection(jdbcUrl, username, password);
                   PreparedStatement statement = connection.prepareStatement(insertQuery)) {
                  statement.setString(1, formattedMessage);
                  statement.executeUpdate();
              } catch (SQLException e) {
                  e.printStackTrace();
              }
          }
      }
      
  3. 定义抽象日志记录器类
    • 创建一个抽象类AbstractLogger,它依赖于LogFormatLogStorage接口。
    public abstract class AbstractLogger {
        protected LogFormat logFormat;
        protected LogStorage logStorage;
        public AbstractLogger(LogFormat logFormat, LogStorage logStorage) {
            this.logFormat = logFormat;
            this.logStorage = logStorage;
        }
        public void log(String message) {
            String formattedMessage = logFormat.format(message);
            logStorage.store(formattedMessage);
        }
    }
    
  4. 可维护性
    • 通过接口和抽象类的使用,将日志框架的不同功能模块进行解耦。例如,添加新的日志输出格式或存储方式时,只需实现相应的接口,而不需要修改其他模块的代码。
    • 代码结构清晰,每个接口和类都有明确的职责,便于理解和维护。
  5. 可测试性
    • 对于具体的日志输出格式类和存储方式类,可以编写单元测试来验证其功能。例如,对于TextLogFormat类,可以测试format方法是否返回正确的文本格式。
    • 对于AbstractLogger类,可以通过依赖注入不同的LogFormatLogStorage实现类,来测试日志记录的功能。例如,使用Mockito等测试框架来模拟LogFormatLogStorage的行为,从而测试AbstractLoggerlog方法。