第14章 Web表现模式

分离请求处理、导航、模型和HTML生成的不同变化轴。

学习目标

  • 能区分 MVC、Page Controller、Front Controller、Application Controller 与三种视图变换的职责
  • 能用 TypeScript 把订单请求映射为可测试的 View Model,并隔离导航与模板输出
  • 能根据路由共享、跨页面流程、视图变体和模板安全要求选择 Web 表示模式

为什么第14章 Web表现模式值得单独学习

第14章 Web表现模式的核心不是把框架目录换成另一套类名,而是把请求处理、导航、模型调用与 HTML 生成拆成不同的变化轴。订单后台可能同时有列表、详情、审批和导出;如果控制器既保存流程状态又拼 HTML,模板又直接访问数据库,一次路由或字段变化就会穿过整个应用。

是请求变化与业务变化之间的隔离层。本页以 2024 年中文版公开目录限定第14章的范围,并依据 Martin Fowler 的作者图书页和模式目录独立重写;目录只决定要讲什么,案例、实验、判断题和答案均为本课程原创。

先建立直觉:问题、机制与代价

适合把局部变化留在局部。

减少共享基础设施重复,但不能因此吞掉所有页面逻辑。

则拥有流程导航,不拥有每个页面的展示细节。

适合稳定页面结构;Transform View 把模型转换为另一种输出,Two Step View 把内容与全局布局分成两步。选择要由路由共享、流程状态、视图变体和转义安全的证据推动,而不是由框架默认值推动。

对第14章 Web表现模式,优先比较的替代路线是:页面边界局部时采用 Page Controller,认证和错误处理共享时采用 Front Controller,跨页面流程复杂时采用 Application Controller,输出格式变化时采用 Template View、Transform View 或 Two Step View。若实验只能显示一页 HTML,不能说明导航、输入校验和模板安全,就不能据此选择模式。

目录单元到教学证据

第14章 Web表现模式

第14章 Web表现模式要求把“HTTP 请求如何变成安全且可导航的响应”变成可观察的架构决定:先标出路由、控制器、应用模型、视图与导航状态的所有者,再用订单后台多视图的路由测试、流程测试和输出快照验证决定。只有模板替换不会重写业务和导航,表示模式才真正隔离了变化。

专属代码案例:订单审批后台

把订单审批后台切成“HTTP 请求 → Front/Page Controller → 应用流程 → View Model → Template/Transform View”五个观察点。第14章 Web表现模式的设计草案必须写出谁拥有状态、谁作出业务决定、失败怎样传播,以及路由、输入校验、导航、模板转义和视图复用中哪个指标最先提示当前方案不再适用。

设计记录采用五个可换行字段:单元键为 poeaa24-chapter-14-web-presentation-patterns;模式族为 web;裁决是“共享基础设施集中,页面输入局部,跨页状态独立,视图只消费已转义的 View Model”;观测项包括路由、输入校验、导航、模板转义、视图复用;拒绝条件是“模板直接查询数据库或控制器同时持有流程、业务规则和 HTML 字符串”。

先预测:订单审批从“详情”进入“确认”再进入“完成”,哪些状态属于 Application Controller,哪些内容属于 View?先写下导航、模型和模板边界,再阅读实现;验证时要能说明同一审批结果如何转换为 HTML 与 CSV,而不会重复权限和金额规则。

type ApprovalRequest = {
  userId: string;
  orderId: string;
  action: "approve" | "reject";
};
 
type ApprovalViewModel = {
  heading: string;
  nextPath: string;
  notice: string;
};
 
interface ApprovalApplication {
  approve(
    userId: string,
    orderId: string,
  ): "approved" | "forbidden" | "missing";
  reject(userId: string, orderId: string): "rejected" | "forbidden" | "missing";
}
 
class ApprovalPageController {
  constructor(private readonly application: ApprovalApplication) {}
 
  handle(request: ApprovalRequest): ApprovalViewModel {
    const result =
      request.action === "approve"
        ? this.application.approve(request.userId, request.orderId)
        : this.application.reject(request.userId, request.orderId);
 
    if (result === "forbidden") {
      return {
        heading: "Not allowed",
        nextPath: "/orders",
        notice: "权限不足",
      };
    }
    if (result === "missing") {
      return {
        heading: "Order not found",
        nextPath: "/orders",
        notice: "订单不存在",
      };
    }
    return {
      heading: "Approval updated",
      nextPath: `/orders/${request.orderId}`,
      notice: result === "approved" ? "订单已批准" : "订单已拒绝",
    };
  }
}

