دیزاین پترن ها(قسمت اول)

مقدمهبه عنوان یک برنامه نویس، فارغ از اینکه با چه زبان شی گرایی کد نویسی کنید، یک سری چهارچوب فکری برای کد نویسی باید در اختیار داشته باشید. این چهارچوب هاست که در کنار کد نویسی، به شما در تولید کد با کیفیت کمک میکنه.ما در برنامه نویسی:یک سری اصول داریم مثل SOLID،DRY و KISS.یک سری پترن یا الگو داریم که مشهور ترینشون GOF است.سوالی که مطرح میشه، اینه که این دسته بندی، الگو و اصل بر چه اساسی است؟ یعنی چه چیزی رو ما الگو می نامیم و چه چیزی رو اصل؟الگو ها تمرکزشون روی پیاده سازیه. در صورتی که اصل ها اصلا در مورد پیاده سازی صحبت نمیکنند.به بیان بهتر، الگوها از تجربه های زیاد در کدنویسی و در برخورد با صورت مساله های تکراری که در حال حاضر در بسیاری از سامانه های نرم افزاری هست، به وجود می آیند و راه حل هایی هستند که در دنیا توسط بسیاری از برنامه نویسان استفاده شده و نتایج استفاده خوبی در بر داشته و به برنامه نویس ها توصیه میشه که ازشون استفاده کنند. همون اصطلاح معروف چرخ رو اختراع نکن! اگر کسی قبلا چرخ رو ساخته، ازش استفاده کن.اما اصل ها به پیاده سازی نرم افزار کار ندارند. تمرکزشون روی اینه که با توجه به ماهیت نرم افزار و اینکه دائما در حال تغییره و مرتبا گسترش پیدا میکنه، چه طور میشه در مقابل این تغییر و توسعه مقاوم بود و محصولی با قابلیت نگهداری و توسعه ی خوب داشت. در واقع اصل ها تمرکزشون روی خود حفظ و نگهداری محصوله و پایبندی به اصل ضروریه. وگرنه احتمال شکست نرم افزار در مارکتینگ، در نهایت بسیار بالاست.دسته بندی الگوها به بیان سادهبر اساس Gang of Four (GOF) که گفتم مرجع اصلی دیزاین پترن هاست، ما سه دسته بندی اصلی داریم. این دسته بندی بر چه اساسیه؟ بر اساس کاربرد.دسته اول الگوها، الگوهای Creational هستند : یک سری الگو معرفی شدند بابت ایجاد شی از کلاس. یعنی چی؟ به بیان خیلی ساده، یعنی شما یک کلاس داری، و بسته به بیزنس و نیازمندی هایی که داری بابت اون موجودیت، پیچیدگی اش و اینکه میخوای منطق ایجاد شی ات رو هم پنهان کنی و .... به جای اینکه همه جای کد ات، همینطوری خیلی علی الله ای!، فقط بخوای بنویسی new و شی ایجاد کنی، بخوای راه حل های مختلف ارائه بدی.صورت مساله : مثلا یک کلاس Person داری که بر اساس موجودیت شخص حقیقی ایجاد شده. |این آدمه یک جا توی زیر سیستم حسابداری ات ممکنه new بشه که خب رول های مختلف، سطح دسترسی های مختلف و ... میگیره. یک جا ممکنه توی زیر سیستم انبارت new میشه. یک جا ممکنه توی زیر سیستم حقوق دستمزدت new میشه. یک جایی ممکنه توی زیر سیستم فروش به عنوان مشتری ات new بشه. یعنی ممکنه از این کلاس برای مصارف مختلفی شی ایجاد بشه.پس صورت مساله ات اینه که وقتی یک کلاسی دارم که ازش داره اشیایی مختلفی ایجاد میشود.بسته به نیازمندی، چطوری این ایجاد شدن رو بنویسم خوبه؟ خب الگوهایی مثلا Factory Method یا Abstract Factory رو میتونی به کار بگیری.صورت مساله: آقا من یک کلاسی دارم، خیلی سنگینه. و مدام هم در تمام بیزنس هام ازش داره شی ایجاد میشه. چطوری میتونم این ایجاد شی رو بهینه تر و سبک تر کنم؟...اینجا الگوی prototype توصیه میشه. صورت مساله: من یک کلاس دارم که میخوام یک دونه شی ازش ایجاد کنم.فقط یک instance. چی کار کنم...بهش میگیم برو الگو Singleton رو برای کلاست پیاده سازی کنو الی ماشاالله که حالا در قسمت های بعدی اگر عمری بود به ریز این الگوها رو توضیح میدم.دسته دوم الگوها، الگوهای ساختاری یا Structural هستند : اینا الگوهایی هستند که تمرکزشون روی نحوه نگارش خود کلاس، توسعه و نیازمندی متد های ایجاد شده داخل کلاس هستند. در واقع اینها الگوهایی هستند که زمانی که میخوای یک کلاس ایجاد کنی،یا یک متد برای کلاست بنویسی و ... قبل از اینکه شروع کنی به نوشتن اش، ازت میخوان که به بیزنس ات، اینکه اصلا این کلاسه یا متده برای چی داره ایجاد میشه و قراره چی کار کنه و چه نیازمندی هایی داره و اینا فکر کنی و بعد شروع کنی به ایجاد کلاس ات. در واقع این الگو ها تمرکزشون روی خود کلاس و متدهاشه. این کلاس قراره چی کار کنه؟ چه طوری توی ارث بری ها شرکت کنه؟ از چه اینترفیسی میخواد ارث ببره یا کرده و ...صورت مساله: فرض کنید میخواهید یک ERP برای یک شرکت سازمانی خاص ایجاد کنید. خب مسلما در هر ساختار سازمانی، ما موجودیتی به اسم چارت سازمانی داریم که ساختارش درختیه. مدام در تمامی زیر سیستم های مختلف داره پیمایش میشه و عملیات Crud روش انجام میشه و پشت این عملیاتم بیزنس ران میشه.مثلا آدمه از اون سازمان استعفا میده، جابه جا میشه، سمت اش عوض میشه، یا در یک جایگاه سازمانی یک جایگاه جدیدی که قبلا نبوده، قراره ایجاد بشه و ...خب در چنین ساختار درختی، اگر کلاسی برای موجودیت چارت دارید ایجاد میکنید باید به این ساختار Tree گونه این موجودیت فکر کنید و الگو Composit برای این صورت مساله تکراری در دنیا، مطرح شده.صورت مساله: آقا من قبلا توی زیر سیستم حضور غیابم اومدم تمام متدها و روال های محاسبه ی روز تعطیلی و شیفت تعطیلی و ... رو نوشتم. و بعد زیرسیستم حقوق و دستمزد من داره از اینها استفاده میکنه و کارم میکنه.حالا کارفرما میاد میگه که آقا من یک پاداش میخوام توی سازمانم راه بندازم تحت عنوان کارانه ، بعد یک سری فرمول برای محاسبات رقم این کارانه به شما میده. خب یک قسمتی از این روال ها همین الان در حقوق و دستمزد داره استفاده میشه.ولی برای پاداش یک سری تغییراتم لازم هست که صورت بگیره.آیا من بشینم از اول جدا بنویسم همه این روال ها رو مختص کارانه؟ یا بیام دست بزنم توی اون روال ها و برای زیر سیستم حقوق دستمزدم ریسک خطا ایجاد کنم؟خب طبیعتا اینجا الگو Adapter بهتون کمک زیادی می کنه که به این چالش هاتون فائق بشین. و همینطور صورت مساله های مختلفی که الگوهای ساختاری توشون ایجاد شده.دسته سوم یا دسته آخر الگوها، بهشون میگن الگوهای رفتاری یا Behavioral:این الگو ها روی روابط بین اشیا تمرکز دارند. جاهایی که در مورد رفتار یک کلاس یا شی لزوما صحبت میکنیم.صورت مساله: خیلی بر میخوریم توی کد ها به الگوهای شرطی. اگر اینجوری بود، برو اینکارو بکن. else برو اینکارو بکن.باز توی else همینطور یک if دیگه.یک else دیگه و همینطور تاااااا بی نهایت داره بسته به بیزنس زیاد میشن. خب به مروز زمان این نگهداری کد، انتقال کد به برنامه نویسان بعدی، تست نویسی رو هی بیشتر سخت و سخت تر و سخت تر میکنه. اینجا خب میشه برای چنین رفتار سیستمی از الگو Chain of Responsibility استفاده میکرد. مثل Middleware ها توی دات نت کور. که هر واسط یا Middleware ای کار خودش رو انجام میده خروجی رو میده به واسط بعدی، واسط بعدی و در نهایت کار از همون مسیری که رفته جلو، لازم باشه برمیگرده.صورت مساله: یک سری مجموعه از یک اشیایی دارید که اینها نوع مجموعه شون مشخص نیست. یک بار لیست بهتون پاس داده میشه توی بیزنس. یک بار آرایه پاس میدن. یک بار صف هستند... اصلا مشخص نیست این مجموعه شی شما از چه مدل مجموعه ای قراره بیاد. بعد شما از فارغ از نوع مجموعه، میخوای یک روال پیمایش برای این اشیا بنویسی و خب یک بیزنسی پیاده سازی کنی. خب این یک صورت مساله خیلی پر تکرار در دنیا بوده... من چه جوری میتونم بر این عدم درک از نوع مجموعه ورودی ام غلبه کنم و یک کد همیشگی بنویسم؟ الگو معرفی شده بابت چنین مسائلی Iterator هست.و همینطور مسائل مختلف Behavioral که در دنیا مطرح شده و راه حل به شکل الگو براش ارائه شده.در قسمت های بعدی به جزئیات بیشتری از Design pattern ها خواهیم پرداخت.