دیزاین پترن (Design pattern) یا الگوی طراحی چیست؟

04 دی 1402 - آخرین بروزرسانی: 05 دی 1402
طراحی نرم افزار
زمان تقریبی مطالعه: 12 دقیقه

دیزاین پترن (Design pattern) یا الگوی طراحی، راه حلی تکرار شونده و اثبات‌شده برای مشکلات رایج در طراحی و ساخت نرم‌افزار است. دیزاین پترن‌ها می‌توانند به دولوپرهای حرفه‌ای کمک کنند تا کدی با کیفیت بالا، قابل نگهداری و قابل توسعه ایجاد کنند.

دیزاین پترن‌ها در انواع مختلفی وجود دارند، از جمله دیزاین پترن سازنده یا Creational، دیزاین پترن ساختاری یا Structural و دیزاین پترن رفتاری یا Behavioral که در این بلاگ به شرح همه آنها می‌پردازیم.

استفاده از دیزاین پترن‌ مزایای زیادی مانند کاهش پیچیدگی کد، بهبود قابلیت نگهداری کد، افزایش کیفیت کد و… را به همراه دارد.

دیزاین پترن‌ها یا الگوهای طراحی راه‌حل‌های سطح طراحی برای مشکلات تکراری هستند که مهندسان نرم افزار اغلب با آن‌ها مواجه می شوند. دیزاین پترن، کد نیست. دیزاین پترن یا الگوی طراحی مانند توضیحی در مورد چگونگی مقابله با یک مشکلات و طراحی راه حل است. استفاده از دیزاین پترن بسیار کاربردی است، زیرا الگوی طراحی راه حل کاملاً آزمایش شده‌ای است که منجر به خوانایی بیشتر کد نهایی می‌شود. الگوهای طراحی اغلب برای زبان‌های برنامه‌نویسی شی گرا مانند جاوا ایجاد شده و مورد استفاده قرار می‌گیرند.

در این بلاگ، به بررسی انواع مختلف دیزاین پترن، کاربردهای آن‌ها و نحوه استفاده از آن‌ها می‌پردازیم. با ما همراه باشید.

 

انواع دیزاین پترن یا الگوی طراحی

در حال حاضر حدود 26 الگوی طراحی به وجود آمده است.

این 26 دیزاین پترن را می توان به 3 دسته‌بندی کلی طبقه‌بندی کرد.

  1. سازنده یا Creational: این الگوها برای نمونه‌سازی کلاس طراحی شده‌اند. آنها می‌توانند دیزاین پترن‌های ایجاد کلاس یا الگوهای طراحی ساخت آبجکت باشند.
  2. ساختاری یا Structural: این الگوها با توجه به ساختار و ترکیب کلاس طراحی می‌شوند. هدف اصلی بیشتر این الگوها افزایش عملکرد کلاس(های) درگیر بدون تغییر در ترکیب آن است.
  3. رفتاری یا Behavioral: این الگوها بسته به نحوه ارتباط یک کلاس با بقیه طراحی می‌شوند.

در ادامه به شرح این سه نوع دیزاین پترن می‌پردازیم.

 

مطلب پیشنهادی: پسوند زبان های برنامه نویسی

 

الگوی طراحی سازنده یا Creational

این الگوهای طراحی همه در مورد نمونه‌سازی کلاس هستند. این الگو را می توان بیشتر به الگوهای ایجاد کلاس و الگوهای ساخت آبجکت تقسیم کرد. در حالی که الگوهای ایجاد کلاس از وراثت به طور مؤثر در فرآیند نمونه‌سازی استفاده می‌کنند، الگوهای ساخت آبجکت به طور مؤثر از تفویض اختیار برای انجام کار استفاده می‌کنند.

