Bridge Pattern #

Dalam pengembangan perangkat lunak, sering kali kita menghadapi situasi di mana sebuah class harus memiliki banyak variasi tergantung pada kombinasi fitur atau platform yang berbeda. Jika menggunakan inheritance secara langsung, kita bisa cepat menghasilkan ledakan subclass yang sulit dikelola. Di sinilah Bridge Pattern hadir sebagai solusi elegan.

Bridge Pattern membantu memisahkan abstraction dari implementation, sehingga keduanya dapat dikembangkan secara independen. Dengan memisahkan kedua aspek ini, kode menjadi lebih fleksibel, mudah diperluas, dan lebih mudah diuji. Pattern ini sangat berguna ketika sistem membutuhkan kombinasi dari dua dimensi perubahan yang berbeda, seperti tipe notifikasi dan media pengiriman, atau bentuk dan metode rendering pada grafik.

Dengan memahami dan menerapkan Bridge Pattern, kita bisa menjaga kode tetap bersih, scalable, dan mengurangi ketergantungan antar class yang kompleks.

Apa itu Bridge Pattern? #

Bridge Pattern adalah salah satu structural design pattern yang bertujuan untuk memisahkan abstraction dari implementation, sehingga keduanya dapat dikembangkan secara independen tanpa saling memengaruhi.

Inti dari Bridge Pattern adalah composition over inheritance. Alih-alih membuat banyak subclass untuk setiap kombinasi fitur, kita memecahnya menjadi dua hierarki terpisah:

  • Abstraction: sisi yang digunakan oleh client
  • Implementation: detail teknis di balik abstraction

Keduanya dihubungkan melalui sebuah bridge (biasanya berupa interface).


Tujuan Pattern #

Bridge Pattern digunakan untuk:

  1. Menghindari explosion of subclasses akibat kombinasi abstraction dan implementation
  2. Memisahkan high-level logic dari low-level detail
  3. Memungkinkan perubahan implementation tanpa mengubah abstraction
  4. Memudahkan testing dan extensibility
  5. Mendukung Open/Closed Principle

Kapan Cocok Digunakan? #

Bridge Pattern sangat cocok ketika:

  • Sebuah class memiliki dua dimensi perubahan (misalnya: tipe dan platform)
  • Abstraction dan implementation perlu berkembang secara independen
  • Inheritance mulai menghasilkan banyak subclass yang sulit dirawat
  • Detail implementation tidak ingin diekspos ke client

Contoh Kasus Nyata #

  • Shape (Circle, Square) × Renderer (SVG, Canvas)
  • Notification (Alert, Reminder) × Channel (Email, SMS, Push)
  • Remote Control × Device (TV, Radio, Projector)
  • Storage Service × Backend (Local, S3, GCS)

Struktur Pattern #

Bridge Pattern biasanya terdiri dari:

  • Abstraction: mendefinisikan interface tingkat tinggi
  • RefinedAbstraction: variasi dari abstraction
  • Implementor: interface untuk implementation
  • ConcreteImplementor: implementasi konkret
Abstraction  ----->  Implementor
     |                    |
Refined           ConcreteImplementor

Contoh Implementasi (Golang) #

Studi Kasus: Notification System #

Kita ingin membuat sistem notifikasi dengan:

  • Jenis notifikasi: Alert, Reminder
  • Media pengiriman: Email, SMS

Tanpa Bridge Pattern, kita akan memiliki banyak kombinasi class.

Implementor Interface (Bridge) #

package notification

// Implementor
// Media pengiriman notifikasi
type Sender interface {
    Send(message string) error
}

Concrete Implementor #

package notification

import "fmt"

// EmailSender
type EmailSender struct{}

func (e *EmailSender) Send(message string) error {
    fmt.Println("Sending Email:", message)
    return nil
}

// SMSSender
type SMSSender struct{}

func (s *SMSSender) Send(message string) error {
    fmt.Println("Sending SMS:", message)
    return nil
}

Abstraction #

package notification

// Abstraction
type Notification interface {
    Notify(message string) error
}

Refined Abstraction #

package notification

// AlertNotification
type AlertNotification struct {
    sender Sender
}

func NewAlertNotification(sender Sender) *AlertNotification {
    return &AlertNotification{sender: sender}
}

func (a *AlertNotification) Notify(message string) error {
    return a.sender.Send("[ALERT] " + message)
}

// ReminderNotification
type ReminderNotification struct {
    sender Sender
}

func NewReminderNotification(sender Sender) *ReminderNotification {
    return &ReminderNotification{sender: sender}
}

func (r *ReminderNotification) Notify(message string) error {
    return r.sender.Send("[REMINDER] " + message)
}

Client Code #

package main

import "notification"

func main() {
    email := &notification.EmailSender{}
    sms := &notification.SMSSender{}

    alert := notification.NewAlertNotification(email)
    reminder := notification.NewReminderNotification(sms)

    alert.Notify("Server down")
    reminder.Notify("Meeting at 10 AM")
}

Kenapa Ini Bridge Pattern? #

  • Notification dan Sender adalah dua hierarki terpisah

  • Keduanya dihubungkan melalui interface (Sender)

  • Kita bisa menambah:

    • Media baru (WhatsAppSender)
    • Tipe notifikasi baru (WarningNotification)

Tanpa mengubah kode yang sudah ada.


Perbandingan dengan Pattern Lain #

PatternFokus Utama
BridgeMemisahkan abstraction & implementation
AdapterMenyesuaikan interface yang tidak kompatibel
StrategyMengganti algoritma secara runtime
DecoratorMenambah behavior tanpa mengubah struktur

Kesalahan Umum #

  • Menggunakan Bridge Pattern terlalu dini
  • Abstraction terlalu tipis (over-engineering)
  • Implementor terlalu kompleks

Best Practices #

  1. Gunakan ketika ada dua axis perubahan Jangan gunakan Bridge Pattern jika problem bisa diselesaikan sederhana

  2. Favor composition dibanding inheritance Inject implementor melalui constructor

  3. Jaga abstraction tetap bersih Abstraction tidak boleh tahu detail teknis implementation

  4. Gunakan interface kecil dan fokus Hindari interface besar yang sulit diimplementasikan

  5. Cocok dikombinasikan dengan Factory Untuk mengatur pembuatan kombinasi abstraction dan implementation


Penutup #

Bridge Pattern adalah solusi elegan untuk masalah kombinasi kompleks antara abstraction dan implementation. Dengan memisahkan keduanya, sistem menjadi lebih fleksibel, mudah diuji, dan scalable.

Jika Anda melihat banyak subclass hanya karena perbedaan platform, media, atau backend — Bridge Pattern hampir selalu menjadi kandidat kuat.

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact