
在 laravel 中,重复的 crud 控制器逻辑(如 store 方法)应通过抽象基类、依赖注入与泛型请求处理来消除冗余,而非简单复制代码;同时需兼顾模型特异性、验证请求隔离与响应一致性。
遵循 DRY(Don’t Repeat Yourself)原则在 Laravel 控制器中不仅是最佳实践,更是可维护性与扩展性的关键。你提供的多个控制器中 store 方法高度相似——仅模型类名和对应 Form Request 不同——这正是抽象的理想场景。但直接使用 new First() 赋值给 $this->model 并调用 ::create() 存在设计缺陷(如无法支持静态代理、丢失类型提示、违反依赖注入原则),因此我们需要更健壮、Laravel 原生友好的方案。
✅ 推荐方案:泛型资源控制器 + 依赖注入 + 策略化请求解析
1. 创建抽象基控制器(带类型约束)
requestClass())->validated();
$model = app($this->modelClass())::create($validated);
return response()->json(['message' => 'Successfully created'], 201);
}
}⚠️ 注意:此处不直接注入 Request 实例,而是动态解析具体 Form Request(如 FirstRequest),确保验证逻辑完全解耦且可复用。
2. 在子控制器中声明模型与请求类(无需构造函数赋值)
3. (可选)统一响应封装提升一致性
为避免重复 response()->json(...),可进一步封装响应:
json(['message' => $message], $code); } }然后在 ResourceController@store 中调用:
return ApiResourceResponse::success('Successfully created');✅ 优势总结
- 零重复逻辑:所有 store 行为收敛至一个方法;
- 强类型安全:modelClass() 和 requestClass() 返回 string,IDE 可识别,路由绑定与测试友好;
- 符合 Laravel 惯例:不破坏服务容器自动解析、中间件、策略授权等机制;
- 可扩展性强:后续添加 update, destroy 等方法时,同样可复用该模式;
- 请求隔离保障:每个控制器仍使用专属 Form Request,验证规则、权限逻辑完全独立。
❌ 不推荐的做法提醒
- 避免在基类中用 new $this->model —— 会绕过容器、丢失单例/绑定、无法 mock 测试;
- 避免将 Request $request 直接作为参数传入基类方法 —— 无法触发 Laravel 的自动 Form Request 解析(即跳过验证);
- 不要为“省几行代码”而牺牲可读性与调试性:抽象应清晰表达意图(如 modelClass() 比 $this->model 更语义化)。
通过以上结构,你不仅实现了 DRY,更构建了一套可持续演进的 API 控制层架构。










