首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java Web MVC 設計模式演進與三層架構最佳實踐

     編輯:Java 相關知識

從 Servlet/JSP 到 MVC 的演進歷程

階段 1:Servlet 獨攬大權

// 在 Java 代碼中拼接 HTML - 維護噩夢
out.println("");
out.println("

用戶列表

"); out.println("...
"); out.println("");

缺點:視圖邏輯與業務邏輯耦合,前後端協作困難,修改頁面需重新編譯 Java 類。

階段 2:JSP 內嵌 Java 代碼

<%-- 頁面中混雜大量 Java 邏輯 --%>
<% 
    List<User> users = userDao.findAll();
    for (User u : users) {
%>
    <tr><td><%= u.getName() %></td></tr>
<% } %>

缺點:JSP 變成「大雜燴」,職責不清,難以複用與測試。

階段 3:JSP + JavaBean 分離

將數據封裝為 JavaBean,JSP 僅負責顯示。但控制邏輯(請求分發、參數處理)仍分散在各 JSP 中。

階段 4:Servlet + JSP + JavaBean(Model 1 / Model 2)

  • Servlet 作為 Controller:接收請求、調用 Service、選擇視圖
  • JavaBean 作為 Model:封裝數據與業務邏輯
  • JSP 作為 View:純粹渲染展示

這是經典的 MVC Model 2 架構,也是後續 Struts、Spring MVC 等框架的基石。

經典三層架構詳細設計

┌─────────────────────────────────────┐
│           Presentation Layer        │  ← JSP / Thymeleaf / Vue/React
│   (Controller: Servlet / @Controller)│
├─────────────────────────────────────┤
│            Service Layer            │  ← @Service 業務邏輯、事務控制
│   (Business Logic & Transaction)    │
├─────────────────────────────────────┤
│              DAO Layer              │  ← @Repository / Mapper 數據訪問
│   (CRUD & ORM: MyBatis/JPA)         │
├─────────────────────────────────────┤
│              Database               │
└─────────────────────────────────────┘

各層職責與規範

層級核心職責關鍵規範典型技術
Controller 請求接收、參數校驗、調用 Service、視圖跳轉/JSON 返回 不含業務邏輯、不直接操作 DB、薄控制器 Spring MVC @RestController
Service 核心業務流程、事務管理(@Transactional)、異常處理、聚合多 DAO 接口隔離實現、領域模型驅動、無視圖依賴 Spring @Service + @Transactional
DAO/Mapper 單表/多表 CRUD、複雜查詢、結果映射 面向接口編程、SQL 與代碼分離、無業務邏輯 MyBatis Mapper / Spring Data JPA
Entity/DTO/VO 數據載體:Entity 對應表、DTO 服務層傳輸、VO 視圖層展示 Getter/Setter、無參構造、序列化、校驗註解 Lombok @Data / Record (Java 16+)

JavaBean 規範回顧

  1. 實現 Serializable 接口
  2. 提供 無參構造器
  3. 屬性 private 封裝
  4. 標準 getXxx/setXxx 方法(布爾型可用 isXxx)
  5. 無業務邏輯,純數據容器

現代化最佳實踐建議

1. 分層解耦:面向接口編程

// Service 接口
public interface UserService {
    UserDTO getById(Long id);
    PageResult<UserDTO> query(UserQuery query);
}

// Controller 僅依賴接口
@RestController
@RequestMapping("/users")
public class UserController {
    private final UserService userService; // 構造器注入
    
    @GetMapping("/{id}")
    public Result<UserDTO> get(@PathVariable Long id) {
        return Result.success(userService.getById(id));
    }
}

2. 數據傳輸對象分離(DTO/VO/Entity 隔離)

  • Entity:映射資料表,僅在 DAO 層流轉
  • DTO:Service 與 Controller 間傳輸,包含業務所需字段
  • VO:Controller 返回前端,可能包含格式化、掩碼等展示邏輯
  • 使用 MapStruct 或手動轉換器避免層間對象污染

3. 統一異常處理與響應規範

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(BizException.class)
    public Result<Void> handleBiz(BizException e) {
        return Result.fail(e.getCode(), e.getMessage());
    }
}

4. 事務邊界清晰:只在 Service 層開啟

Controller、DAO 層 禁止 使用 @Transactional。事務應圍繞完整業務用例,而非單條 SQL。

總結

MVC 與三層架構不僅是代碼組織形式,更是關注點分離的工程實踐。從早期的 Servlet/JSP 到現代 Spring Boot + 前後端分離,核心思想始終未變:控制器調度、服務封裝業務、數據層專注持久化。遵循分層規範、接口隔離、對象分離,才能構建可維護、可測試、可擴展的企業級應用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved