TGViewer
| کانال توسعه‌دهندگان لاراول | | کانال توسعه‌دهندگان لاراول | @developixlaravel · 1.54K subscribers
Post #181 1.05K
‎تمیز کردن کنترلرهای Laravel با Service Layer 🧼

خیلی وقت‌ها کنترلرهای Laravel کم‌کم تبدیل می‌شوند به محل تجمع همه‌چیز: validation، منطق بیزنسی، queryهای Eloquent، ارسال notification و…

این یعنی:

• سختی در تست کردن 🧪
• کدهای تکراری در چند کنترلر
• سختی در تغییر منطق بیزنسی بدون شکستن endpointها

یکی از الگوهای ساده و کاربردی برای حل این مشکل در Laravel، استفاده از Service Layer است.

ایده اصلی ✨

هر action در کنترلر فقط کارهای زیر را انجام دهد:

• دریافت و validate ورودی
• صدا زدن یک Service (یا چند Service)
• برگرداندن Response مناسب (JSON / View)

تمام منطق بیزنسی داخل کلاس‌های Service قرار می‌گیرد.

نمونه سناریو: ثبت سفارش 🛒

قبل از refactor (کنترلر چاق)
class OrderController extends Controller
{
public function store(Request $request)
{
$data = $request->validate([
'user_id' => ['required', 'exists:users,id'],
'items' => ['required', 'array'],
]);

$user = User::findOrFail($data['user_id']);

$order = DB::transaction(function () use ($user, $data) {
$order = $user->orders()->create();

foreach ($data['items'] as $item) {
$order->items()->create($item);
}

if ($user->isVip()) {
$order->applyDiscount(10);
}

return $order;
});

Notification::send($user, new OrderCreated($order));

return response()->json($order, 201);
}
}


کنترلر هم transaction دارد، هم business rule (Vip)، هم notification.

بعد از refactor با Service ✅

۱) ساخت Service:
namespace App\Services;

use App\Models\User;
use App\Notifications\OrderCreated;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Notification;

class OrderService
{
public function createOrderForUser(User $user, array $items)
{
$order = DB::transaction(function () use ($user, $items) {
$order = $user->orders()->create();

foreach ($items as $item) {
$order->items()->create($item);
}

if ($user->isVip()) {
$order->applyDiscount(10);
}

return $order;
});

Notification::send($user, new OrderCreated($order));

return $order;
}
}


۲) تزریق Service در کنترلر (Dependency Injection از Service Container):
use App\Models\User;
use App\Services\OrderService;
use Illuminate\Http\Request;

class OrderController extends Controller
{
public function __construct(private OrderService $orderService)
{
}

public function store(Request $request)
{
$data = $request->validate([
'user_id' => ['required', 'exists:users,id'],
'items' => ['required', 'array'],
]);

$user = User::findOrFail($data['user_id']);

$order = $this->orderService
->createOrderForUser($user, $data['items']);

return response()->json($order, 201);
}
}


مزایا 💡

• کنترلرها کوتاه و قابل‌خواندن
• قابلیت استفاده مجدد از منطق در Job، Command، Event Listener و…
• آماده‌تر شدن برای تست واحد (Unit Test) روی Serviceها به‌جای تست‌های سنگین روی کنترلر

منابع پیشنهادی 📚

• مستندات Service Container در Laravel:
laravel.com/docs/container

این الگوی ساده اگر از همین امروز در پروژه لاراول‌تان اجرا شود، معماری تمیزتری می‌سازد و تغییرات بعدی را بسیار کم‌هزینه‌تر می‌کند 🌱

🔖 #Laravel #PHP #لاراول #Laravel #Service_Layer #Clean_Code #Controller #PHP #Architecture

👤 Developix

💎 Channel: @DevelopixLaravel
  • 👍 4
  • ❤ 3
More from @developixlaravel
  1. Oct 1, 2026روابط پایگاه داده چند ریختی یا Eloquent Polymorphic در لاراول - قسمت اول در لاراول، روابط…
  2. Sep 30, 2026مدیریت همزمانی و قفل‌گذاری روی پردازش‌ها در لاراول (Laravel Atomic Locks) در بخش چهارم از…
  3. Sep 26, 2026🔥 پکیج: ورود با حساب‌های دیگر؛ Socialite برای اضافه‌کردن ورود با حساب‌های دیگر به پروژه ل…
  4. Sep 25, 2026🔒 فقط داده‌های تأییدشده را ذخیره کن وقتی یک فرم ویرایش پروفایل داری، ممکن است کلاینت علاو…
  5. Sep 20, 2026حفاظت از پردازش ها با Laravel Rate Limiter بخش سوم - پیکربندی در قسمت سوم از مجموعه آموزش…
  6. Sep 16, 2026🚀 ‏LaraGram Brain منتشر شد! از این به بعد برای ساخت ربات‌های تلگرام با فریم‌ورک LaraG…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →