الگوی پل چیست؟
الگوی پل یک الگوی طراحی سازه است. به عبارت دیگر، کار اصلی آن ایجاد یک ساختار تمام عیار از کلاس ها و اشیاء است. یک پل این کار را با تقسیم یک یا چند کلاس به سلسله مراتب جداگانه انجام می دهد: انتزاع و پیاده سازی . تغییر در عملکرد در یک سلسله مراتب مستلزم تغییر در سلسله مراتب دیگر نیست. این همه خوب و خوب است، اما این تعریف بسیار گسترده است و به مهمترین سوال پاسخ نمی دهد: "الگوی پل چیست؟" من فکر می کنم درک کاربرد عملی آن برای شما آسان تر خواهد بود. بنابراین بلافاصله، بیایید یک سناریوی کلاسیک برای الگوی پل ایجاد کنیم. ما یک کلاس انتزاعی داریمShape
که یک شکل هندسی عمومی را نشان می دهد:
-
Shape.java
public abstract class Shape { public abstract void draw(); }
وقتی تصمیم می گیریم اشکالی مانند مثلث و مستطیل را اضافه کنیم، آنها را به ارث بردن کلاس تبدیل می کنیم
Shape
: -
Rectangle.java:
public class Rectangle extends Shape { @Override public void draw() { System.out.println("Drawing rectangle"); } }
-
Triangle.java:
public class Triangle extends Shape { @Override public void draw() { System.out.println("Drawing triangle"); } }
draw()
به این رنگ بستگی دارد. برای اینکه پیاده سازی های متفاوتی از draw()
متد داشته باشیم، باید برای هر ترکیب شکل و رنگ یک کلاس ایجاد کنیم. اگر سه رنگ داشته باشیم، به شش کلاس نیاز داریم: TriangleBlack
, TriangleGreen
, TriangleRed
, و . شش کلاس مشکل بزرگی نیست. ولی! اگر نیاز به اضافه کردن یک شکل یا رنگ جدید داشته باشیم، تعداد کلاس ها به صورت تصاعدی افزایش می یابد. چگونه از این وضعیت خارج شویم؟ ذخیره رنگ در یک فیلد و برشمردن تمام گزینه ها با استفاده از دستورات شرطی بهترین راه حل نیست. یک راه حل خوب این است که رنگ را به یک رابط جداگانه منتقل کنید . زودتر گفته شد: بیایید یک رابط با سه پیاده سازی ایجاد کنیم: و :RectangleBlack
RectangleGreen
RectangleRed
Color
BlackColor
GreenColor
RedColor
-
Color.java:
public interface Color { void fillColor(); }
-
BlackColor.java:
public class BlackColor implements Color { @Override public void fillColor() { System.out.println("Filling in black color"); } }
-
GreenColor.java
public class GreenColor implements Color { @Override public void fillColor() { System.out.println("Filling in green color"); } }
-
RedColor.java
public class RedColor implements Color { @Override public void fillColor() { System.out.println("Filling in red color"); } }
حالا یک
Color
فیلد بهShape
کلاس اضافه می کنیم. مقدار آن را در سازنده می گیریم. -
Shape.java:
public abstract class Shape { protected Color color; public Shape(Color color) { this.color = color; } public abstract void draw(); }
color
از متغیر در پیاده سازی ها استفاده خواهیم کردShape
. این بدان معناست که اکنون اشکال می توانند از عملکردColor
رابط استفاده کنند. -
Rectangle.java
public class Rectangle extends Shape { public Rectangle(Color color) { super(color); } @Override public void draw() { System.out.println("Drawing rectangle"); color.fillColor(); } }
Color color
پلی است که دو سلسله مراتب کلاس جداگانه را به هم متصل می کند.
نحوه ساخت پل: انتزاع و اجرا
بیایید به نمودار کلاسی نگاه کنیم که الگوی پل را به تصویر میکشد:
- انتزاع
Shape
کلاس است - RefinedAbstraction کلاس های
Triangle
و استRectangle
Color
پیاده کننده رابط است- ConcreteImplementor کلاس ها و
BlackColor
است .GreenColor
RedColor
Shape
یک انتزاع است - مکانیزمی برای مدیریت پر کردن اشکال با رنگ های مختلف، که به Color
رابط (Implementor) واگذار می شود. کلاسها Triangle
و Rectangle
کلاسهای مشخصی هستند که از مکانیسمی استفاده میکنند که توسط Shape
کلاس در دسترس است. BlackColor
، GreenColor
و RedColor
پیاده سازی های مشخص در سلسله مراتب پیاده سازی هستند.
کجا از الگوی پل استفاده کنیم
مزیت بزرگ استفاده از این الگو این است که میتوانید در یک سلسلهمراتب تغییراتی در کلاسهای تابعی ایجاد کنید بدون اینکه منطق دیگری را زیر پا بگذارید. همچنین، این رویکرد به کاهش جفت بین کلاس ها کمک می کند. نیاز اصلی هنگام استفاده از این الگو این است که "دستورالعمل ها را دنبال کنید" - هیچ یک از آنها را نادیده نگیرید! برای این منظور، بیایید موقعیتهایی را که قطعاً باید از الگوی پل استفاده کنید، دریابیم:-
اگر نیاز دارید تعداد موجودات را بر اساس ترکیب دو مفهوم (مثلاً اشکال و رنگ) گسترش دهید.
-
اگر می خواهید یک کلاس بزرگ را که با اصل مسئولیت تکی مطابقت ندارد به کلاس های کوچکتر که عملکرد محدودی دارند تقسیم کنید.
-
اگر لازم باشد در حین اجرای برنامه تغییراتی در منطق موجودیت های خاص ایجاد شود.
-
اگر لازم است یک پیاده سازی از مشتریان کلاس یا کتابخانه پنهان شود.
جوانب مثبت و منفی الگو
مانند دیگر الگوها، پل هم مزایا و هم معایب دارد. مزایای الگوی پل:- این مقیاسپذیری کد را بهبود میبخشد - میتوانید بدون ترس از شکستن چیزی در قسمت دیگری از برنامه عملکردی را اضافه کنید.
- در صورتی که تعداد موجودیت ها بر اساس ترکیبی از دو مفهوم (مثلاً اشکال و رنگ) باشد، تعداد زیر کلاس ها را کاهش می دهد.
- این امکان را فراهم می کند که به طور جداگانه روی دو سلسله مراتب جداگانه کار کنید - Abstraction و Implementation. دو توسعهدهنده مختلف میتوانند بدون پرداختن به جزئیات کد یکدیگر تغییراتی را ایجاد کنند.
- جفت شدن بین کلاس ها را کاهش می دهد - تنها جایی که این دو کلاس در آن جفت می شوند، پل (یعنی میدان
Color color
) است.
- بسته به موقعیت خاص و ساختار کلی یک پروژه، می تواند بر عملکرد یک برنامه تأثیر منفی بگذارد (به عنوان مثال، اگر نیاز به مقداردهی اولیه اشیاء دارید).
- به دلیل نیاز به جابجایی بین دو کلاس، کد را کمتر خوانا می کند.
GO TO FULL VERSION