پــــــل (Bridge)
هـــدف
الگوی طراحی پل یک الگوی طراحی ساختاری است که به شما امکان میدهد یک کلاس بزرگ یا مجموعهای از کلاسهای نزدیک به هم را به دو سلسله مراتب جداگانه – انتزاع و پیادهسازی – تقسیم کنید که میتوانند به طور مستقل از یکدیگر توسعه یابند.
مـسئـــلـه
ترجمه:
انتزاع؟ پیادهسازی؟ ترسناک به نظر میرسد؟ آرام باشید و بیایید یک مثال ساده را در نظر بگیریم.
فرض کنید یک کلاس هندسی شکل با یک جفت زیر کلاس دارید: دایره و مربع. میخواهید این سلسله مراتب کلاس را برای گنجاندن رنگها گسترش دهید، بنابراین قصد دارید زیر کلاسهای شکل قرمز و آبی ایجاد کنید. با این حال، از آنجایی که از قبل دو زیر کلاس دارید، باید چهار ترکیب کلاس مانند دایره آبی و مربع قرمز ایجاد کنید.
افزودن انواع جدید شکل و رنگ به سلسله مراتب آن را به صورت نمایی رشد میدهد. به عنوان مثال، برای افزودن یک شکل مثلث، باید دو زیر کلاس معرفی کنید، یکی برای هر رنگ. و پس از آن، افزودن یک رنگ جدید نیاز به ایجاد سه زیر کلاس دارد، یکی برای هر نوع شکل. هر چه بیشتر پیش برویم، بدتر میشود.
راهــکــــار
این مشکل به دلیل تلاش ما برای گسترش کلاسهای شکل در دو بعد مستقل: شکل و رنگ رخ میدهد. این یک مشکل بسیار رایج در وراثت کلاس است.
الگوی پل تلاش میکند این مشکل را با تغییر از وراثت به ترکیب شی حل کند. این بدان معنی است که شما یکی از ابعاد را به یک سلسله مراتب کلاس جداگانه استخراج میکنید، به طوری که کلاسهای اصلی به جای داشتن تمام حالت و رفتار خود در یک کلاس، به یک شی از سلسله مراتب جدید ارجاع میدهند.
با پیروی از این رویکرد، میتوانیم کد مربوط به رنگ را در کلاس جداگانهای با دو زیر کلاس: قرمز و آبی استخراج کنیم. کلاس شکل سپس یک فیلد مرجع به یکی از اشیاء رنگ دارد. اکنون شکل میتواند هر کار مرتبط با رنگ را به شیء رنگ مرتبط واگذار کند. این مرجع به عنوان پلی بین کلاسهای شکل و رنگ عمل میکند. از این پس، افزودن رنگهای جدید نیاز به تغییر سلسله مراتب شکل نخواهد داشت و بالعکس.
انـــتــزاع و پـــیـــاده ســـازی
کتاب گنگافف اصطلاحات انتزاع و پیادهسازی را به عنوان بخشی از تعریف پل معرفی میکند. به نظر من، این اصطلاحات بیش از حد آکادمیک هستند و الگو را پیچیدهتر از آنچه واقعا هست نشان میدهند. با خواندن مثال ساده با شکلها و رنگها، بیایید معنای پشت کلمات ترسناک کتاب گنگافف را رمزگشایی کنیم.
انتزاع (یا رابط) یک لایه کنترل سطح بالا برای برخی موجودیتها است. انتظار نمیرود این لایه کار واقعی را خودش انجام دهد. باید کار را به لایه پیادهسازی (یا پلتفرم) واگذار کند.
توجه داشته باشید که ما در مورد رابطها یا کلاسهای انتزاعی از زبان برنامهنویسی خود صحبت نمیکنیم. اینها چیزهای یکسانی نیستند.
هنگام صحبت در مورد برنامههای واقعی، انتزاع میتواند توسط یک رابط کاربری گرافیکی (GUI) نمایش داده شود و پیادهسازی میتواند کد سیستم عامل زیرین (API) باشد که لایه GUI در پاسخ به تعاملات کاربر آن را فراخوانی میکند.
به طور کلی، میتوانید چنین برنامهای را در دو جهت مستقل گسترش دهید:
- داشتن چندین رابط کاربری متفاوت (برای مثال، برای مشتریان عادی یا مدیران)
- پشتیبانی از چندین API متفاوت (برای مثال، برای توانایی راهاندازی برنامه در ویندوز، لینوکس و macOS)
در بدترین حالت، این برنامه ممکن است شبیه یک کاسه اسپاگتی غولپیکر باشد، جایی که صدها شرط مختلف انواع مختلف GUI را با APIهای مختلف در سراسر کد متصل میکنند.
میتوانید با استخراج کد مربوط به ترکیبهای خاص رابط-پلتفرم به کلاسهای جداگانه، نظم را به این آشفتگی بیاورید. با این حال، به زودی متوجه خواهید شد که تعداد زیادی از این کلاسها وجود دارد. سلسله مراتب کلاس به صورت نمایی رشد خواهد کرد زیرا افزودن یک GUI جدید یا پشتیبانی از یک API متفاوت نیاز به ایجاد کلاسهای بیشتر و بیشتری دارد.
بیایید سعی کنیم این مشکل را با الگوی پل حل کنیم. این الگو پیشنهاد میکند که کلاسها را به دو سلسله مراتب تقسیم کنیم:
- انتزاع: لایه رابط کاربری برنامه
- پیادهسازی: APIهای سیستم عاملها
شیء انتزاعی ظاهر برنامه را کنترل میکند و کار واقعی را به شی پیادهسازی مرتبط واگذار میکند. پیادهسازیهای مختلف قابل تعویض هستند تا زمانی که از یک رابط مشترک پیروی کنند، که امکان استفاده از همان GUI در ویندوز و لینوکس را فراهم میکند.
در نتیجه، میتوانید کلاسهای GUI را بدون دست زدن به کلاسهای مرتبط با API تغییر دهید. علاوه بر این، افزودن پشتیبانی برای سیستم عامل دیگر فقط نیاز به ایجاد یک زیر کلاس در سلسله مراتب پیادهسازی دارد.
ســاخــتـــار