الگوی طراحی Singleton یک الگوی خلاقانه است که هدف آن ایجاد تنها یک نمونه از یک کلاس و ارائه تنها یک نقطه دسترسی سراسری به آن شیء یا آبجکت است. یکی از نمونه های رایج چنین کلاسی در جاوا Calendar است که در آن شما نمی توانید نمونه‌ای از آن کلاس بسازید. همچنین از روش ()getInstance خود برای دریافت شیء مورد استفاده بهره می‌گیرد.

کلاسی که از الگوی طراحی Singleton استفاده می کند شامل موارد زیر می‌شود.

الگوی طراحی سازنده

  • یک متغیر استاتیک اختصاصی (private static variable) که تنها نمونه کلاس را در خود جای می‌دهد.
  • یک سازنده اختصاصی (private constructor)که نمی‌توان instance یا نمونه آن را در جای دیگری ساخت.
  • یک روش استاتیک عمومی (public static method)، برای برگرداندن یک instance از کلاس.

پیاده‌سازی‌های مختلفی از طراحی Singleton وجود دارد. سه نوع پیاده‌سازی مهم عبارتند از:

  1. نمونه سازی Eager
  2. نمونه سازی Lazy
  3. نمونه سازی Thread-safe

انواع الگوهای طراحی Creational

  • Abstract Factory

نمونه ای از چندین خانواده از کلاس‌ها ایجاد می‌کند.

  • Builder

ساخت شیء را از نمایش آن جدا می‌کند.

  • Factory Method

نمونه ای از چندین کلاس مشتق شده ایجاد می‌کند.

  • Object Pool

با بازیافت آبجکت‌هایی که دیگر مورد استفاده قرار نمی‌گیرند، از دستیابی و آزادسازی منابع گران قیمت خودداری می‌کند.

  • Prototype

یک نمونه کاملاً اولیه که باید کپی یا کلون شود.

  • Singleton

کلاسی که فقط یک نمونه از آن می تواند وجود داشته باشد.

کدنویسی

الگوی طراحی ساختاری یا Structural

الگوی طراحی دکوراتور یک نوع الگوی طراحی ساختاری است که به شما امکان می دهد رفتارهای جدیدی را به صورت پویا به آبجکت‌ها اضافه کنید بدون اینکه بر رفتار سایر آبجکت‌های هم کلاس تأثیر بگذارد. این با پیچاندن شیء اصلی در یک شیء دکوراتور (که این امر، کپسوله‌سازی نامیده می‌شود) عملکرد اضافی را فراهم می کند و اجرا می شود. این الگو اغلب برای ایجاد نرم‌افزارهای شیء گرا، انعطاف پذیر و قابل استفاده مجدد استفاده می‌شود.

در ادامه به یکی از انواع الگوهای طراحی ساختاری، الگوی طراحی دکوراتور، بیشتر می‌پردازیم.

 

مطلب پیشنهادی: برنامه نویسی اندروید بهتره یا طراحی سایت؟

 

ویژگی های کلیدی دیزاین پترن دکوراتور:

  • اصلاح رفتار پویا: الگوی طراحی دکوراتور به شما این امکان را می‌دهد که بدون تغییر کلاس اصلی آن، رفتارهایی را به یک شیء در زمان اجرا اضافه کرده یا تغییر دهید.
  • کپسوله‌سازی: انعطاف‌پذیری و محصورسازی کلاس‌ها را افزایش می‌دهد و به شما امکان می‌دهد رفتارهای جدیدی را بدون تغییر تعریف کلاس اصلی اضافه کنید.
  • Open/Closed Principle: با گسترش عملکرد کلاس‌های موجود بدون تغییر، به اصل Open-Closed پایبند است و آنها را برای گسترش بازتر و برای اصلاح بسته‌تر می‌کند.
  • کد قابل استفاده مجدد: با ایجاد کلاس‌های دکوراتور که می‌توانند با آبجکت‌های مختلف استفاده شوند، استفاده مجدد از کد را ترویج می‌کند و نیاز به کدهای تکراری را کاهش می‌دهد.

