در این مقاله به بررسی اصول SOLID در PHP میپردازیم؛ مجموعهای از پنج اصل طراحی که به بهبود قابلیت فهم، انعطافپذیری و نگهداری کد کمک میکنند. با استفاده از این اصول میتوانید کدهای تمیزتر و مقیاسپذیرتری در برنامهنویسی شیءگرا بنویسید.
SOLID چیست؟
شاید تا به حال این اصطلاح SOLID را در تقریباً هر شرح شغلی شنیده باشید و از خود بپرسید چرا اینقدر مهم است. اصول SOLID مجموعهای از پنج راهنمای طراحی هستند که هدف آنها قابل فهمتر کردن، انعطافپذیرتر کردن و نگهداری آسانتر طراحیهای نرمافزار است. این اصول به طور گسترده در برنامهنویسی شیءگرا استفاده میشوند، اگرچه میتوان آنها را در سایر پارادایمها نیز به کار برد.
ارکان اصول SOLID
کلمه اختصاری SOLID به معنای:
- اصل مسئولیت یگانه (SRP)
- اصل باز-بسته (OCP)
- اصل جایگزینی لیسکوف (LSP)
- اصل جداسازی رابط (ISP)
- اصل وارونگی وابستگی (DIP)
1. اصل مسئولیت یگانه (Single Responsibility Principle)
یک کلاس باید تنها یک دلیل یا هدف برای سرویسدهی داشته باشد. به این معنا که کلاس باید تنها یک مسئولیت داشته باشد. من هرکدام را به همراه مثالهایی در PHP توضیح خواهم داد.
// Single Responsibility Principle
// Shouldn't do
class Report {
public function generate() {
// generating report
}
public function saveToFile($filename) {
// save report to file
}
}
// Should do
class Report {
public function generate() {
// generating report
}
}
class ReportSaver {
public function saveToFile(Report $report, $filename) {
// save report to file
}
}
2. اصل باز-بسته (Open-Closed Principle)
اشیا باید برای توسعه باز و برای تغییر بسته باشند. به این معنا که اشیا (کلاسها، توابع، ماژولها و غیره) باید قابلیت گسترش توسط اشیای دیگر را داشته باشند، اما نباید اجازه تغییر مستقیم در آنها داده شود.
// Open Close Principle
// Shouldn't do
class Rectangle {
public $width;
public $height;
}
function area($rectangle) {
return $rectangle->width * $rectangle->height;
}
// Should do
interface Shape {
public function area();
}
class Rectangle implements Shape {
public $width;
public $height;
public function area() {
// w * h
}
}
class Circle implements Shape {
public $radius;
public function area() {
// πr2
}
}
3. اصل جایگزینی لیسکوف (Liskov Substitution Principle)
این به این معناست که اشیای یک کلاس والد باید بتوانند بدون تأثیر بر درستی برنامه، با اشیای کلاسهای فرزند جایگزین شوند. این یعنی برنامه باید بتواند بهدرستی با اشیای کلاسهای فرزند همانطور که با کلاس والد کار میکند، کار کند. حالا برای روشنتر شدن این موضوع، بیایید کد نمونه را ببینیم.
// Liskov Substitution Principle
// Shouldn't do
class Animal {
public function jump() {
// code for jumping
}
}
class Snail extends Animal {
public function jump() {
// Sanil can't jump
}
}
// Good example
abstract class Animal {
abstract public function eat();
}
class Snail extends Bird {
public function eat() {
// every animal can eat
}
}
class Tiger extends Bird {
public function eat() {
// every animal can eat
}
}
4. اصل جداسازی رابط (Interface Segregation Principle)
نباید اشیا را مجبور کنیم که رابطهایی را پیادهسازی کنند که به آنها نیازی ندارند. ما باید رابطها را به گونهای طراحی کنیم که در بیشتر موارد انعطافپذیر باشند.
// Interface Segregation Principle
// Shouldn't do
interface Human {
public function walk();
public function swim(); // not everyone can swim
}
// Should do
interface Walkable {
public function walk();
}
interface Swimmable {
public function swim();
}
class People implements Walkable, Swimmable {
public function walk() {
// walking
}
public function swim() {
// swimming
}
}
5. اصل وارونگی وابستگی (Dependency Inversion Principle)
این اصل با معرفی یک لایه انتزاعی بین ماژولهای سطح بالا (که عملکرد پیچیدهای را ارائه میدهند) و ماژولهای سطح پایین (که عملکردهای پایهای را فراهم میکنند)، هدفش جدا کردن این دو نوع ماژول است. این لایه انتزاعی باعث میشود که هم ماژولهای سطح بالا و هم سطح پایین به انتزاعات وابسته باشند، نه به پیادهسازیهای ثابت. نتیجه این کار افزایش انعطافپذیری، توسعهپذیری و قابلیت نگهداری سیستم است.
// Dependency Inversion Principle
// Shouldn't do
class Book {
public function getContent() {
// return contents
}
}
class Printer {
public function printBook(Book $book) {
$content = $book->getContent();
// print the content
}
}
همانطور که در مثال بالا مشاهده میکنید، کلاس Printer به شیء Book وابسته است و فقط میتواند برای کتاب چاپ کند. حالا اگر کلاسی دیگر به نام Article وجود داشته باشد که بخواهد از پرینتر استفاده کند، چه باید کرد؟ نباید کلاس Printer را تغییر دهیم تا اشیاء بیشتری را بپذیرد. در عوض، باید یک لایه انتزاعی بین آنها ارائه دهیم.
// Dependency Inversion Principle
// Should do
interface Printable {
public function getContent();
}
class Book implements Printable {
public function getContent() {
return "This is the book content";
}
}
class Article implements Printable {
public function getContent() {
return "This is the article content";
}
}
class Printer {
public function printContent(Printable $printable) {
$content = $printable->getContent();
echo "Printing content: " . $content;
}
}
در PHP، این اصول به ایجاد یک پایگاه کد تمیز کمک میکنند که اشکالزدایی، درک و گسترش آن آسانتر است. با توجه به اینکه برنامههای PHP معمولاً در طول زمان تکامل مییابند، اعمال اصول SOLID میتواند بهطور چشمگیری مشکلات مرتبط با رشد و نگهداری را کاهش دهد.
در این مقاله با `اصول SOLID در PHP` آشنا شدید. امیدوارم که این مقاله برای شما مفید بوده باشد. اگر هر سوال/مشکلی در خصوص این مقاله داشتید حتما در قسمت نطرات سایت با ما در میان بگذارید.
منبع: dev