داستان های Design Patterns

(خلاصه کتاب Head First Design Patterns - o Reilly)داستان اول- بخش اول - قصه Strategy Pattern توضیحات : در این سری از مقاله ها قصد دارم دلیل پیدایش هر کدام از Pattern ها را با مثال و به صورت داستان بیان کنم و چالش هایی که در رسیدن به یک الگو با آن دست و پنجه نرم می کنیم تا به یک Pattern برسیم را بررسی می کنیم . امیدوارم این مجموعه راهنمای خوبی را برای تفکر در مورد طراحی های شی گرا پیش روی ما قرار دهد. کدهایی که به صورت نمونه قرار می گیرد ، فارغ از نوع زبان برنامه نویسی می باشد و فرض براین است که اصول طراحی شی گرا را درک کرده ایم.به دنیای پترن ها خوش آمدید.(یک کسی قبلا مشکل شما را حل کرده است)با یک اپ ساده بازی شبیه سازی اردک ها شروع می کنیم : جویی قصه ما برای یک شرکت موفق بازی شبیه ساز اردک ها کار می کند.بازی می تواند گونه های مختلف اردک ها رانمایش بدهد که شنا می کنند و آوای صدای کوئک را تولید می کنند. طراحی اولیه سیستم از تکنیک های استاندارد شی گرا استفاده می کرد به این صورت که یک Super class مربوط به duck وجود داشت که تمامی گونه های اردک از آن ارث بری می کردند.و مابقی اردک ها از Duck ارث بری می کنند.و اما الان می خواهیم اردک ها پرواز کنند ........جویی با خودش فکرکرد که فقط کافی است متد fly را به کلاس duck اضافه کند تا همه اردک ها بتوانند پرواز کنند. در جلسه دمویی که در شرکت داشتند مشاهده نمودند که حتی اردک های پلاستیکی هم می توانند پرواز کنند که این رویه منجربه شکست در مقایسه با رقبا میشد. برخی اردک ها از جمله اردک پلاستیکی برخی رفتارهارا مانند fly و یا quack را نیازندارند که ارث بری کنند.جویی فکر کرد یکی از مهم تریم ویژگی های ارث بری Reuse بودن یا قابلیت استفاده مجدد آن است که این موضوع نگهداری سیستم را آسان تر می کند. جویی در مورد Inheritance تفکر کرد....هر کدام از اردک ها آوای صدایی خود را تولید می کنند و رفتارهای پرواز کردن آنها باهم متفاوت است. قرار است به لیست اردک موجود در بازی ، اردک چوبی هم اضافه شود که نه آوایی تولید می کند و نه پرواز می کند پس در متدهای fly و quack مربوط به آن هیچ پیاده سازی وجود ندارد . معایب زیر برای ادامه با طراحی بالا وجود دارد :برای هر کدام از Sub Class ها لزوم پیاده سازی این دو رفتار(quack وfly) اجبار می شود.ما دقیقا رفتار تمامی اردک ها را از ابتدا نمی دانیم.بنابراین ، این روش پاسخگوی نیاز ما نخواهد بود. راهکار دومی که جویی در مورد آن فکر کرد ، پیاده سازی رفتارها توسط Interface است که طراحی آن به صورت زیر می باشد :در طراحی بالا ، دورفتار quack و Fly از کلاس Duck بیرون کشیده شده است و در دو Interface قرار گرفته است تا هر کدام از رفتارها را فقط برای کلاس هایی که لازم داریم پیاده سازی نماییم . همان گونه که در تصویر مشخص است ، DecoyDuck یا اردک چوبی هیچ کدام از رفتارهار را پیاده سازی نکرده است. اشکالی که در این نوع طراحی می توان گرفت به این صورت است که اگر بخواهیم تغییری در رفتارها اعمال کنیم و بخواهیم آن تغییر در تمامی اردک ها اعمال شود ، بایستی آن را در همه اردک ها تکرار کنیم که قانون قابلیت استفاده مجدد یا Reuse را نقض می کند و کابوس نگهداری سیستم را خواهیم داشت.در سناریوی بالا ، بازهم مدیرجویی که کمی هم اصول شی گرایی را می دانست ، به وی اعتراض کرد که اگر بخواهیم تکه کدی را به متد Fly اضافه کنیم آیا بایستی تمامی زیرمجموعه ها آن تکه کد اضافه شود(تمامی زبان ها امکان پیاده سازی کد در Interface را ندارند.) ؟ پس همان طراحی قبلی با Duplicate Code بهتربود.اگر شما به جای جویی بودین چه کار می کردین ؟یک اصل ثابت در توسعه نرم افزارآیا چیزی در توسعه نرم افزار هست که شما همیشه بتوانید روی آن حساب باز کنید؟جدای از اینکه شما کجا کار می کنید ، در حال ساختن چه نرم افزاری هستید یا شما با چه زبانی در حال برنامه نویسی هستید . چه اصل ثابتی برای همیشه با شما همراه خواهد بود؟تغییرجدای از اینکه شما چقدر خوب نرم افزار خودرا طراحی کرده اید ، در طول زمان و به مرور نرم افزار بایستی رشد کند و دراین حین یا تغییرات انجام می شود یا نرم افزار طراحی شده ، محکوم به فنا خواهد بود.اولین اصل طراحیجنبه هایی از نرم افزار خود را که تغییر می کنند را تشحیص دهید و آنها را از قسمت هایی که ثابت باقی می مانند ، مجزا کنید.ما می دانیم که متدهای fly و duck قسمت هایی از کلاس duck هستند که درحال تغییر می باشند، بنابراین این رفتارهارا از کلاس duck بیرون می کشیم و هر کدام از آنهارا به عنوان یک کلاس در نظر می گیریم.که تصویر شماتیک آن به صورت زیر می باشد :جداسازی یا Encapsule نمودن رفتارهای متغیرماجرا هنوز ادامه دارد و در قسمت های بعدی بیشتر آن را درک می کنیم....