PDA

View Full Version : آموزش: برنامه نویس حرفه ای و مفهوم SOLID



mb.rostami
جمعه 08 خرداد 1394, 12:06 عصر
سلام
بدون مقدمه
هر برنامه ای با هر زبانی که بخواهیم بنویسیم(زبان شی گرا) مثل PHP, .Net, Java و... بایستی یک سری اصول رو رعایت کنیم تا از بروز مشکلات متداول توی یک پروژه جلوگیری کنیم.
علاوه بر الگوهای طراحی که یک برنامه نویس حرفه ای باید با اونها آشنا باشه مفهوم دیگه ای با نام SOLID وجود داره.
SOLID مخفف 5 کلمه است :

S مخفف Single responsibility principle یا SRP به معنی اینکه هر کلاس بایستی فقط یک کار انجام دهد نه بیشتر.

O مخفف Open/closed principle یا OCP به معنی اینکه کلاس ها جوری نوشته بشن که قابل گسترش باشند اما نیاز به تغییر نداشته باشند.

L مخفف Liskov Substitution Principle یا LSP به مفهوم اینکه هر کلاسی که از کلاس دیگر ارث بری میکند هرگز نباید رفتار کلاس والد را تغییر دهد.
I مخفف Interface Segregation Principle با ISP به مفهوم اینکه چند اینترفیس کوچک و خورد شده همیشه بهتر از یک اینترفیس کلی و بزرگ است
D مخفف Dependency inversion principle یا DIP به معنی اینکه از اینترفیس ها به خوبی استفاده کن!

این اصول به ما کمک میکنه تا کمتر به مشکلات اساسی بر بخوریم و برنامه ای داشته باشیم که خیلی راحت قابل تست و قابل اجرا و قابل توسعه باشه.
منبع فارسی : سایت پیک نیک (http://pikneek.com/programming)
منبع انگلیسی : code.tutsplus.com (http://code.tutsplus.com/series/the-solid-principles--cms-634)

fatima-php
شنبه 09 خرداد 1394, 08:52 صبح
کاش برای هرکدوم از مواردی که گفتین، مثال هم میزدین. بعضیها خیلی سرراسته و توی PSR هم قید شده ولی بعضی دیگه مثل DIP رو فکر میکنم بهتر باشه مثال هم بزنید تا تاپیکتون کاربردی تر بشه.

vahid83
دوشنبه 18 خرداد 1394, 09:46 صبح
fatima-php (http://barnamenevis.org/member.php?360548-fatima-php) ، اگه به سايت پيك نيك سر بزنيد، بيشتر توضيح دادند.

fatima-php
دوشنبه 18 خرداد 1394, 11:15 صبح
بله دیدم ولی اولاً لینک دادن به سایتهای دیگه برای خوندن ادامه مطلب تا جایی که میدونم ممنوعه و تاپیک آموزش مرحله به مرحله PHP رو هم بخاطر همین مسئله حذف کردن و گفتن باید آموزشها به برنامه نویس منتقل بشه. ثانیاً یکسری چیزها مثل همین DIP توی اون سایت هم توضیح داده نشده. ضمناً نگفتن اگه قراره توی کلاس فرزند، متدها و رفتارهای کلاس والد رو تغییر ندیم، پس مفهوم و کاربرد Polymorphism و اصلاً امکان Override کردن رو برای چی توی برنامه نویسی شئ گرا گذاشتن. مثلاً اگه یه کلاس Point2D داشته باشیم و یک کلاس Point3D که از اون مشتق شده و هر دو کلاس، متد Display دارن که مؤلفه های نقطه رو در فضای دوبعدی یا سه بعدی نمایش میده، قطعاً نحوه نمایش در اشیاء سه بعدی فرق میکنه. اونوقت اصل اول SOLID داره میگه حق نداریم Display کلاس پایه رو اینجا بازنویسی کنیم. قاعدتاً باید طبق این اصل یک متد دیگه اضافه کنیم ولی متد Display دیگه بدرد نمیخوره و وجودش فایده ای نداره. پس چرا به ارث بردیمش؟!

mb.rostami
دوشنبه 18 خرداد 1394, 21:11 عصر
در مورد override کردن متد ها مشکلی وجود نداره, یعنی اینکه این حالت مجازه. اما در مورد مثال Point2D و Point3D بهتره گفته بشه که هر دو کلاس از یه کلاس پایه دیگه با نام Point ارث بری می کنند. اما در کل منظور از اصل سوم که اشاره کردید این نیست که متد ها نمی تونن Override بشن. منظور این هست که رفتار متد اصلی رو تغییر ندن. اگه قرار کار Display رو انجام بدن واقعا همین کار رو انجام بدن حالا چه 3D, چه 2D.
به هر حال در هر دو صورت کار Display انجام میشه. منظور این بود که اگه قراره کار Display انجام بشه متدی نوشته نشه که به جای Display از کاربر ورودی بگیره!
اصل اول هم به این اشاره میکنه که یک کلاس تنها و تنها یک وظیفه رو به عهده داشته باشه. اگه قراره نقطه ها نمایشه داده بشه بهتره برای هر کدوم دو کلاس مجزا داشته باشیم.
DisplayPoint2D برای چاپ نقطه ها که از کلاس DisplayPoint ارث بری(یا Implement) میکنه و کلاس Point2D که از کلاس Point ارث بری (یا Implement) میکنه.
در نهایت داخل کلاس DisplayPoint2D متدی با نام Display خواهیم داشت که ورودی این متد میتونه کلاسی از نوع Point2D باشه.

fatima-php
سه شنبه 19 خرداد 1394, 00:51 صبح
بنظرم این روش خیلی کارها رو پیچیده میکنه. الان این کلاسها مشکلی دارن؟

class Point2D
{
public $x;
public $y;

public function __construct()
{
$this->x = 0;
$this->y = 0;
}

public function display()
{
echo "<p>X = {$this->x}</p>";
echo "<p>Y = {$this->y}</p>";
}
}

class Point3D extends Point2D
{
public $z;

public function __construct()
{
parent::__construct();
$this->z = 0;
}

public function display()
{
parent::display();
echo "<p>Z = {$this->z}</p>";
}
}

در ضمن فکر میکنم طبیعیه که هیچ کسی توی متد Display نمیاد ورودی بگیره چون کارش مشخصه ولی قطعاً روش نمایش یک نقطه سه بعدی با دو بعدی فرق میکنه. پس عملاً متدهای کلاس پایه دارن توی کلاس مشتق شده تغییر میکنن.