当前位置: 首页 > news >正文

模板方法模式(Template Method):`FormRequest` 的 `authorize()` + `rules()` 是否定义了验证的算法骨架?

Laravel 的FormRequest类确实是模板方法模式(Template Method Pattern)在 Web 请求验证场景中的精妙应用。它通过定义验证流程的算法骨架(validateResolved(),并将具体授权逻辑(authorize())和验证规则(rules()延迟到子类实现,完美体现了模板方法模式的核心思想。


一、模板方法模式的核心思想(GoF 定义)

定义一个操作中的算法骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变算法结构即可重定义该算法的某些特定步骤

  • AbstractClass(抽象类):定义模板方法(templateMethod())和抽象/钩子方法;
  • ConcreteClass(具体子类):实现抽象方法,定制算法步骤;
  • 关键算法结构由父类控制,具体步骤由子类实现

FormRequest中:

  • AbstractClass=FormRequest(本身是具体类,但扮演抽象角色);
  • Template Method=validateResolved()(定义验证骨架);
  • Primitive Operations=authorize()rules()(由子类实现)。

二、FormRequest的模板方法实现

1.算法骨架:validateResolved()

这是验证流程的“模板方法”,定义在FormRequest的父类Request中(Laravel 8+ 位于ValidatesWhenResolvedTrait):

// Illuminate\Foundation\Http\FormRequestpublicfunctionvalidateResolved(){// 1. 执行授权检查if(!$this->passesAuthorization()){$this->failedAuthorization();}// 2. 执行验证规则$validator=$this->getValidatorInstance();if($validator->fails()){$this->failedValidation($validator);}}

这就是固定的算法骨架:先授权,再验证。

2.可定制步骤:authorize()rules()

子类必须实现这两个方法:

// App\Http\Requests\UpdateUserRequestclassUpdateUserRequestextendsFormRequest{// 钩子方法 1:授权逻辑publicfunctionauthorize(){return$this->user()->can('update',$this->route('user'));}// 钩子方法 2:验证规则publicfunctionrules(){return['name'=>'required|string|max:255','email'=>'required|email|unique:users,email,'.$this->route('user'),];}}
3.执行流程(由 Laravel 内核触发)
  1. 请求进入控制器方法(如update(UpdateUserRequest $request));
  2. Laravel自动调用$request->validateResolved()
  3. validateResolved()按顺序调用:
    • $this->passesAuthorization()→ 调用子类的authorize()
    • $this->getValidatorInstance()→ 调用子类的rules()
  4. 根据结果决定是否抛出异常(403 或 422)。

🔑开发者只需关注“做什么”(authorize/rules),框架控制“怎么做”(validateResolved


三、为什么这是模板方法,而非简单继承?

特性普通继承模板方法模式
算法控制权子类完全控制父类控制流程,子类提供步骤
扩展点任意重写方法仅开放特定钩子(authorize,rules
稳定性易被子类破坏流程骨架固定,子类无法绕过授权或验证

FormRequest强制子类遵循“先授权、再验证”的安全流程,这是模板方法的核心价值。


四、与你工程理念的深度对齐

你的原则FormRequest中的体现
关注点分离授权(Policy)、验证(FormRequest)、业务(Controller)各司其职
避免重复验证骨架由框架提供,无需在每个控制器写if/validate
可维护性修改验证流程只需调整validateResolved()(框架层),业务代码不变
安全性强制先授权后验证,避免逻辑漏洞
SOLID 遵循符合开闭原则:对扩展开放(自定义authorize/rules),对修改关闭(骨架固定)

五、高级技巧:扩展模板方法

1.自定义验证后逻辑
protectedfunctionpassedValidation(){// 在验证通过后、控制器执行前运行$this->merge(['slug'=>Str::slug($this->name)]);}
2.自定义错误格式
protectedfunctionfailedValidation(Validator$validator){thrownewHttpResponseException(response()->json(['errors'=>$validator->errors()],422));}
3.复用验证规则
// 在多个 FormRequest 中复用规则traitUserValidationRules{publicfunctionrules(){return['name'=>'required','email'=>'email'];}}

模板方法提供扩展点,但不强制复杂继承


六、与其他模式的协同

  • 与策略模式协同rules()返回的规则数组可视为“验证策略”;
  • 与工厂模式协同getValidatorInstance()是验证器的工厂方法;
  • 与观察者模式协同:验证失败触发异常,可被全局异常处理器捕获。

FormRequest是多种模式的协同典范,但模板方法是其架构主干


结语

Laravel 的FormRequest是模板方法模式在现代 Web 框架中的优雅实现。它通过:

validateResolved()(模板方法) +authorize()/rules()(钩子方法)

实现了:

  • 验证流程的标准化与安全固化
  • 业务逻辑的灵活定制
  • 代码的高内聚、低耦合

正如你所坚持的:好的框架不是替你思考,而是为你提供思考的脚手架
FormRequest正是这样一个脚手架——它定义了“验证必须先授权”的铁律,却将“如何授权、验证什么”交还给开发者,这正是模板方法模式的精髓所在。

http://www.zskr.cn/news/157096.html

相关文章:

  • Hap QuickTime编解码器终极指南:3种安装方法与性能优化技巧
  • Qwen快速图像生成:三步操作法的ComfyUI工作流教程
  • leetcode 787. Cheapest Flights Within K Stops K 站中转内最便宜的航班
  • PyGMTSAR 终极指南:5步掌握卫星干涉测量核心技术
  • 2025年靠谱的风冷一体化加热器厂家最新权威实力榜 - 品牌宣传支持者
  • PaddlePaddle镜像能否用于虚拟主播驱动?技术路径清晰
  • 2025钢格板厂家推荐排行榜:产能规模与专利技术双维度权威解析 - 爱采购寻源宝典
  • edge-tts语音合成WebSocket连接403错误的完整解决方案指南
  • PaddlePaddle镜像支持模型服务降级策略,保障核心GPU业务
  • 使用CAPL编程模拟CAN节点:从零实现
  • 避免蓝屏:CP2102驱动数字签名绕过安全策略
  • OpenTracks运动追踪应用完整使用指南:隐私优先的专业运动伴侣
  • PaddlePaddle镜像如何实现训练资源配置模板化
  • 广州留学中介专业度大比拼,科学评估甄选优质服务榜单 - 留学品牌推荐官
  • Spring Modulith完整指南:用模块化思维重构大型应用架构
  • Open-AutoGLM实战入门(零基础必备手册)
  • 私人音乐服务器搭建指南:any-listen全功能解析
  • 揭秘Docker容器中的Windows系统:技术实现与实战指南
  • PaddlePaddle镜像优势详解:工业级模型库助力快速落地
  • CSS混合模式:background-blend-mode与mix-blend-mode解析
  • Python 变量类型
  • ComfyUI自定义脚本终极指南:提升AI工作流效率的必备工具
  • PaddlePaddle镜像支持模型A/B测试,科学评估GPU服务效果
  • Sci-Hub X Now学术论文访问工具完全配置手册
  • 揭秘Open-AutoGLM安装难点:5步实现零错误配置与运行
  • Julia 基本语法
  • OneDark-Pro 完整指南:打造专业级代码视觉体验
  • AI工具高效使用指南:从入门到精通的5大实用技巧
  • 无需后期配音的AI视频生成app,到底是不是伪命题?
  • 使用proteus示波器分析AT89C51晶振启动波形的详细步骤