بله یکی از سوالاتی که توی مصاحبه های برنامه نویسان پرسیده میشه عموما، همین مفهوم دیزاین پترن (الگوی طراحی) هستش.
سوال من اینه که اول دیزاین پترن دقیقا چی هستن؟
از نظر تحت و الفظی، خب design pattern به معنی الگوی طراحی هست، به عبارت بهتر، وقتی داریم یه نرم افزار رو توسعه میدیم، حین توسعه، نیاز داریم کلاس هایی رو اضافه کنیم، توابعی رو بسازی، مسیر تعریف کنیم و .. که اینا همه باید در قالب یک الگوی مشخص و از پیش تعریف شده باشه.
پس دیزاین پترن یک کلاس خاص یا یک اسکریپت مشخصی نیست که اگه اون رو به کدت اضافه کردی میتونی بگی کد من دیزاین پترن داره!
بله همونطور که گفتی، دیزاین پترن فقط مختص زبان php نیست و یک مفهمومه که توی سایر زبان ها هم معنی داره. مثلا شما نیاز داری توی یک کلاس یک سری متغییر (از پیش تعریف شده) تزریق بشه و مقادیرشون قابل استفاده باشه توی اون کلاس .. یا کلاس های یک موجودیت خاص، همه باید از کلاس پدر اون موجودیت extends بشن .. و خلاصه یک سری از این الگوها که باعث میشه یک ساختار و روند ثابت و قابل اتکا توی کد ایجاد بشه.
مبنی دیزاین پترن ها
در واقع تمام دیزاین پترن ها مبتنی به 3 پایه هستن که در ادامه لیست تمام دیزاین-پترن ها رو برای هر کدوم از پایه های اصلی به همراه یک توضیح مختصر ذکر میکنم:
-
ساختاری (structural)
-
Adapter: یک واسط را به واسط مورد نظر کلاینت تبدیل میکنه و اجازه میده تا کلاسها با اینترفیسهای متفاوت و ناسازگار با یکدیگر کار کنن.
-
Bridge: کلا واژه bridge به معنی «پُل» هست؛ این لایهٔ انتزاع را از لایهٔ پیادهسازی جدا میکنه، بنابراین دو کلاس میتوانند مستقلاً تغییر کنن.
-
Composite: اشیاء را درون ساختار درختی ترکیب میکنه تا سسله-مراتب جز-کل را ارائه کنه. الگوی کامپوزت به کارخواهها اجازه میده تا با اشیاء تکی و با اشیائی که ترکیبی از اشیاء هستند، به یک صورت رفتار کنه.
-
Decorator: وظایف و قابلیتهای بیشتری را به صورت داینامیک به شیء اضافه میکنه. دکوریتورها برای توسعهٔ رفتارها و قابلیتها روش انعطافپذیر جایزینی را به جای زیرکلاسسازی ارائه میدن.
-
Facade: واسط یکپارچهای را برای مجموعهای از واسطها در زیر سیستم، ارائه میده. این الگو واسط سطح-بالاتری را تعریف میکنه که استفاده از زیرسیستم را سادهتر میکنه.
-
Flyweight: استفادهٔ دوبارهٔ بسیاری از اشیاء fine-grain رو با اشتراک آنها در سیستم، آسان میکنه.
-
Proxy: برای کنترل دسترسی به اشیاء، نماینده یا نگهدارندهای برای آنها ارائه میکنه.
-
ساختنی (creational)
-
Abstract Factory: بدون مشخص کردن کلاسهای کانکرت، واسطی برای ساخت خانوادهای از اشیاء وابسته یا مرتبط با یکدیگر فراهم میکنه.
-
Builder: روند ساخت یک شیء پیچیده رو از نمایش آن جدا میکنه، به طوری که یک روند ساخت مشترک میتواند برای ساخت انوع بازنماییها به کار گرفته میشه.
-
Factory Method: واسطی برای ساخت اشیاء ایجاد میکنه، اما به زیرکلاسها اجازه میدهد که تصمیم بگیرن که چه کلاسی رو نمونهسازی کنن. این الگو اجازه میده تا نمونهبرداری کلاس، به زیرکلاسها معوق بشه.
-
Prototype: انواع اشیائی که باید ساخته بشن رو با استفاده از یک نمونهٔ اولیه، مشخص میکند و اشیاء جدید رو با کپی کردن این نمونهٔ اولیه تولید میکنه.
-
Singleton: تضمین میکنه که کلاس تنها یک نمونه داشته باشه و دسترسی سراسری برای آن فراهم میکنه.
-
رفتاری (behavioral)
-
Chain Of Responsibility: با دادن بیشتر از یک شیء برای هندل کردن درخواست از جفتگری (کوپلینگ) فرستندهٔ درخواست و گیرندهٔ درخواست اجتناب میکنه. اشیاء گیرنده رو زنجیر میکنه و درخواست را در امتداد زنجیر گذر میده تا زمانی که یکی از اشیاء آن را هندل کنه.
-
Command: درخواست را به عنوان یک شیء کپسوله میکنه، از این رو اجازه میده تا بتونید کارخوهها رو با درخواستها، صفها و یا لاگهای متفاوت پارامتری کنید.
-
Interpreter: یک بازنمایی برای گرامر زبان داده شده تعریف میکنه و مفسر توسط این باز نمایی، جملات زبان را تفسیر میکنه.
-
Iterator: روشی برای دستری به عناصر یک شیء اگریگیت فراهم میکنه بدون اینکه اصول پیادهسازی و ساختمان دادهٔ لایهٔ زیرین اگریگیت را نمایش میده.
-
Mediator: شیءای رو تعریف میکند که نحوهٔ ارتباط بین مجوعهای از اشیاء را کپسوله میکنه. این الگو با جلوگیری ارتباط صریح بین اشیاء از جفتگری ضعیف (loose coupling) پشتیبانی میکنه.
-
Memento: بدون تخلف از کپسولهسازی، وضعیت داخلی شیء ضبط و استخراج میکنه از این رو شیء بعداً میتواند به این حالت برگرده.
-
Observer: وابستگی یک-به-چند بین اشیاء تعریف میکنه بنابراین وقتی یک شیء وضعیتاش را تغییر میده، تمامی اشیاء وابسته به آن از آن تغییر مطلع شده و به صورت خودکار به روز میشن.
-
State: به شیء این اجازه رو میده که وقتی وضعیت درونیاش تغییر کرد، رفتارش رو تغییر بده. در واقع به نظر میرسه که شیء کلاس خود را عوض میکنه.
-
Strategy: خانوادهای از الگوریتم ها رو تعریف میکنه، هر یک رو کپسوله میکنه و آنها را جابهجا پذیر میکنه. الگوی استراتژی اجازه میده که الگوریتمها مستقل از کارخواهی که از آنها استفاده مکنه، تغییر کنن.
-
Template Method: استخوانبندی و شالودهٔ اصلی عملیات الگوریتم رو تعریف میکند، و پیادهسازی هر مرحله رو به زیرکلاسها میسپره. این الگو، به زیرکلاسها این اختیار رو میده که تا خودشان، مراحل الگوریتم رو پیاده کنن بدون اینکه ساختار الگوریتم رو تغییر بدن.
-
Visitor: اعمالی که باید روی عناصری از شیء اجرا شود رو ارائه میکنن. این الگو اجازه رو میده تا اعمال جدیدی تعریف کنید بدون اینکه کلاسهایی که این اعمال روی آنها انجام میشه رو تغییر بدید.
دیزاین پترن ربطی به کد نویسی و syntax کدها دارن یا یک مفهوم هستن صرفا؟
ربطی به کد نویسی اره داره! ربطی به سینتکس نه نداره! این تعریفی هست که از دیزاین پترن داریم:
In software engineering, a software design pattern is a general, reusable solution to a commonly occurring problem within a given context in software design. It is not a finished design that can be transformed directly into source or machine code.
همونطور که میبینی، دیزاین پترن یک راه حل کلی و قابل استفاده هست برای تمام مشکلاتی که توی فرایند طراحی نرم افزار باهاش مواجه میشیم. طبیعتا نرم افزارها باهم متفاوتن و کاربری و عملکرد خودشون رو دارن، به همین دلیل هر دیزاین پترنی هم میتونه در جای خودش برای هر پروژه مفید و مناسب باشه.
کلا توی پی اچ پی دیزاین پترن factory انگار از همشون برجسته تره؟
نه واقعا! قاطعانه نمیشه همچین چیزی رو گفت. هر دیزاین پترنی برای یک پروژه میتونه بهترین انتخاب باشه .. اره لاراول Laravel که تقریبا جزو محبوب ترین فریم ورک های زبان php هست داره از دیزاین پترن factory استفاده میکنه، ولی خب بازم دلیل نمیشه که بگیم این بهترین دیزاین پترنه. اگه به من باشه که میگم کلا فریم ورک لاراول انتخاب خوبی نیست.
البته اینم بگم که توی دیزاین پترن های موجود php، در واقع factory ساده ترین و در عین حال بسیار قدرتمنده. ولی در کل دیزاین پترن های Adapter، Strategy، Observer، Decorator هم جزو کاربردی ترین دیزاین پترن های زبان php هستن. برای اطلاعت بیشتر راجع به این موضوع بد نیست مقاله The 5 Most Common Design Patterns in PHP Applications رو مطالعه کنی.
در پی اچ پی design pattern های خودش رو داره و مثلا سی شارپ هم design pattern های خودشو داره؟
درواقع یک سری دیزاین پترن design pattern کلی هست که توی زبان های مختلف مشابه هستن. ولی از اونجایی که گاها زبان ها از بنیه متفاوت هستن (مثلا یک سریهاشون کامپایلر دارن یه سری هاشون مفسر )، خلاصه یک سری دیزاین پترن بومی سازی شده برای هر زبان هم وجود داره. به عنوان مثال Dependency Injection یکی از دیزاین پترن هایی هست که توی یک سری از زبان ها وجود نداره.