در پروژههای PHP و Laravel گاهی یک کلاس باید در چند بُعد مختلف توسعه پیدا کند.
برای مثال فرض کنید یک سیستم نمایش محتوا داریم که باید:
- چند نوع صفحه داشته باشد؛
- چند نوع خروجی تولید کند؛
- از HTML و JSON پشتیبانی کند؛
- در آینده خروجی XML یا Markdown نیز به آن اضافه شود.
اگر همه این تفاوتها را با Inheritance مدیریت کنیم، تعداد کلاسها بهسرعت افزایش پیدا میکند.
مثلاً ممکن است کلاسهایی مانند اینها ایجاد شوند:
HtmlSimplePage
JsonSimplePage
HtmlProductPage
JsonProductPage
HtmlArticlePage
JsonArticlePage
با اضافهشدن هر نوع صفحه یا خروجی، باید کلاسهای ترکیبی بیشتری ایجاد کنیم.
Bridge Pattern برای حل چنین مسئلهای طراحی شده است. این الگو یک ساختار بزرگ را به دو سلسلهمراتب مستقل تقسیم میکند:
- Abstraction
- Implementation
در این روش، Abstraction بهجای اینکه تمام جزئیات Implementation را در خود نگهداری کند، یک نمونه از Implementation را دریافت کرده و عملیات مربوط به آن را به این Object واگذار میکند. <Cite refs={["turn0search0","turn0search2"]} />
Bridge Pattern چیست؟
Bridge Pattern یک Structural Design Pattern است که به ما اجازه میدهد Abstraction را از Implementation جدا کنیم تا هرکدام بتوانند مستقل از دیگری توسعه پیدا کنند.
به زبان ساده:
> بهجای ساختن کلاسهای متعدد برای تمام ترکیبهای ممکن، دو بخش مستقل ایجاد میکنیم و آنها را از طریق Composition به یکدیگر متصل میکنیم.
ساختار کلی به این شکل است:
Abstraction
|
| has-a
v
Implementation
برای مثال:
Page
|
v
Renderer
در این مثال:
Pageمسئول منطق کلی صفحه است.Rendererمسئول نحوه نمایش صفحه است.HtmlRendererخروجی HTML تولید میکند.JsonRendererخروجی JSON تولید میکند.
بنابراین میتوانیم یک ProductPage را با HtmlRenderer یا JsonRenderer استفاده کنیم، بدون اینکه برای هر ترکیب کلاس جداگانه بسازیم.
مشکل اصلی که Bridge Pattern حل میکند
فرض کنید یک سیستم پرداخت داریم.
در این سیستم دو بُعد مستقل وجود دارد:
نوع پرداخت
- پرداخت عادی
- پرداخت اشتراکی
- پرداخت اقساطی
درگاه پرداخت
- زرینپال
- Stripe
- PayPal
اگر این دو بُعد را با Inheritance ترکیب کنیم، احتمالاً کلاسهایی مانند زیر خواهیم داشت:
NormalZarinpalPayment
NormalStripePayment
NormalPaypalPayment
SubscriptionZarinpalPayment
SubscriptionStripePayment
SubscriptionPaypalPayment
InstallmentZarinpalPayment
InstallmentStripePayment
InstallmentPaypalPayment
در این حالت، با اضافهشدن نوع جدید پرداخت یا درگاه جدید، تعداد کلاسها بیشتر میشود.
این مشکل را میتوان با Bridge Pattern حل کرد.
بهجای ساخت کلاسهای ترکیبی، دو سلسلهمراتب مستقل میسازیم:
Payment
├── NormalPayment
├── SubscriptionPayment
└── InstallmentPayment
PaymentGateway
├── ZarinpalGateway
├── StripeGateway
└── PaypalGateway
سپس هر نوع Payment به یک PaymentGateway متصل میشود.
مفهوم Abstraction در Bridge Pattern
Abstraction بخش سطح بالای سیستم است.
این بخش معمولاً منطق اصلی و قابلفهم برای Client را در اختیار قرار میدهد.
برای مثال:
abstract class Payment
{
public function __construct(
protected PaymentGateway $gateway
) {
}
abstract public function pay(int $amount): string;
}
در اینجا Payment یک Abstraction است.
این کلاس لازم نیست بداند پرداخت دقیقاً با چه سرویس یا API انجام میشود. فقط میداند که یک Gateway دارد و میتواند عملیات پرداخت را به آن واگذار کند.
مفهوم Implementation در Bridge Pattern
Implementation بخش پایینتر سیستم است که عملیات جزئی و فنی را انجام میدهد.
برای مثال:
interface PaymentGateway
{
public function charge(int $amount): string;
}
این Interface قرارداد مشترک تمام درگاههای پرداخت را مشخص میکند.
سپس درگاههای مختلف آن را پیادهسازی میکنند:
class ZarinpalGateway implements PaymentGateway
{
public function charge(int $amount): string
{
return "Payment through Zarinpal: {$amount}";
}
}
و:
class StripeGateway implements PaymentGateway
{
public function charge(int $amount): string
{
return "Payment through Stripe: {$amount}";
}
}
در این ساختار:
Paymentنقش Abstraction را دارد.PaymentGatewayنقش Implementation Interface را دارد.ZarinpalGatewayوStripeGatewayConcrete Implementation هستند.
ساختار کلی Bridge Pattern
ساختار رایج Bridge Pattern شامل بخشهای زیر است:
Abstraction
|
+── RefinedAbstraction
Implementation
|
+── ConcreteImplementationA
+── ConcreteImplementationB
Abstraction
رابط یا منطق سطح بالای سیستم را مشخص میکند.
Refined Abstraction
نسخههای تخصصیتر Abstraction را پیادهسازی میکند.
Implementation
قرارداد عملیات فنی را تعریف میکند.
Concrete Implementation
پیادهسازی واقعی عملیات را انجام میدهد.
در نمونههای استاندارد Bridge، Abstraction یک Reference از نوع Implementation نگهداری میکند و عملیات را به آن واگذار میکند. <Cite refs={["turn0search0","turn0search2"]} />
# پیادهسازی Bridge Pattern در PHP
برای درک بهتر، یک سیستم نمایش صفحه میسازیم.
در این مثال:
Pageمسئول ساختار صفحه است.Rendererمسئول نحوه خروجی گرفتن است.HtmlRendererخروجی HTML تولید میکند.JsonRendererخروجی JSON تولید میکند.
مرحله اول: ساخت Renderer Interface
ابتدا قرارداد Renderer را ایجاد میکنیم:
interface Renderer
{
public function renderTitle(string $title): string;
public function renderText(string $text): string;
public function renderImage(string $url): string;
public function renderPage(array $parts): string;
}
هر Renderer باید این متدها را پیادهسازی کند.
مرحله دوم: ساخت HtmlRenderer
حالا Renderer مربوط به HTML را میسازیم:
class HtmlRenderer implements Renderer
{
public function renderTitle(string $title): string
{
return "<h1>{$title}</h1>";
}
public function renderText(string $text): string
{
return "<p>{$text}</p>";
}
public function renderImage(string $url): string
{
return "<img src=\"{$url}\" alt=\"\">";
}
public function renderPage(array $parts): string
{
return implode("\n", $parts);
}
}
این کلاس فقط مسئول تولید HTML است.
مرحله سوم: ساخت JsonRenderer
حالا Renderer مربوط به JSON را ایجاد میکنیم:
class JsonRenderer implements Renderer
{
public function renderTitle(string $title): string
{
return json_encode([
'title' => $title,
], JSON_UNESCAPED_UNICODE);
}
public function renderText(string $text): string
{
return json_encode([
'text' => $text,
], JSON_UNESCAPED_UNICODE);
}
public function renderImage(string $url): string
{
return json_encode([
'image' => $url,
], JSON_UNESCAPED_UNICODE);
}
public function renderPage(array $parts): string
{
return json_encode(
$parts,
JSON_UNESCAPED_UNICODE
);
}
}
در یک پروژه واقعی بهتر است ساختار JSON از ابتدا به شکل مشخص و استاندارد طراحی شود، اما این مثال برای درک Bridge مناسب است.
مرحله چهارم: ساخت Abstraction اصلی
حالا کلاس Page را میسازیم:
abstract class Page
{
public function __construct(
protected Renderer $renderer
) {
}
public function changeRenderer(Renderer $renderer): void
{
$this->renderer = $renderer;
}
abstract public function view(): string;
}
نکته مهم این کلاس، وابستگی آن به Interface است:
protected Renderer $renderer;
بنابراین Page به HtmlRenderer یا JsonRenderer وابسته نیست؛ بلکه به قرارداد Renderer وابستگی دارد.
همچنین متد زیر اجازه میدهد Implementation در زمان اجرا تغییر کند:
public function changeRenderer(Renderer $renderer): void
مرحله پنجم: ساخت SimplePage
حالا یک نوع صفحه ساده ایجاد میکنیم:
class SimplePage extends Page
{
public function __construct(
Renderer $renderer,
private string $title,
private string $content
) {
parent::__construct($renderer);
}
public function view(): string
{
return $this->renderer->renderPage([
$this->renderer->renderTitle($this->title),
$this->renderer->renderText($this->content),
]);
}
}
این کلاس مسئول منطق صفحه است، اما نحوه خروجی گرفتن را به Renderer واگذار میکند.
مرحله ششم: ساخت ProductPage
میتوانیم نوع دیگری از صفحه را نیز ایجاد کنیم:
class ProductPage extends Page
{
public function __construct(
Renderer $renderer,
private string $title,
private string $description,
private string $image
) {
parent::__construct($renderer);
}
public function view(): string
{
return $this->renderer->renderPage([
$this->renderer->renderTitle($this->title),
$this->renderer->renderText($this->description),
$this->renderer->renderImage($this->image),
]);
}
}
حالا دو Abstraction داریم:
Page
├── SimplePage
└── ProductPage
و دو Implementation:
Renderer
├── HtmlRenderer
└── JsonRenderer
مرحله هفتم: استفاده از Bridge Pattern
حالا میتوانیم صفحه را با Rendererهای مختلف ترکیب کنیم:
$htmlRenderer = new HtmlRenderer();
$page = new SimplePage(
$htmlRenderer,
'صفحه اصلی',
'به سایت ما خوش آمدید'
);
echo $page->view();
خروجی:
<h1>صفحه اصلی</h1>
<p>به سایت ما خوش آمدید</p>
حالا همان صفحه را با JSON نمایش میدهیم:
$jsonRenderer = new JsonRenderer();
$page->changeRenderer($jsonRenderer);
echo $page->view();
در این حالت، بدون تغییر در کلاس SimplePage، خروجی آن تغییر میکند.
این دقیقاً همان هدف Bridge Pattern است: جداکردن منطق سطح بالا از جزئیات نحوه پیادهسازی.
# مثال کاربردیتر: Bridge Pattern در سیستم ارسال پیام
فرض کنید یک سیستم ارسال پیام داریم.
دو بُعد مستقل در این سیستم وجود دارد:
نوع پیام
- پیام اطلاعرسانی
- پیام تبلیغاتی
- پیام هشدار
سرویس ارسال
- SMS
- Telegram
اگر این دو بخش را با Inheritance ترکیب کنیم، تعداد زیادی کلاس خواهیم داشت.
اما با Bridge میتوانیم آنها را جدا کنیم.
ساخت MessageSender Interface
interface MessageSender
{
public function send(
string $recipient,
string $message
): bool;
}
پیادهسازی SMS
class SmsSender implements MessageSender
{
public function send(
string $recipient,
string $message
): bool {
echo "Sending SMS to {$recipient}: {$message}";
return true;
}
}
پیادهسازی Email
class EmailSender implements MessageSender
{
public function send(
string $recipient,
string $message
): bool {
echo "Sending Email to {$recipient}: {$message}";
return true;
}
}
ساخت Abstraction پیام
abstract class Message
{
public function __construct(
protected MessageSender $sender
) {
}
abstract public function send(
string $recipient
): bool;
}
ساخت NotificationMessage
class NotificationMessage extends Message
{
public function __construct(
MessageSender $sender,
private string $text
) {
parent::__construct($sender);
}
public function send(string $recipient): bool
{
return $this->sender->send(
$recipient,
$this->text
);
}
}
ساخت AlertMessage
class AlertMessage extends Message
{
public function __construct(
MessageSender $sender,
private string $text
) {
parent::__construct($sender);
}
public function send(string $recipient): bool
{
return $this->sender->send(
$recipient,
"ALERT: {$this->text}"
);
}
}
استفاده از سیستم پیام
$smsSender = new SmsSender();
$notification = new NotificationMessage(
$smsSender,
'سرویس شما تمدید شد'
);
$notification->send('09120000000');
حالا میتوانیم همان نوع پیام را با Email ارسال کنیم:
$emailSender = new EmailSender();
$notification = new NotificationMessage(
$emailSender,
'سرویس شما تمدید شد'
);
$notification->send('user@example.com');
همچنین:
$alert = new AlertMessage(
$smsSender,
'موجودی کیف پول شما کم است'
);
$alert->send('09120000000');
در این مثال، نوع پیام و سرویس ارسال از یکدیگر مستقل هستند.
# Bridge Pattern در Laravel
در Laravel میتوان از Bridge برای جداکردن منطق کسبوکار از سرویسهای زیرساختی استفاده کرد.
برای مثال در پروژهای که با چند سرویس پیامک کار میکند، میتوانیم Interface زیر را تعریف کنیم:
namespace App\Contracts;
interface SmsProvider
{
public function send(
string $mobile,
string $message
): bool;
}
سپس Providerهای مختلف را ایجاد کنیم:
namespace App\Services\Sms;
use App\Contracts\SmsProvider;
class MelipayamakProvider implements SmsProvider
{
public function send(
string $mobile,
string $message
): bool {
// ارسال پیامک با ملی پیامک
return true;
}
}
و:
namespace App\Services\Sms;
use App\Contracts\SmsProvider;
class KavenegarProvider implements SmsProvider
{
public function send(
string $mobile,
string $message
): bool {
// ارسال پیامک با کاوه نگار
return true;
}
}
حالا منطق سطح بالای پیام را جدا میکنیم:
namespace App\Services;
use App\Contracts\SmsProvider;
class ServiceNotification
{
public function __construct(
private SmsProvider $provider
) {
}
public function sendRenewalMessage(
string $mobile,
string $serviceName
): bool {
$message = "سرویس {$serviceName} با موفقیت تمدید شد.";
return $this->provider->send(
$mobile,
$message
);
}
}
در این ساختار:
ServiceNotificationنقش Abstraction را دارد.SmsProviderنقش Implementation Interface را دارد.- Providerهای پیامک، Concrete Implementation هستند.
با این روش، منطق تمدید سرویس به Provider خاصی وابسته نمیشود.
# اتصال Bridge به Service Container لاراول
میتوانیم Provider موردنظر را در Service Container ثبت کنیم:
use App\Contracts\SmsProvider;
use App\Services\Sms\KavenegarProvider;
$this->app->bind(
SmsProvider::class,
KavenegarProvider::class
);
سپس Laravel هنگام ساخت ServiceNotification، پیادهسازی مناسب را تزریق میکند.
در این حالت، اگر بعداً بخواهیم Provider را تغییر دهیم، لازم نیست منطق اصلی Notification را تغییر دهیم.
فقط Binding را عوض میکنیم:
$this->app->bind(
SmsProvider::class,
MelipayamakProvider::class
);
البته در پروژههای واقعی بهتر است تنظیم Provider از طریق فایل Config انجام شود تا تغییر سرویس بدون ویرایش چندین بخش از برنامه امکانپذیر باشد.
# تفاوت Bridge و Adapter Pattern
Bridge و Adapter از نظر ساختار ظاهری شباهت زیادی دارند، اما هدفشان متفاوت است.
Bridge
Bridge معمولاً از ابتدا برای جداکردن دو بُعد مستقل طراحی میشود.
مثلاً:
Page + Renderer
Payment + Gateway
Message + Sender
هدف این است که دو سلسلهمراتب مستقل باشند.
Adapter
Adapter معمولاً زمانی استفاده میشود که دو کلاس یا سرویس موجود Interface سازگاری ندارند و باید آنها را با یکدیگر هماهنگ کنیم.
به زبان ساده:
Bridge:
طراحی مستقل دو بخش از ابتدا
Adapter:
سازگارکردن دو بخش موجود
Refactoring.Guru نیز Bridge را بیشتر برای طراحی مستقل دو سلسلهمراتب و Adapter را برای سازگارکردن کلاسهای موجود معرفی میکند. <Cite refs={["turn0search2"]} />
# تفاوت Bridge و Strategy Pattern
Bridge و Strategy هر دو از Composition استفاده میکنند و در هر دو، یک کلاس به Object دیگری وابسته میشود.
اما هدف آنها متفاوت است.
Strategy
Strategy برای انتخاب یا تعویض الگوریتم استفاده میشود.
مثلاً:
PaymentStrategy
├── ZarinpalStrategy
├── StripeStrategy
└── PaypalStrategy
Bridge
Bridge برای جداکردن دو بُعد مستقل از یک ساختار بزرگتر استفاده میشود.
مثلاً:
PaymentType
+
PaymentGateway
در Strategy معمولاً تمرکز روی تعویض الگوریتم است، اما در Bridge تمرکز روی مستقلکردن دو سلسلهمراتب است.
ساختار Bridge و Strategy ممکن است شبیه باشند، اما مسئلهای که حل میکنند متفاوت است. <Cite refs={["turn0search2"]} />
# مزایای Bridge Pattern
1. کاهش تعداد Subclassها
بهجای ساخت کلاس برای تمام ترکیبها، دو سلسلهمراتب مستقل ایجاد میکنیم.
2. توسعه مستقل
میتوان Abstraction را بدون تغییر در Implementation توسعه داد و برعکس.
3. رعایت اصل Open/Closed
برای اضافهکردن نوع جدید، معمولاً کافی است کلاس جدیدی در یکی از سلسلهمراتب ایجاد کنیم.
4. کاهش وابستگی
Abstraction به Interface وابسته است، نه به یک پیادهسازی مشخص.
5. امکان تغییر Implementation در زمان اجرا
اگر طراحی اجازه دهد، میتوان Implementation را در زمان اجرا تغییر داد.
6. تستپذیری بهتر
در تستها میتوان یک Fake یا Mock از Implementation به Abstraction تزریق کرد.
# معایب Bridge Pattern
1. افزایش تعداد کلاسها
اگرچه تعداد کلاسهای ترکیبی کاهش پیدا میکند، اما ممکن است تعداد Interfaceها و کلاسهای مستقل بیشتر شود.
2. پیچیدگی اولیه
برای پروژههای کوچک، این ساختار ممکن است بیش از نیاز باشد.
3. نیاز به طراحی درست
اگر دو بُعد واقعاً مستقل نباشند، استفاده از Bridge میتواند ساختار را غیرضروری پیچیده کند.
4. دشواری برای افراد مبتدی
مفاهیمی مانند Abstraction، Implementation و Composition ممکن است در ابتدا کمی پیچیده باشند.
# چه زمانی از Bridge Pattern استفاده کنیم؟
Bridge معمولاً زمانی مناسب است که:
- یک کلاس در چند بُعد مستقل تغییر میکند؛
- تعداد Subclassها در حال افزایش است؛
- منطق سطح بالا نباید به سرویس خاصی وابسته باشد؛
- چند Provider یا Platform مختلف دارید؛
- باید Implementation در زمان اجرا تغییر کند؛
- میخواهید بخشهای مختلف سیستم مستقل تست و توسعه داده شوند.
مثالهای رایج عبارتاند از:
- چند نوع درگاه پرداخت؛
- چند سرویس پیامک؛
- چند نوع خروجی مانند HTML و JSON؛
- چند سرویس ذخیرهسازی؛
- چند Provider برای API؛
- چند نوع گزارشگیری؛
- چند نوع Renderer برای یک صفحه.
Bridge برای پشتیبانی از چند Platform یا Provider مختلف، مانند سرویسهای API یا پایگاه داده، کاربرد مناسبی دارد. <Cite refs={["turn0search0","turn0search2"]} />
# چه زمانی از Bridge استفاده نکنیم؟
اگر فقط یک نوع Implementation دارید و احتمال توسعه آن کم است، شاید Bridge لازم نباشد.
مثلاً:
class Report
{
public function generate(): string
{
return 'Report';
}
}
در این شرایط ساخت Interface و چند کلاس جداگانه ممکن است فقط پیچیدگی ایجاد کند.
همچنین اگر مسئله فقط انتخاب بین چند الگوریتم است، Strategy احتمالاً انتخاب سادهتر و واضحتری خواهد بود.
# تست Bridge Pattern با PHPUnit
برای تست میتوانیم یک Fake Renderer بسازیم:
class FakeRenderer implements Renderer
{
public function renderTitle(string $title): string
{
return "TITLE: {$title}";
}
public function renderText(string $text): string
{
return "TEXT: {$text}";
}
public function renderImage(string $url): string
{
return "IMAGE: {$url}";
}
public function renderPage(array $parts): string
{
return implode('|', $parts);
}
}
حالا تست میکنیم که SimplePage از Renderer استفاده میکند:
public function testSimplePageUsesRenderer(): void
{
$renderer = new FakeRenderer();
$page = new SimplePage(
$renderer,
'Home',
'Welcome'
);
$result = $page->view();
$this->assertSame(
'TITLE: Home|TEXT: Welcome',
$result
);
}
همچنین میتوان تغییر Renderer را تست کرد:
public function testRendererCanBeChanged(): void
{
$htmlRenderer = new HtmlRenderer();
$jsonRenderer = new JsonRenderer();
$page = new SimplePage(
$htmlRenderer,
'Home',
'Welcome'
);
$htmlResult = $page->view();
$page->changeRenderer($jsonRenderer);
$jsonResult = $page->view();
$this->assertNotSame(
$htmlResult,
$jsonResult
);
}
# اشتباهات رایج در استفاده از Bridge Pattern
اشتباه اول: استفاده از Inheritance برای تمام ترکیبها
اگر چند بُعد مستقل دارید، ساخت کلاسهای ترکیبی باعث رشد سریع Hierarchy میشود.
اشتباه دوم: وابستگی مستقیم به Concrete Class
بهتر است Abstraction به Interface وابسته باشد:
protected Renderer $renderer;
نه به یک کلاس مشخص:
protected HtmlRenderer $renderer;
اشتباه سوم: استفاده برای پروژههای بسیار ساده
Bridge برای هر کلاس کوچک لازم نیست.
اشتباه چهارم: اشتباه گرفتن Bridge با Adapter
Adapter برای سازگارکردن Interfaceهای موجود است، اما Bridge برای جداکردن دو سلسلهمراتب مستقل طراحی میشود.
اشتباه پنجم: قرار دادن منطق Implementation داخل Abstraction
اگر Page شروع به ساخت HTML، JSON و XML کند، جداسازی از بین میرود.
# جمعبندی Bridge Pattern در PHP
Bridge Pattern یک Structural Design Pattern است که Abstraction را از Implementation جدا میکند.
در این الگو، بهجای اینکه برای تمام ترکیبهای ممکن کلاسهای جداگانه بسازیم، دو سلسلهمراتب مستقل ایجاد میکنیم و آنها را با Composition به یکدیگر متصل میکنیم.
ساختار کلی آن به شکل زیر است:
Abstraction
|
v
Implementation
نمونههای رایج استفاده از Bridge عبارتاند از:
- Page و Renderer؛
- Payment و PaymentGateway؛
- Message و MessageSender؛
- Report و ReportFormatter؛
- Service و API Provider.
مهمترین مزیت Bridge این است که میتوان هر بخش را مستقل از بخش دیگر توسعه داد. همچنین با استفاده از Interface و Dependency Injection، تستپذیری و انعطافپذیری سیستم افزایش پیدا میکند.
با این حال، Bridge برای تمام پروژهها مناسب نیست. اگر سیستم ساده باشد یا فقط به انتخاب یک الگوریتم نیاز داشته باشید، Strategy یا حتی یک کلاس ساده میتواند انتخاب بهتری باشد.
# سوالات متداول Bridge Pattern در PHP
Bridge Pattern در PHP چیست؟
Bridge Pattern الگویی Structural است که Abstraction و Implementation را از یکدیگر جدا میکند تا هرکدام مستقل توسعه پیدا کنند.
مهمترین هدف Bridge Pattern چیست؟
هدف اصلی آن جلوگیری از افزایش تعداد Subclassها در شرایطی است که یک سیستم در چند بُعد مستقل توسعه پیدا میکند.
Abstraction در Bridge چه نقشی دارد؟
Abstraction منطق سطح بالای سیستم را مدیریت میکند و عملیات فنی را به Implementation واگذار میکند.
Implementation در Bridge چیست؟
Implementation قراردادی برای عملیات فنی تعریف میکند و Concrete Implementationها آن را پیادهسازی میکنند.
تفاوت Bridge و Adapter چیست؟
Bridge برای جداکردن دو بخش مستقل از ابتدا طراحی میشود، اما Adapter معمولاً برای سازگارکردن دو کلاس یا سرویس موجود استفاده میشود.
تفاوت Bridge و Strategy چیست؟
Strategy بیشتر برای تعویض الگوریتم کاربرد دارد، اما Bridge برای جداکردن دو سلسلهمراتب مستقل طراحی میشود.
آیا Bridge Pattern در Laravel کاربرد دارد؟
بله. میتوان از آن برای جداکردن منطق کسبوکار از Providerهای پیامک، درگاههای پرداخت، سرویسهای ذخیرهسازی و APIهای مختلف استفاده کرد.
آیا Bridge همیشه انتخاب مناسبی است؟
خیر. در پروژههای کوچک یا زمانی که فقط یک Implementation وجود دارد، استفاده از Bridge ممکن است پیچیدگی غیرضروری ایجاد کند.





