news 2026/7/14 16:58:11

模板方法模式(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/7/7 15:17:05

10分钟精通ABSA-PyTorch:基于方面的情感分析实战指南

10分钟精通ABSA-PyTorch:基于方面的情感分析实战指南 【免费下载链接】ABSA-PyTorch Aspect Based Sentiment Analysis, PyTorch Implementations. 基于方面的情感分析,使用PyTorch实现。 项目地址: https://gitcode.com/gh_mirrors/ab/ABSA-PyTorch …

作者头像 李华
网站建设 2026/7/11 17:51:39

SoundCloud音乐获取新体验:打造专属音频收藏库

想要轻松获取SoundCloud上的音乐资源吗?这款音频工具让你在几分钟内掌握专业级的音乐下载技巧!无需复杂配置,一键获取完整音频文件并自动整理标签信息,为你的音乐收藏带来革命性体验。🎵 【免费下载链接】scdl Soundcl…

作者头像 李华
网站建设 2026/7/13 3:32:37

18、组件、类层次结构与税务引擎实现

组件、类层次结构与税务引擎实现 1. 接口与实现的概念 在生活中,以餐厅为例,我们去餐厅用餐,关注的是服务员能完成接单、上菜等任务,而不关心服务员具体是谁,也不在意服务员当天心情好坏或者其他个人情况。即使服务员换成机器人,只要能完成相应任务,我们也不会在意 。…

作者头像 李华
网站建设 2026/7/7 15:17:49

19、组件与类层次结构:税收引擎实现解析

组件与类层次结构:税收引擎实现解析 1. 基础税收计算与额外税判定 调用基类可以计算出基本的应纳税额。为了确定是否需要征收额外税,我们会用到受保护的数据成员 _calculatedTaxable 。在调用 BaseTaxEngine.CalculateTaxToPay() 后, _calculatedTaxable 会被赋值,…

作者头像 李华
网站建设 2026/7/6 21:24:47

24、深入了解列表、委托和 Lambda 表达式

深入了解列表、委托和 Lambda 表达式 在编程过程中,管理多个对象实例的代码十分常见。此前的示例中,常使用数组来管理多个对象实例。现在我们将介绍 .NET 集合类,它为管理对象实例集提供了便捷的方式,可将集合对象想象成一个能添加、遍历和检索内容的无限大袋子。 集合管…

作者头像 李华