سناریوهای استفاده از الگوی طراحی دکوراتور:

افزودن گزارش یا حسابرسی به اشیاء موجود: می‌توانید آبجکت‌ها را با دکوراتورهای ورود به سیستم کپسوله سازی کنید تا تعاملات و رویدادهای آنها را ثبت کنید.

سفارشی کردن رفتارهای شیء: شما می‌توانید به صورت پویا رفتارهای خاصی را بر اساس شرایط زمان اجرا یا ترجیحات کاربر به آبجکت‌ها اعمال کنید.

افزایش ویژگی‌های شیء: می‌توانید ویژگی‌ها و عملکردهای اضافی را بدون تغییر کلاس‌های پایه آنها به آبجکت‌ها اضافه کنید.

اجرای الگوی دکوراتور:

رابط مشترک: یک رابط مشترک را هم برای شیء پایه و هم برای دکوراتورها تعریف کنید. این تضمین می کند که همه آبجکت‌ها را می توان به طور یکنواخت درمان کرد.

Object پایه: یک کلاس پایه انتزاعی یا یک رابط ایجاد کنید که عملکرد اصلی آبجکت‌ها را برای Decorated شدن نشان می‌دهد.

کلاس دکوراتور: کلاس‌های دکوراتور به هم چسبیده ایجاد کنید که از کلاس پایه به ارث می‌برند یا رابط را پیاده‌سازی می‌کنند. این کلاس ها رفتارهای اضافی را برای آبجکت‌هایی که دکور می‌کنند ارائه می‌دهند.

ترکیب دکوراتور: دکوراتورها می‌توانند دکوراتورهای دیگر یا شیء پایه را کپسوله کنند تا ترکیبی از رفتارها را ارائه دهند.

مزایای الگوی طراحی دکوراتور:

انعطاف پذیری: به صورت پویا رفتارهایی را به آبجکت‌ها اضافه یا حذف می‌کند بدون اینکه کلاس های پایه آنها را تغییر دهد.

قابلیت استفاده مجدد: کلاس های دکوراتور را می توان با آبجکت‌ها مختلف مورد استفاده مجدد قرار داد و استفاده مجدد از کد را ترویج می‌دهد.

طراحی چندپارچه‌ای (Modular): نگرانی‌ها را از هم جدا می‌کند و مدیریت سلسله مراتب آبجکت‌های پیچیده را آسان‌تر می‌کند.

قابلیت نگهداری: قابلیت نگهداری کد را با جداسازی تغییرات رفتاری در دکوراتورهای خاص بهبود می‌بخشد.

انطباق با اصول OOP: به اصل باز-بسته پایبند است و کپسوله‌سازی را ترویج می‌دهد.

 

مطلب پیشنهادی: تفاوت برنامه نویسی فرانت اند و بک اند

 

انواع دیزاین پترن‌های ساختاری

در مهندسی نرم افزار، الگوهای طراحی سازه، الگوهای طراحی هستند که با شناسایی یک راه ساده برای تحقق روابط بین موجودیت‌ها، طراحی را آسان می‌کنند.

  • آداپتور

رابط های کلاس‌های مختلف را مطابقت می‌دهد.

  • Bridge

رابط یک شیء را از پیاده‌سازی آن جدا می‌کند.

  • Composite

ساختار درختی از اشیاء ساده و مرکب ایجاد می‌کند.

  • Decorator

مسئولیت‌ها را به صورت پویا به اشیا اضافه می‌کند. (در بالا توضیحات بیشتری درباره الگوی طراحی دکوراتور داده‌ایم.)

  • Facade

یک کلاس واحد که یک زیرسیستم کامل را نشان می‌دهد.

  • Flyweight

یک نمونه ریز دانه که برای اشتراک گذاری کارآمد استفاده می‌شود.

  • Private Class Data