这段代码让 Page Controller 负责输入和响应模型,让应用层负责审批规则,让视图只消费 ApprovalViewModel。真实 Front Controller 可以在更外层统一认证、路由和错误记录;Template View 或 Transform View 再把同一 View Model 输出成 HTML 或 CSV,不能把用户输入直接拼入 HTML。

Web 表示模式职责矩阵

控制器组解决请求路由和流程控制,视图组解决模型到输出的转换,MVC 负责把 Model、View、Controller 的职责放在可替换边界上。下面的矩阵覆盖七种模式及其核心职责。

Web 表示模式:职责分配控制器(请求 → 逻辑)视图(逻辑 → 输出)MVC分离 M/V/C 职责Page Controller每页一个处理器Front Controller单一入口分发Template View模板 + 占位符Transform View模型 → 视图转换Two Step View内容 + 布局分离App Controller跨页面流程控制选择视图请求流:HTTP → Front/Page Controller → MVC 分发 → 视图渲染 → HTTP 响应控制器决定做什么,视图决定怎么展示——两者通过 Model 解耦
Web 表示模式族包含 7 个模式。控制器组(MVC、Page/Front Controller、Application Controller) 负责请求路由和流程控制;视图组(Template/Transform/Two Step View)负责渲染输出。

矩阵不是“每个项目都要用七个模式”的清单;它用于记录变化轴,帮助团队拒绝不必要的共享入口、隐式导航和模板业务逻辑。

Web 流程选择图

先看共享认证、路由和错误处理,再看是否存在跨页面流程,最后看是否存在多个输出格式。每次集中化都要给出减少重复或保护状态的证据;没有证据时保持 Page Controller 和简单 Template View。

Web 流程:先分路由,再分流程与输出页面输入局部Page Controller路由 + 校验页面失败局部可测共享基础设施Front Controller认证 + 错误 + 路由不承载页面业务跨页或多输出Application ControllerTemplate / TransformView Model + 布局拒绝条件:模板查库、客户端决定流程、入口吞掉全部页面业务MVC 解耦职责,控制器与应用流程仍需保持清晰所有权
Web 模式选择由共享程度、流程状态和输出变化推动,集中化必须有可测试的收益。

选择与拒绝矩阵

评审问题选择 Web 表示模式的证据应拒绝当前方案的信号
路由页面与共享入口的边界可测试一个巨型入口包含所有页面业务分支
流程Application Controller 明确拥有跨页状态控制器或模板用隐式变量猜测下一步
输出View Model 可被 HTML、CSV 或布局复用每个模板复制金额、权限和状态规则
安全输入校验、转义和错误路径有专门测试用户输入直接进入 HTML 或 SQL

常见误区

可验证练习

练习

本组练习覆盖第14章 Web表现模式,并要求把路由、输入校验、导航、模板转义和视图复用映射到订单后台多视图。

问题 1:选择入口。 多个页面共享认证、错误处理和路由,但每个页面的业务用例不同,应该如何拆分?

问题 2:处理跨页流程。 订单审批需要详情、确认和完成三个步骤,下一步不能由客户端任意跳过,状态应由谁拥有?

问题 3:复用输出。 同一审批结果需要 HTML 页面和 CSV 下载,如何避免视图复制规则?

名词解释

名词解释

本章出现的专业名词,用大白话再讲一遍。

Page Controller

为单个页面或用例提供输入处理、模型调用和响应选择的局部控制器。

Front Controller

为多个请求提供统一入口,集中认证、路由、错误处理和通用上下文的控制器。

Application Controller

封装跨页面导航和应用流程状态的协调对象,不拥有每个页面的展示细节。

Template View

使用模板占位符把模型数据生成输出的视图组件,不直接访问数据库或改变领域状态。

本章小结

掌握第14章 Web表现模式的标志不是记住七个模式名称,而是能在订单审批后台中解释“HTTP 请求 → 控制器 → 应用流程 → View Model → Template/Transform View”的责任链。学习者应利用路由、输入校验、导航、模板转义和视图复用作出可证伪的选择,并在巨型入口、模板业务逻辑或客户端控制流程时明确拒绝当前实现。

前后导航

来源与改写范围

资料与写作方式声明

本章以Martin Fowler《企业应用架构模式》与公开模式目录权威目录界定学习范围,并结合正文列出的技术资料独立重写;不宣称复现原书正文,也不沿用原作表述。

原作版权归作者与出版社所有;本站原创教学结构与表述仅供学习交流。

讨论

评论区加载中…