重構 Laravel 10 專案架構:終結義大利麵程式碼的設計心法
☰ 目錄 table-of-contents.md
接手過的 Laravel 10 專案多了,我發現一個共通點:即使 Laravel 13 的謠言滿天飛、新的 AI Agent 開發工具層出不窮,企業手邊跑得最穩的,往往還是這些 Laravel 10 老專案。穩定比追新重要,但穩定不等於放任架構腐化——這篇就來談 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 企業級開發與重構經驗。無論是架構診斷、效能優化,還是從頭打造高擴展性的系統,我們都能提供協助。
延伸閱讀
RoamerHost 幫你把開源 AI 與自動化工具一鍵代管:獨立 Docker、自動 SSL、24/7 監控,60 秒上線。省下租機器、裝環境、顧維運的力氣,訂閱就能開始用。
▶立即免費註冊常見問題
Laravel 專案為什麼會變成難以維護的「義大利麵程式碼」?
如何把驗證邏輯從 Laravel Controller 中抽離?
Service Layer(服務層)在 Laravel 架構中扮演什麼角色?
Laravel 專案一定要用 Repository Pattern 嗎?
面對現有的 Laravel 遺留專案,該如何安全地重構?
訂閱免費電子報
把 AI 自動化、企業系統設計與 WordPress / Laravel 開發的真實案例和可直接照做的技巧,整理成電子報寄給你。只寄精選內容、不灌垃圾信,一鍵就能退訂。