news 2026/5/1 7:58:34

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
模板方法模式(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正是这样一个脚手架——它定义了“验证必须先授权”的铁律,却将“如何授权、验证什么”交还给开发者,这正是模板方法模式的精髓所在。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/4 1:38:05

完全指南:3步轻松搭建AI金融交易框架实现智能投资分析

想要快速体验AI驱动的智能投资分析吗?这份部署指南将帮助您用最简单的方式搭建TradingAgents-CN这个强大的AI金融交易框架。无论您是技术新手还是普通用户,都能通过本教程轻松上手,开启智能投资之旅。 【免费下载链接】TradingAgents-CN 基于…

作者头像 李华
网站建设 2026/4/27 19:29:21

安卓文本编辑神器:Turbo Editor完全使用手册

安卓文本编辑神器:Turbo Editor完全使用手册 【免费下载链接】turbo-editor Simple and powerful File Editor for Android. All is licensed under the GPLv3 license. 项目地址: https://gitcode.com/gh_mirrors/tu/turbo-editor 还在为手机上的文本编辑而…

作者头像 李华
网站建设 2026/4/30 5:15:51

38、多线程与关系型数据库数据学习

多线程与关系型数据库数据学习 1. 多线程相关知识 1.1 读写锁 读写锁能使读写事件有序进行,确保共享状态始终一致。不过,它无法阻止死锁,若代码编写不当,死锁仍可能发生。读写锁主要关注用于管理数据的代码。 1.2 生产者/消费者架构 1.2.1 架构概念 生产者/消费者技术…

作者头像 李华
网站建设 2026/4/17 22:07:14

ModbusRTU报文详解:多从机通信策略解析

ModbusRTU报文详解:多从机通信策略解析从一个工业现场的通信故障说起上周,某工厂自动化系统频繁出现数据采集中断的问题。排查发现,主控PLC轮询到第8个传感器时经常超时,而其他设备正常。现场工程师反复检查接线、电源和地址设置&…

作者头像 李华