MST

星途 面试题库

面试题:Java项目中违反单一职责原则的影响及重构

在一个Java Web项目中,发现某个Servlet类既负责处理用户登录请求,又负责处理订单创建请求,还承担了部分日志记录的功能。请分析这种设计违反单一职责原则可能带来的问题,并阐述如何对该Servlet类进行重构以遵循单一职责原则。
38.0万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

违反单一职责原则带来的问题

  1. 可维护性差:当需要修改用户登录逻辑时,可能会不小心影响到订单创建或日志记录功能,因为它们都集中在同一个类中,牵一发而动全身。
  2. 可扩展性低:如果要新增一种请求处理逻辑,比如处理商品查询请求,将不得不修改这个已经很臃肿的类,增加了代码修改的风险。
  3. 复用性差:处理用户登录、订单创建和日志记录的代码紧密耦合在一起,无法单独复用其中某一个功能模块。

重构方法

  1. 拆分Servlet功能
    • 用户登录Servlet:创建一个新的LoginServlet类,专门处理用户登录请求的逻辑,如验证用户名和密码,生成登录令牌等。示例代码如下:
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 处理用户登录逻辑
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        // 验证逻辑
        if ("admin".equals(username) && "123456".equals(password)) {
            response.getWriter().println("登录成功");
        } else {
            response.getWriter().println("登录失败");
        }
    }
}
- **订单创建Servlet**:创建`OrderCreateServlet`类,负责处理订单创建的请求,包括接收订单信息,调用业务逻辑进行订单保存等。示例代码如下:
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/createOrder")
public class OrderCreateServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 处理订单创建逻辑
        String orderInfo = request.getParameter("orderInfo");
        // 调用业务逻辑保存订单
        response.getWriter().println("订单创建成功,订单信息:" + orderInfo);
    }
}
- **日志记录类**:创建一个独立的日志记录类`LoggerUtil`,提供静态方法来记录日志。示例代码如下:
public class LoggerUtil {
    public static void log(String message) {
        System.out.println("[LOG] " + message);
    }
}
  1. 在Servlet中调用日志记录:在LoginServletOrderCreateServlet中,当需要记录日志时,调用LoggerUtil的方法。例如在LoginServlet中:
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 处理用户登录逻辑
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        // 验证逻辑
        if ("admin".equals(username) && "123456".equals(password)) {
            LoggerUtil.log("用户 " + username + " 登录成功");
            response.getWriter().println("登录成功");
        } else {
            LoggerUtil.log("用户 " + username + " 登录失败");
            response.getWriter().println("登录失败");
        }
    }
}

通过这样的重构,每个类都只负责单一的职责,提高了代码的可维护性、可扩展性和复用性。