کسانی که تجربه کافی در زمینه طراحی شیگرا نداشته باشند، وقت زیادی را در طراحی از دست میدهند؛ زیرا به دنبال این هستند که چه طرحی خوب و چه طرحی بد است و حتی بین کار مجبور میشوند طراحی را از اول شروع کنند. بهترین راه حل برای این مشکل، استفاده از تجربه دیگران یا الگوهای طراحی است.
به مسائلی که به بهترین شکل حل شده و با تعریف خاصی ارائه شده باشند، الگوی طراحی (Design Patterns) میگوییم. این الگوها یا راه حلها، مواردی هستند که میتوانیم از آنها برای حل مشکلات مشابه استفاده کنیم. هدف از مطالعه الگوهای طراحی، افزایش کارایی در فرایند تولید نرمافزار است. در این مقاله با ارائه مثالهایی از دنیای واقعی، کاربرد عملی الگوها و مزیت استفاده از آنها را بررسی میکنیم.
مقدمهای بر الگوهای طراحی (دیزاین پترن Design Patterns)
«طراحی برنامههای شیگرا به خودی خود سخت، و طراحی برنامههای شیگرایی که قابل استفاده مجدد باشند، از آن هم سختتر است.»
روشی که طراحان خبره برای حل یک مسئله به کار میبرند، این است که هر مسئلهای را با استفاده از اصول اولیه حل نکنند و در عوض از راه حلهایی که در گذشته برایشان مفید بوده است، استفاده کنند. آنها هنگامی که یک راه حل خوب پیدا کردند، آن را دوباره و چندباره مورد استفاده قرار میدهند. در نتیجه این عمل، به الگوهای تکراری بین کلاسها و ارتباطات در سیستمهای شیگرا میرسند. هر الگو یک مشکل خاص را در طراحی نرمافزار حل میکند و باعث میشود که طراحی شیگرای ما انعطافپذیرتر، زیباتر و در نهایت، قابل استفاده مجدد باشد.
منظور از الگوهای طراحی چیست؟
الگو، یک راه حل اثبات شده انتزاعی است که برای حل مشکل ویژهای ایجاد شده است؛ مشکلی که بارها و بارها به شکلهای گوناگون و در پروژههای مختلف رخ داده است. نکته مهم این است که الگوهای طراحی نتیجه تجربیات یک یا چند نفر نیستند؛ بلکه از تجربیات صدها برنامهنویس و طراح حرفهای، در طول سالها برنامهنویسی به دست آمدهاند.
همچنین الگوها چیزی نیستند که از اول ایجاد یا اختراع شده باشد، بلکه بازتاب طراحیها و کدنویسیهای مکرری هستند که برنامهنویسان برای کسب بیشترین انعطافپذیری، توسعهپذیری و قابلیت استفاده مجدد، با آنها درگیری داشتهاند. الگوهای طراحی، نمودی خلاصه و عملی از راه حلهایی هستند که برنامهنویسان از تجربیات موفق خود به دست آوردهاند.
چرا باید از الگوهای طراحی استفاده کنیم؟
الگوهای طراحی، استفاده مجدد از طرحها و معماریهای موفق را آسانتر میکنند و بیان کردن تکنیکهای اثباتشده و کارا به صورت الگوهای طراحی، آنها را برای برنامهنویسان سیستمهای جدید بسیار قابل دسترستر میکند. این الگوها به شما کمک میکنند تا از بین انتخابهای موجود، طرحهایی را به کار بگیرید که قابلیت استفاده مجدد از سیستم را بالا میبرند و از انتخاب طرحهایی که قابلیت استفاده مجدد را کاهش میدهند، جلوگیری میکنند. به زبان ساده، الگوهای طراحی به طراح کمک میکنند تا طرح درست را سریعتر پیدا کند. هر الگو مسئلهای را شرح میدهد که در محیط ما به طور مکرر رخ داده و سپس راه حل اصلی مسئله را بیان میکند.
تاریخچه دیزاین پترن (Design Pattern)
مفهوم الگو چیزی نیست که فقط در دنیای نرمافزار کاربردی باشد، بلکه در سایر زمینههای علمی هم استفاده شده و میشود. در واقع، اولین بار یک معمار به نام کریستوفر الکساندر (Christopher Alexander) بود که در سال ۱۹۷۰، ایده الگو را برای ایجاد مجموعهای از واژگان مشترک (یک زبان مشترک) در مبحث طراحی ساختمان و معماری معرفی کرد.
کریستوفر الکساندر میگوید:
«هر الگو، مسئلهای را که در پیرامون ما بارها و بارها اتفاق میافتد، تشریح میکند و سپس راه حل اساسی آن را به صورتی بیان میکند که میتوانید آن را میلیونها بار به کار برید؛ بدون آن که حتی دو نمونه از نتایج شبیه هم باشد».
هرچند الکساندر در مورد الگوهای ساختمانی صحبت کرده، اما ایده او درباره الگوهای طراحی شیگرا هم صادق است.
در معماری و طراحی نرمافزار مسائل به صورت اشیا، و روابط بین آنها به جای دیوارها و درها تعریف شده است؛ اما در هر دو مبحث الگو، راه حلی برای یک مسئله در یک بستر تعریفشده، است. با وجود اینکه الگوهای طراحی، دستاورد تجربیات برنامهنویسهای بیشماری هستند، در سال ۱۹۹۴ برای اولین بار مجموعهای از مشهورترین الگوها در کتابی به عنوان Design Patterns : Elements of Reusable Object Oriented Software جمعآوری شد که تقریبا به عنوان انجیل الگوهای طراحی شناخته میشود.
این کتاب توسط چهار نفر به نامهای اریک گاما (Erich Gamma)، ریچارد هلم (Richard Helm)، رالف جانسون (Ralph Johnson) و جان ولیسیدس (John Vlissides) نوشته شد که به (Gang of Four (GOF معروف هستند. آنها در این کتاب، ایده استفاده از الگوها را در طراحی نرمافزار توضیح دادند و یک ساختار استاندارد برای مستندسازی الگوها ایجاد کردند.
عناصر الگوهای طراحی
به طور کلی یک الگو دارای چهار عنصر اساسی است:
- نام الگو: سمبلی است که میتوانیم برای ارجاع به یک مسئله طراحی، راه حل و دستاوردهایش، در یک الی دو کلمه به کار بریم.
- مسئله: تعیین میکند که یک الگو تحت چه شرایطی میتواند به کار برود و محل بحث و بستر آن را مشخص میکند. گاهی اوقات مسئله شامل فهرستی از شرایطی است که باید قبل از به کارگیری الگو فراهم شوند.
- راه حل: عناصری که طرح را میسازد و همچنین ارتباطات، وظایف و همکاریها را تشریح میکند.
- دستاورد: نتایج، مزایا و معایب به کارگیری الگو را مشخص میکند.
الگوهای طراحی مزایای زیادی دارند؛ اما فقط با شناخت الگوها نمیتوانیم هر مشکلی را حل کنیم. راه درست استفاده از الگوها این است که ابتدا مشکل خود را به خوبی بشناسیم، سپس بررسی کنیم که راه حل از پیش آمادهای برای آن وجود دارد یا خیر. بهتر است بدانید که همیشه و همه جا مجبور به استفاده از الگوها نیستیم. اگر با مشکل سادهای برخورد کردیم، نیازی نیست به هر نحوی یک الگو را با آن مطابقت دهیم. با این کار تنها کد خود را پیچیده میکنیم. در واقع همان گونه که الگوها میتوانند مشکلات پیچیده را ساده کنند، میتوانند مشکلات ساده را نیز پیچیده کنند.
همچنین نوع کاربرد الگوها با یکدیگر متفاوت است و لزوما نیازی به استفاده از همه الگوها در یک پروژه نیست. استفاده از الگوها، به صورت مسئله و مشکلات پروژه بستگی دارد و کاربرد هر الگو با دیگری متفاوت است.
الگوهای طراحی (Design Pattern) چه مزایایی دارند؟
استفاده از الگوها، باعث میشود طراحی سادهتر، ساختار به دست آمده انعطافپذیرتر و قابلیت استفاده مجدد بیشتری داشته باشد. کسی که الگوهای طراحی را بشناسد، میتواند بدون نیاز به کشف دوباره راه حلها، بیدرنگ آنها را برای مشکلات مختلف به کار ببرد، ضمانت و اعتماد طراحی خود را افزایش دهد و در وقت، هزینه و انرژی خود صرفهجویی کند. الگوها حتی در بهبود توصیف، مستندسازی و نگهداری از سیستمها هم موثر هستند.
در برخورد با مشکلات پیچیده، الگوها میتوانند نقش پررنگی داشته باشند و طراحی درست و پایبندی به اصول شیگرایی را ترویج دهند؛ چرا که خود الگوها بر اساس اصول طراحی شیگرا ابداع شدهاند.
بنابراین به طور خلاصه میتوانیم موارد زیر را به عنوان مزایای استفاده از الگوها بیان کنیم:
- طراحی بهتر
- کدنویسی زیباتر
- صرفهجویی در زمان و هزینه
- افزایش قابلیت استفاده مجدد
- افزایش اطمینان و ضمانت طراحی
- کاهش هزینه نگهداری و توسعه
- افزایش شیگرایی
- به دست آوردن یک زبان مشترک و قابل فهم برای طراحی
انواع الگوهای طراحی Design Pattern
در کتاب GOF: design patterns تعداد ۲۳ الگو در سه دستهبندی معرفی شدهاند. در ادامه نگاهی کوتاه به این الگوها خواهیم داشت. البته بعد از این کتاب الگوهای دیگری هم مانند Multiton ایجاد شدند که آنها را هم میتوان در یکی از این دستهها قرار داد.
الگوهای ایجادی یا آفرینشی (Creational Pattern)
این الگوها به ساخت اشیا و ارجاع به آنها میپردازند و با انتزاعی کردن روند نمونهسازی از کلاسها، مسئولیت این کار را خودشان بر عهده میگیرند؛ یعنی دیگر نیازی نیست کلاینت، خودش به طور صریح از یک کلاس نمونهسازی کند. الگوهای آفرینشی، اتصال بین کلاسها را ضعیف میکنند و اتصالهای سست (Loose-coupling) را افزایش میدهند. هدف الگوهای ایجادی این است که یک سیستم را از چگونگی ساخت، تشکیل و ارائه اشیاء جدا کنند. این الگوها انعطافپذیری سیستم را از نظر اینکه چه کسی، چگونه و چه هنگام شی را ایجاد میکند، افزایش میدهند.
الگوهای ایجادی، دانش این که چه کلاسهایی توسط سیستم استفاده میشود را کپسوله و جزئیات نمونهسازی از آنها را پنهان میکنند. اهداف کلی این الگوها به شرح زیر است:
- تسریع نمونهسازی از کلاسهای سنگین (Prototype)
- متمرکز کردن نمونهسازی از کلاسهای هم شکل (Factory Method)
- ایجاد کلاسی که باید تنها یک نمونه داشته باشد (Singleton)
- متمرکز کردن نمونهسازی از مجموعهای از کلاسها، که میتوان آنها را در قالب دستههای هم شکل تقسیم کرد (Abstract Factory)
- جدا کردن یک شی از روند ساخت آن (Builder)
الگوهای ساختاری (Structural Pattern)
این الگوها بر روابط و تعامل بین اشیا و ترکیب شدن آنها با یکدیگر برای شکل دادن سازهها و اشیا پیچیدهتر، تمرکز دارند. الگوهای ساختاری میتوانند هنگام طراحی یک سیستم یا پس از آن، در حین نگهداری و توسعه استفاده شوند.
اهداف کلی الگوهای ساختاری به شرح زیر است:
- اضافه یا حذف کردن یک قابلیت به طور پویا به اشیا در زمان اجرا (Decorator)
- یکسانسازی واسط چندین کلاس مختلف مرتبط با هم (Composite)
- دسترسی غیر مستقیم به اشیا، از طریق اشیا واسطه و اعمال کنترل دسترسی (Proxy)
- جدا ساختن قسمت پیادهسازی از قسمت انتزاعی یک کلاس و امکان تغییر آنها به صورت مستقل (Bridge)
- فراهم کردن امکان استفاده از واسطهای ناهمگون (Adapter)
- کاهش مصرف منابع با فاکتورگیری از اشیا تکراری و استفاده از اشیا سبک وزن (Flyweight)
- سادهسازی و خلاصهسازی چندین زیرسیستم بزرگ در قالب یک لایه سادهتر (Facade)
الگوهای رفتاری (Behavioral Pattern)
همان طور که اشاره کردیم، نقطه تمرکز الگوهای ایجادی و ساختاری ایجاد اشیا است؛ اما الگوهای رفتاری به جنبهای دیگر میپردازند. در این الگوها به الگوریتمها، مبادله اطلاعات و رفتار کلاسها توجه میشود. هدف این الگوها پاسخگویی به سناریوهای رایجی است که در آنها بتوان رفتار یک کلاس را بر اساس یک الگو تعریف کرد. الگوهای رفتاری نحوه تقسیم عملیات بین کلاسها را تعریف میکنند و چگونگی ارتباط بین آنها را بهبود میدهند.
اهداف کلی الگوهای رفتاری به شرح زیر است:
- قابلیت استخدام چند الگوریتم برای انجام یک کار مشخص (Strategy)
- فراهم کردن رفتار پویا برای یک شی با وجود ثابت بودن واسط آن (State)
- توانایی دخل و تصرف در بعضی از مراحل اجرای یک الگوریتم مشخص (Template Method)
- فاصله انداختن بین درخواستدهنده و کسی که درخواست را اجابت میکند، با ایجاد زنجیرهای از پاسخدهندهها با وظایف و مسئولیتهای مختلف (Chain of Responsibility)
- نگهداری سابقه فرمانهای اجرا شده در برنامه به منظور فراهم کردن قابلیت بازگشت فرمان (Redo and Undo Command)
- مهیا کردن قابلیت تکرار و شمارش برای اشیایی که از مجموعهای از آیتمها تشکیل میشوند (Iterator)
- متمرکز کردن منطق داخلی یک مولفهی بزرگ در قالب یک شی مرکزی (Mediator)
- توانایی آگاه کردن تعدادی از اشیا از تغییرات یک شی دیگر (Observer)
- اجرای یک عملیات بر روی مجموعهای از اشیا ناهمگون (Visitor)
- ایجاد مدلی ساده برای نمایش شیگرایی جملات یک زبان (Interpreter)
- حفظ وضعیت یک شی در یک منبع خارجی به منظور بازیابی وضعیت شی در آینده (Memento)
جمعبندی
الگوی طراحی یک مکانیزم برای بیان تجربه در طراحی شیگرا است؛ راه حل مناسبی که توسط افراد خبره برای یک نوع مشکل ایجاد شده است و میتواند بارها و بارها مورد استفاده قرار بگیرد. توسعهدهندگان برای حل مشکلات مختلف میتوانند از این الگوها، که توسط افراد خبره طراحی شدهاند، استفاده کنند.
الگوهای طراحی نتیجه تجربیات یک برنامهنویس نیستند و میتوان آنها را خلاصه تجربیات موفق برنامهنویسها در زبانهای مختلف دانست. استفاده از این الگوها باعث میشود که طراحی به دست آمده، ساده و انعطافپذیر باشد و قابلیت باز استفاده بیشتری داشته باشد.
دیدگاهتان را بنویسید