دسترسی Accessor/mutator را محدود می‌کند.

  • Proxy

شیءای که نمایانگر یک شیء دیگر است.

 

الگوی طراحی رفتاری یا Behavioral

این الگوهای طراحی همه در مورد ارتباطات آبجکت‌های کلاس هستند. الگوهای رفتاری آن دسته از الگوهایی هستند که به طور خاص به ارتباط بین آبجکت‌ها مربوط می‌شوند.

یک الگوی طراحی رفتاری بر نحوه ارتباط کلاس‌ها و آبجکت‌ها با یکدیگر تمرکز می‌کند. تمرکز اصلی الگوی طراحی Command القای درجه بالاتری از اتصال آزاد بین طرف‌های درگیر است.

جفت کردن (Coupling) روشی است که در آن دو (یا چند) کلاس که با یکدیگر تعامل دارند. سناریوی ایده آل در هنگام تعامل این کلاس‌ها این است که به شدت به یکدیگر وابسته نیستند. این کاپلینگ یا جفت کردن چندان قوی نیست (شل است). بنابراین، تعریف بهتری برای کاپلینگِ شل، کلاس هایی است که به هم پیوسته هستند و کمترین استفاده را از یکدیگر می کنند.

نیاز به این الگو زمانی ایجاد شد که درخواست‌ها بدون اینکه آگاهانه بدانند چه چیزی را می‌خواهید یا گیرنده کیست ارسال می‌شدند.

در این الگو، کلاس فراخوانی (invoking) از کلاسی که در واقع یک عمل را انجام می دهد جدا می شود. کلاس Invoker فقط دارای متد callable execute است که دستور لازم را زمانی که کلاینت درخواست می کند اجرا می‌کند.

بیایید یک مثال ساده در دنیای واقعی، مانند سفارش دادن یک وعده غذایی در یک رستوران شیک را در نظر بگیریم. همانطور که جریان پیش می رود، شما سفارش (کامند) خود را به پیشخدمت (invoker) می‌دهید، که سپس آن را به سرآشپز (receiver) می‌دهد تا بتوانید غذا دریافت کنید. ممکن است ساده به نظر برسد اما در کدنویسی کمی سخت است.

جریان عملیات در بخش فنی به این صورت است که شما یک کامند مشخص می‌سازید که رابط Command را پیاده سازی می‌کند و از گیرنده می خواهد که یک عمل را تکمیل کند و فرمان را به فراخوان ارسال کند. Invoker شخصی است که می داند چه زمانی این دستور را بدهد. سرآشپز تنها کسی است که می‌داند وقتی command یا سفارش خاصی داده می‌شود چه کاری انجام دهد. بنابراین، هنگامی که متد execute invoker اجرا می شود، به نوبه خود باعث می شود تا متد command objects’ execute روی receiver اجرا شود و در نتیجه اقدامات لازم انجام شود.

آنچه ما در این دیزاین پترن باید پیاده سازی کنیم این است؛

  • یک کامندِ اینترفیس (Interface Command)
  • یک کلاس Order که رابط Command را پیاده سازی می‌کند.
  • کلاسِ invoker
  • کلاسِ گیرنده (receiver)

کدنویسی

انواع دیزاین پترن‌های Behavioral

  • Chain of responsibility

راهی برای ارسال درخواست بین زنجیره‌ای از آبجکت‌ها.

  • Command

یک درخواست فرمان را به عنوان یک شیء کپسوله می‌کند.

  • Interpreter

راهی برای گنجاندن عناصر زبان در یک برنامه.

  • Iterator

به صورت متوالی به عناصر یک مجموعه دسترسی دارد.

  • Mediator

ارتباط ساده بین کلاس‌ها را تعریف می‌کند.

  • Memento

گرفتن و بازیابی حالت داخلی یک شیء.

  • Null Object

طراحی شده تا به عنوان مقدار پیش فرض یک شیء عمل کند.

  • Observer

