یکی از مهمترین اصول SOLID که روی تمیزی کد PHP تاثیر مستقیم دارد، Single Responsibility Principle (SRP) است؛ یعنی هر کلاس فقط یک دلیل برای تغییر داشته باشد.
وقتی همهچیز را در یک کلاس میریزیم، بعد از مدتی هر تغییر کوچک تبدیل میشود به کابوس ریفکتور، با دهها باگ پنهان 😅
نمونه کد بد (نقض SRP) 👇
<?php
class UserService
{
public function register(string $email, string $password): void
{
// 1) validation
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException('Invalid email');
}
if (strlen($password) < 8) {
throw new InvalidArgumentException('Weak password');
}
// 2) save to database
// imagine: DB queries here...
// 3) send welcome email
mail($email, 'Welcome', 'Thanks for registering');
}
}
در این کلاس،
UserService هم validation انجام میدهد، هم کار دیتابیس، هم ارسال ایمیل. سه دلیل برای تغییر در یک کلاس؛ این یعنی خلاف SRP.ریفکتور با SRP ✅
هر بخش را به مسئولیت خودش محدود میکنیم:
<?php
class UserValidator
{
public function validate(string $email, string $password): void
{
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException('Invalid email');
}
if (strlen($password) < 8) {
throw new InvalidArgumentException('Weak password');
}
}
}
class UserRepository
{
public function save(string $email, string $password): void
{
// persist user to DB (PDO / ORM / ...)
}
}
class Mailer
{
public function sendWelcome(string $email): void
{
// use real mailer here
}
}
class UserService
{
public function __construct(
private UserValidator $validator,
private UserRepository $repository,
private Mailer $mailer,
) {}
public function register(string $email, string $password): void
{
$this->validator->validate($email, $password);
$this->repository->save($email, $password);
$this->mailer->sendWelcome($email);
}
}
حالا:
• تغییر قوانین پسورد فقط روی
UserValidator اثر دارد 🔐• تغییر دیتابیس یا ORM فقط در
UserRepository انجام میشود 🗄️• سوییچ از
mail() به مثلاً Symfony Mailer فقط در Mailer عوض میشود 📧چرا این ساختار در پروژه واقعی PHP (مثلاً Laravel) جواب میدهد؟
در فریمورکهایی مثل Laravel و Symfony همین ایده تکرار شده: Form Requestها برای validation، Repository / Model برای persistence، و Service / Mailer برای بیزنس لاجیک و ایمیل. SRP دقیقا پشت این تفکیک قرار دارد.
یک قدم ساده مثل جدا کردن validation و ایمیل از کلاس اصلی، کد را:
• قابل تستتر میکند (Unit Test روی هر کلاس جدا)
• قابل ریفکتورتر میکند
• خوانایی تیمی را بالا میبرد
موقع نوشتن کلاس بعدی، فقط از خودت بپرس:
این کلاس دقیقاً مسئول چه کاری است؟ اگر جواب بیشتر از یک جمله شد، یعنی وقت ریفکتور است 😉
منابع پیشنهادی برای مطالعه بیشتر:
PHP The Right Way - SOLID
Single Responsibility Principle (Wikipedia)
🔖 #PHP #پی_اچ_پی #PHP #Clean_Code #SOLID #SRP #Architecture
👤 Developix
💎 Channel: @DevelopixPHP