SOLID مخفف پنج اصل در برنامه نویسی شی گرایی می باشد که توسط رابرت سی مارتین مطرح شده است.با استفاده از این اصول انعطاف پذیری و گسترش در توسعه و نگهداری نرم افزار راحتر صورت می گیرد.
1- Single Responsibility
هر کلاس باید تنها یک مسئولیت داشته باشد.
اگر یک کلاس کار های مختلفی داشته باشد، احتمال ایجاد خطا در آن افزایش می یابد، زیرا ایجاد تغییرات در یکی از توابع، می تواند در خروجی و ورودی توابع دیگر تاثیر بگذارد. رعایت اصل تک مسئولیتی هم پیچیدگی ها را کاهش میدهد و هم سرعت توسعه را بالا میبرد.
class TaxCalculator {
public function calculateTax($income) {
$tax = $income * 0.25; // محاسبه مالیات
return $tax;
}
}
2- Open/Closed
کلاس ها برای توسعه باید باز باشند ولی برای ویرایش بسته.
این اصل به معنای این است که کلاسها باید برای توسعه باز و برای تغییر بسته باشند. به عبارت دیگر، کلاسها باید به گونهای طراحی شوند که برای اضافه کردن ویژگیهای جدید به سیستم، نیاز به تغییر در کدهای موجود نباشد و تنها با ایجاد کلاسهای جدید بتوان ویژگیهای جدید را به سیستم اضافه کرد.
interface Shape {
public function area();
}
class Rectangle implements Shape {
private $width;
private $height;
public function __construct($width, $height) {
$this->width = $width;
$this->height = $height;
}
public function area() {
return $this->width * $this->height;
}
}
class Circle implements Shape {
private $radius;
public function __construct($radius) {
$this->radius = $radius;
}
public function area() {
return pi() * $this->radius * $this->radius;
}
}
3-Liskov Subtitution
این اصل به معنای این است که هر شیء میتواند به جای شیء والدش استفاده شود و به گونهای طراحی شود که اگر یک کلاس جایگزین دیگری برای آن استفاده شود، عملکرد سیستم به همان شکل ادامه پیدا کند. به این ترتیب، ارث بری در ساختار کلاسها باید به گونهای باشد که شیءهای فرعی میتوانند جای شیءهای پایه را بگیرند.
abstract class Animal {
abstract public function makeSound();
}
class Cat extends Animal {
public function makeSound() {
echo "Meow!";
}
}
class Dog extends Animal {
public function makeSound() {
echo "Woof!";
}
}
4- Interface Segregation
زمانی که یک کلاس از یک interface ارث بری می کند لازم نباشد متد هایی که قرار نیست از آن استفاده کند پیاده سازی شود
این اصل به این معنی است که باید رابطها را به گونهای طراحی کنید که تمام ویژگیهایی که برای یک کلاس مورد نیاز است، در یک رابط قرار داشته باشد. به عبارت دیگر، هر کلاس فقط باید به رابطهایی که برایش مورد نیاز هستند، وابستگی داشته باشد.
interface Printable {
public function print();
}
interface Faxable {
public function fax();
}
class Printer implements Printable {
public function print() {
echo "Printing...";
}
}
class FaxMachine implements Faxable {
public function fax() {
echo "Faxing...";
}
}
5- Dependency Inversion
کلاس های سطح بالا نباید به کلاس های سطح پایین وابستگی داشته باشند بلکه هر دو باید به کلاس های انتزاعی(abstarct) وابسته باشند.
هر بخشی از نرم افزار باید فقط به اطلاعاتی دسترسی داشته باشد که برای انجام وظیفه اش لازم است. این امر منجر به کاهش ارتباطات ناخواسته بین قسمت های مختلف می شود.
interface MessageSender {
public function sendMessage($message);
}
class EmailSender implements MessageSender {
public function sendMessage($message) {
echo "ارسال ایمیل: " . $message;
}
}
class MessageService {
private $sender;
public function __construct(MessageSender $sender) {
$this->sender = $sender;
}
public function send($message) {
$this->sender->sendMessage($message);
}
}
این اصول به شکل کلی منظم و قابل اجرا بودن کدهای نرمافزاری را ارتقا میدهد و از جمله مهمترین اصول در طراحی سیستمهای نرمافزاری به شمار می آید.