راهی برای اطلاع رسانی تغییر به تعدادی از کلاس‌ها.

  • State

وقتی یک شیء تغییر می کند، رفتار آن را تغییر می‌دهد.

  • Strategy

یک الگوریتم را درون یک کلاس کپسوله می‌کند.

  • Template method

مراحل دقیق یک الگوریتم را به یک زیر کلاس موکول می‌کند.

  • Visitor

یک عملیات جدید را برای یک کلاس بدون تغییر تعریف می‌کند.

 

مطلب پیشنهادی: کاربردی ترین زبان های برنامه نویسی

 

مزایای دیزاین پترن‌ها

الگوهای طراحی یا دیزاین پترن‌ها راه حل های قابل استفاده مجدد برای مشکلات رایج در طراحی نرم افزار هستند. آنها یک فریمورک یا بلوپرینت کلی ارائه می‌کنند که می تواند برای حل یک کلاس وسیع از مشکلات طراحی استفاده شود.

در ادامه برخی از مزایای استفاده از الگوهای طراحی را شرح می‌دهیم:

قابلیت استفاده مجدد

دیزاین پترن‌های مختلف می توانند به شما کمک کنند تا از اختراع مجدد wheel جلوگیری کنید، آن هم با ارائه یک راه حل آزمایش شده برای یک مشکل رایج. این می تواند در زمان و انرژی شما صرفه جویی کند و به اطمینان از ثبات کد شما کمک کند.

ماژولار (Modular) یا چندپارچه‌ای بودن

الگوهای طراحی می توانند به شما کمک کنند تا کد خود را به قطعات کوچکتر و قابل مدیریت‌تر تقسیم کنید و درک، اصلاح و استفاده مجدد از آن را آسان‌تر می‌کند. این همچنین می تواند ماژولار بودن و قابلیت نگهداری کد شما را بهبود بخشد.

انعطاف‌پذیری

با کمک الگوهای طراحی می‌توانید کدی انعطاف‌پذیر و قابل تطبیق ایجاد کنید که به راحتی قابل گسترش و اصلاح باشد تا نیازهای متغیر را برآورده کند. این می تواند به بهبود طول عمر و مفید بودن کد شما کمک کند.

کارایی

با استفاده از الگوهای طراحی می توانید کد کارآمدتری بنویسید که درک و نگهداری آن آسان‌تر باشد. این می تواند در دراز مدت در زمان شما صرفه جویی کند.

ارتباطات

الگوهای طراحی می توانند با ارائه واژگان مشترک و درک چگونگی حل مشکلات رایج طراحی، به بهبود ارتباط بین دولوپرهای مختلف کمک کنند.

 

نمونه‌های استفاده از الگوهای طراحی

در اینجا چند نمونه خاص از نحوه استفاده از الگوهای طراحی برای حل مشکلات رایج آورده شده است:

  • الگوی استراتژی (The Strategy Pattern) را می توان برای تعریف خانواده ای از الگوریتم‌ها، کپسوله کردن هر یک و تبدیل آنها به یکدیگر استفاده کرد. این می تواند برای ایجاد کد انعطاف پذیر و قابل تطبیق استفاده شود که به راحتی در زمان اجرا قابل تغییر باشد.
  • الگوی آبزِروِر (The Observer Pattern) را می توان برای ایجاد روابط یک به چند بین آبجکت‌ها استفاده کرد، به طوری که وقتی یک شیء تغییر حالت می دهد، همه وابسته‌های آن به طور خودکار مطلع و به روز می شوند. این می تواند برای ایجاد سیستم‌های جدا شده و سست استفاده شود.
  • الگوی سینگلتون (The Singleton Pattern) می تواند برای محدود کردن نمونه‌سازی یک کلاس به یک شیء واحد استفاده شود. الگوی طراحی سینگلتون می تواند برای ایجاد آبجکت‌هایی که توسط چندین بخش از یک برنامه به اشتراک گذاشته شده اند مفید باشد.
  • از الگوی فکتوری (The Factory Pattern) می توان برای ایجاد آبجکت‌ها بدون تعیین کلاس مشخص آنها استفاده کرد. این می تواند برای جدا کردن ایجاد آبجکت‌ها از استفاده آنها استفاده شود.
  • الگوی آداپتِر (The Adapter Pattern) را می توان برای تبدیل رابط یک کلاس موجود به رابط متفاوتی که کلاینت (Client) انتظار دارد استفاده کرد. این می تواند برای یکپارچه سازی سیستم های قدیمی یا برای استفاده از اجزای خارجی مفید باشد.

