告別義大利麵!Laravel 10 架構重構的 2026 年視野
嗨,你的 Laravel 10 專案是否被「胖 Controller」和技術債拖垮了?資深工程師 Eric 將帶你回歸本質,運用 Form Request、服務層(Service Layer)與 DTOs 等分層架構黃金法則,徹底解決義大利麵程式碼的困境。這些現代化重構策略,能確保你的 LTS 專案易於維護與擴展。別讓混亂的架構阻礙業務發展,立即聯繫我們,讓您的專案升級為可維護的數位資產!
嗨,我是 Eric,浪花科技的資深工程師。雖然現在已經是 2026 年,Laravel 13 的謠言滿天飛,新的 AI Agent 開發工具也層出不窮,但讓我猜猜——你手邊肯定還有好幾個正在運行的 Laravel 10 專案,對吧?
別擔心,這很正常。在企業級開發中,「穩定」往往比「追新」更重要。Laravel 10 作為一個長期支援(LTS)的重要版本,至今仍是許多中大型系統的核心基石。然而,隨著業務邏輯像藤蔓一樣瘋狂生長,兩三年前寫下的優雅程式碼,現在是不是已經變成了讓人看了就想嘆氣的「義大利麵程式碼」(Spaghetti Code)?
Controller 肥大到捲不到底、Model 裡塞滿了與資料庫無關的邏輯、Validation 散落在各個角落……如果你點頭如搗蒜,那這篇文章就是為你準備的。今天,我們不談那些花俏的新工具,而是回歸本質,以 2026 年的資深工程師視角,重新審視 Laravel 10 專案架構最佳實務,教你如何透過重構(Refactoring)與設計模式,把手中的技術債變成可維護的數位資產。
為什麼你的 Laravel 專案會變成「大泥球」?
在討論「怎麼做」之前,我們先來聊聊「為什麼」。Laravel 框架以「開發者體驗(DX)」著稱,它的靈活性是雙面刃。MVC(Model-View-Controller)是 Laravel 的基礎,但很多開發者(包括年輕時的我)容易陷入一個誤區:把所有東西都塞進 Controller。
看看下面這段典型的「胖 Controller」程式碼,是不是很眼熟?
// 這是災難的開始
public function store(Request $request)
{
// 1. 驗證邏輯混雜
$request->validate([
'title' => 'required|max:255',
'body' => 'required',
]);
// 2. 商業邏輯直接寫死
if ($request->user()->is_vip) {
$price = $request->price * 0.8;
} else {
$price = $request->price;
}
// 3. 資料庫操作與第三方服務混在一起
$post = Post::create([
'title' => $request->title,
'price' => $price,
'user_id' => auth()->id(),
]);
// 4. 發送通知(還可能卡住請求)
Mail::to($post->user)->send(new PostCreated($post));
return response()->json($post);
}
這段程式碼雖然能跑,但它違反了軟體工程中最重要的單一職責原則(Single Responsibility Principle, SRP)。Controller 應該只負責「接收請求」和「回傳回應」,中間的「怎麼做」不該由它操心。
Laravel 10 架構優化黃金法則
在 2026 年,我們維護 Laravel 10 專案時,通常會引入更分層的架構(Layered Architecture)。這不是過度設計,而是為了讓你在半年後回來修改需求時,不會想穿越時空揍自己一頓。
1. 嚴格執行 Form Request Validation
第一步最簡單,把驗證邏輯從 Controller 抽離。Laravel 的 Form Request 是被嚴重低估的功能。它不僅能驗證資料,還能處理授權(Authorization)。
// app/Http/Requests/StorePostRequest.php
public function rules(): array
{
return [
'title' => ['required', 'string', 'max:255'],
'body' => ['required', 'string'],
'price' => ['required', 'numeric', 'min:0'],
];
}
// 在 Controller 中使用
public function store(StorePostRequest $request)
{
// 程式碼執行到這裡時,資料已經是乾淨的了
$validated = $request->validated();
// ...
}
這樣做的好處是,你的 Controller 不再充斥著 `required` 或 `email` 這種驗證規則,閱讀起來更加清爽。
2. 導入 Service Layer(服務層)處理商業邏輯
這是將專案從「玩具」升級為「企業級」的關鍵。Service Layer 是用來封裝具體商業邏輯的地方。無論是計算折扣、生成報表,還是複雜的資料庫交易,都應該放在這裡。
Controller 只需要呼叫 Service,它不需要知道「VIP 折扣是怎麼算的」,它只需要知道「要算折扣」。
// app/Services/PostService.php
class PostService
{
public function createPost(User $user, array $data): Post
{
$price = $this->calculatePrice($user, $data['price']);
return DB::transaction(function () use ($data, $price, $user) {
$post = Post::create([
...$data,
'price' => $price,
'user_id' => $user->id,
]);
// 發送通知的邏輯也可以封裝出去,或者在這裡觸發 Event
event(new PostCreated($post));
return $post;
});
}
private function calculatePrice(User $user, float $price): float
{
return $user->is_vip ? $price * 0.8 : $price;
}
}
3. 使用 DTOs (Data Transfer Objects) 傳遞資料
在 Laravel 10 (PHP 8.2+) 的環境下,我們應該善用 PHP 的型別系統。與其在 Service 和 Controller 之間傳遞模糊不清的 `array`,不如使用 DTO。這在 2026 年已經是標準配備。
Array 是不可靠的,你永遠不知道 `$data[‘user_id’]` 是不是真的存在。DTO 讓你的資料結構一目了然。
// app/DTOs/PostData.php
readonly class PostData
{
public function __construct(
public string $title,
public string $body,
public float $price,
) {}
public static function fromRequest(Request $request): self
{
return new self(
title: $request->validated('title'),
body: $request->validated('body'),
price: (float) $request->validated('price'),
);
}
}
4. Action Pattern:Service 的替代方案?
這是 Eric 我個人非常喜歡的一種模式,特別是在 Laravel 10 專案中。如果你的 Service 變得太過龐大(God Object),包含 `createPost`, `updatePost`, `deletePost` 等幾十個方法,那麼你可以考慮 Action Pattern。
每個 Action 只做一件事(Single Action Controller 的概念延伸到邏輯層)。例如 `CreatePostAction`, `ApplyDiscountAction`。這樣你的程式碼會變得極度專注且易於測試。
關於 Repository Pattern 的迷思
這是一個爭議話題。在 2026 年,我們對於 Laravel 中的 Repository Pattern 看法更加務實。Laravel 的 Eloquent ORM 本身就是一種 Active Record 實作,它已經非常強大。
- 什麼時候該用 Repository? 當你需要切換資料來源(例如從 MySQL 切換到 Elasticsearch),或者你的查詢邏輯極度複雜,需要被多處複用時。
- 什麼時候不該用? 如果你只是為了把 `User::find($id)` 包裝成 `UserRepository->find($id)`,那大可不必。這只是增加無謂的複雜度(Over-engineering)。
重構的策略:如何不把網站搞掛?
面對現有的 Laravel 10 遺留代碼,絕對不要想著「全部重寫」。那是自殺行為。我建議採用 Boy Scout Rule(童子軍法則):每次你觸碰一段程式碼修復 Bug 或新增功能時,順手把它清理得比原來更乾淨一點。
- 先為要修改的 Controller 寫好 Feature Test(確保重構後功能不變)。
- 提取驗證邏輯到 Form Request。
- 將商業邏輯提取到 Service 或 Action。
- 運行測試,確保一切綠燈。
結語:架構是為了人服務的
無論是 Service Layer、Repository 還是 DTO,這些架構模式的最終目的只有一個:降低認知負擔(Cognitive Load)。好的架構應該讓新加入的同事也能快速看懂程式碼的意圖,而不是在義大利麵裡迷路。
雖然我們談論的是 Laravel 10,但這些觀念在 Laravel 11、12 甚至未來的版本中都是通用的。保持程式碼的整潔與結構化,是資深工程師與「碼農」之間最大的區別。
你的 Laravel 專案是否也面臨著效能瓶頸或維護困難?或者你正打算進行大規模的系統重構?別讓技術債拖垮你的業務發展。
我們在 浪花科技 擁有豐富的 Laravel 企業級開發與重構經驗。無論是架構診斷、效能優化,還是從頭打造高擴展性的系統,我們都能提供協助。
延伸閱讀
- 你的 API 像公共廁所隨便進?Laravel 11 驗證 (Validation) 與 Middleware 客製化終極實戰
- 告別雜亂無章!資深工程師帶你走進 Laravel Admin 後台架構設計的藝術
- 網站卡住了?別再讓使用者等到天荒地老!Laravel 排程與背景任務 (Scheduler & Queue) 終極指南
常見問題 (FAQ)
Q1: Laravel 10 已經是舊版本了,為什麼不直接升級到最新版就好?
升級 Laravel 版本雖然重要,但它解決的是框架本身的安全與功能問題,並不能自動修復糟糕的程式碼架構。如果現有的架構混亂(例如胖 Controller),直接升級反而可能因為依賴項變更而導致更多 Bug。最佳實務是先進行架構重構(Refactoring),將邏輯分層清理後,再進行版本升級會順利得多。
Q2: 引入 Service Layer 和 DTO 會不會讓簡單的專案變得太複雜?
這取決於專案的規模與預期壽命。如果只是一個簡單的形象網站或短期活動頁,直接寫在 Controller 確實最快。但對於預期會長期維護、業務邏輯會持續增長的企業級系統,初期引入 Service Layer 增加的些許開發時間,會在日後的維護中以「倍數」節省回來。這是一種為了「可維護性」的投資。
Q3: 重構 Laravel 10 專案時,最容易遇到的地雷是什麼?
最常見的地雷是「缺乏測試覆蓋」。很多舊專案沒有寫單元測試,導致重構時無法確定是否破壞了原有功能。另一個地雷是「全域依賴」,例如在代碼深處直接呼叫 `request()` 或 `auth()->user()`,這會讓邏輯難以被抽離與測試。建議在重構前,至少先補上關鍵路徑的 Feature Test。






