من اینجا هستم تا بحث پیرامون الگوهای طراحی را ادامه دهم . قبل از شروع با قسمت 11، اجازه دهید ابتدا نگاهی به مقالات قبلی این مجموعه بیندازیم.
- الگوهای طراحی ساده شده: قسمت 1
- الگوهای طراحی ساده شده - قسمت 2 (Singleton)
- الگوهای طراحی ساده شده - قسمت 3 (کارخانه ساده)
- الگوهای طراحی ساده شده - قسمت 4 (کارخانه انتزاعی)
- الگوهای طراحی ساده شده - قسمت 5 (روش کارخانه)
- الگوهای طراحی ساده شده - قسمت 6 (نمونه اولیه)
- الگوهای طراحی ساده شده - قسمت 7 (سازنده)
- الگوهای طراحی ساده شده - قسمت 8 (نما)
- الگوهای طراحی ساده شده - قسمت 9 (آداپتور)
- الگوهای طراحی ساده شده - قسمت 10 (دکوراتور)
امروز یکی از الگوهای طراحی سازه به نام پل را مرور خواهیم کرد. قبل از صحبت در مورد اجرای آن، اجازه دهید با تعریف آن شروع کنیم.
مطابق با بچه های GOF، الگوی پل به صورت زیر تعریف می شود.
" یک انتزاع را از اجرای آن جدا کنید تا این دو بتوانند به طور مستقل متفاوت باشند ."
خوب! بیایید منظور آنها را درک کنیم و این الگو در کجا قرار می گیرد.
در شرایطی که بیش از یک نسخه از روشهای انتزاعی و همچنین راههای زیادی برای پیادهسازی آنها وجود دارد، ارائه کلاسهای انضمامی جدید از هر نسخه انتزاعی ممکن است به کلاسهای زیادی ختم شود. الگوی پل با معرفی یک رابط که به عنوان پل بین کلاس های انتزاعی و واقعی عمل می کند، همین مشکل را حل می کند.
در زیر الگوی UML برای پل آمده است.
الگوی پل دارای چهار عنصر کلیدی است که در زیر آمده است.
- انتزاع - کلاس رو به مشتری. مرجع یک شی از نوع Implementor را نگه می دارد.
- RefinedAbstraction - کلاس Abstraction را گسترش می دهد تا چندین نسخه از متدهای انتزاعی داشته باشد.
- پیاده کننده یا پل - این رابط به عنوان پل بین کلاس های انتزاعی و کلاس های پیاده سازی واقعی عمل می کند.
- ConcreteImplementor -این کلاس رابط Implementor را پیاده سازی می کند.
الگوی پل چگونه کار می کند
این را با مثال ساده متوجه خواهیم شد.
بیایید سناریویی را فرض کنیم که شما چند نوع ایمیل برای ارسال دارید و راه های مختلفی برای انجام آن دارید و در عین حال، می خواهید انتخابی را به مشتری بدهید تا نوع خاص ایمیل و روش یا روش ارسال آن را انتخاب کند.
این مثال عالی است که در آن الگوی پل میتواند مناسب باشد زیرا امکان تغییر منبع (یا روشهای انتزاعی) و هدف (پیادهسازیهای واقعی) را میدهد.
بیایید تصویر را با ایجاد پل یا رابط Implementor شروع کنیم.
- ///<summary>
- /// The Bridge or Implementor interface
- ///</summary>
- public interface IEmailSender
- {
- void SendEmail(string subject, string body);
- }
و سپس کلاس انتزاعی که اشیاء و متدهای تجاری را مانند زیر تعریف می کند.
- ///<summary>
- /// The Abstraction class
- ///</summary>
- public abstract class Email
- {
- public IEmailSenderMessageSender
- {
- get;
- set;
- }
- public string Subject {
- get;
- set;
- }
- public string Body {
- get;
- set;
- }
- public abstract void Send();
- }
همانطور که می بینید کلاس Email مرجع IEmailSender را نگه می دارد تا بتواند Concreate Implementor مناسب را در زمان اجرا فراخوانی کند.
حال اجازه دهید کلاس های RefinedAbstraction را ایجاد کنیم که برای پشتیبانی از چندین نسخه از متدهای انتزاعی استفاده می شود. در اینجا ما دو نوع انتزاع داریم یعنی SystemEmail و UserEmail.
- ///<summary>
- /// The RefinedAbstraction class
- ///</summary>
- public class SystemEmail: Email
- {
- public override void Send()
- {
- string emailSubject = string.Format("Subject: {0} from System", Subject);
- string emailBody = string.Format("Email Body:\n{0}", Body);
- MessageSender.SendEmail(emailSubject, emailBody);
- }
- }
- ///<summary>
- /// The RefinedAbstraction class
- ///</summary>
- public class UserEmail: Email
- {
- publicoverridevoid Send()
- {
- stringemailSubject = string.Format("Subject: {0} from User", Subject);
- stringemailBody = string.Format("Email Body:\n{0}", Body);
- MessageSender.SendEmail(emailSubject, emailBody);
- }
- }