به طور کلی، الگوهای طراحی می تواند ابزار ارزشمندی برای دولوپرهای نرم افزار با تمام سطوح تجربه باشد. آنها می توانند به بهبود کیفیت، قابلیت نگهداری و انعطاف پذیری کد شما کمک کنند و همکاری با سایر توسعه‌دهندگان را آسان تر کنند.

 

مطلب پیشنهادی: چگونه یک برنامه نویس موفق شویم؟

 

کاربردهای دیزاین پترن

دیزاین پترن‌ها می توانند روند کار دولوپر را با ارائه چارچوب‌های توسعه آزمایش شده و اثبات شده، سرعت بخشند. طراحی نرم‌افزار به صورت اصولی مستلزم در نظر گرفتن مسائلی است که ممکن است تا زمان پیاده سازی قابل مشاهده نباشند. استفاده مجدد از دیزاین پترن‌ها یا الگوهای طراحی کمک می‌کنند تا از مسائل ظریفی که می‌توانند باعث مشکلات عمده شوند جلوگیری کرده و خوانایی کد را برای کدنویسان و معماران آشنا با الگوها بهبود می‌بخشد.

اغلب، مردم فقط می‌دانند که چگونه می‌توانند از تکنیک‌های طراحی نرم‌افزار خاص مانند ساخت نرم افزار CRM، ساخت نرم‌افزار حسابداری و.. برای مشکلات و کاربری‌های خاص استفاده کنند. کاربرد این تکنیک‌ها برای طیف وسیع‌تری از مشکلات دشوار است. الگوهای طراحی راه‌حل‌های کلی مستند در فرمتی را ارائه می‌دهند که به جزئیات مرتبط با یک مشکل خاص نیاز ندارد.

علاوه بر این، دیزاین پترن به دولوپر یا توسعه‌دهنده‌ها اجازه می دهد تا با استفاده از نام‌های شناخته‌شده و کاملاً درک‌شده برای تعاملات نرم افزاری ارتباط برقرار کنند. دیزاین پترن‌های رایج را می توان در طول زمان بهبود بخشید، و آنها را قوی تر از دیزاین ادهاک (ad-hoc) می کند.

آیا این مطلب برای شما مفید بود؟
بلهخیر
نویسنده مطلب سوگند صادقی
من نویسنده محتوا به زبان های فارسی و انگلیسی هستم و به نوشتن، به ویژه درباره موضوعات جدید علاقه دارم.

دیدگاه شما

3 دیدگاه

  • امین آفاقی
    04 دی 1402

    قلم بسیار خوبی داری سوگند عزیز. مطلب جامع و کامل

    • سوگند صادقی
      04 دی 1402

      ممنون از نگاهتون💌

  • novid
    04 دی 1402

    این الگوها بیشتر در سبک برنامه‌نویسی Imperative یا زبان‌های Object-Oriented کاربرد دارند و خیلی در مورد سبک برنامه‌نویسی Declarative یا زبان‌های Functional به کار نمیان چون درصد بسیار زیادی از مشکلات زبان‌های شی‌گرا در زبان‌های تابعی وجود نداره که بخواهد کسی براش الگوی طراحی بنویسه