Hai! Kami sekarang terus mempelajari topik berguna yang luas dan sangat penting: pola desain. Hari ini mari kita bicara tentang pola jembatan. Seperti pola lainnya, pola jembatan berfungsi untuk memecahkan masalah khas yang ditemui pengembang saat merancang arsitektur perangkat lunak. Hari ini mari pelajari fitur-fitur dari pola ini dan cari tahu cara menggunakannya.

Apa itu pola jembatan?

Pola jembatan adalah pola desain struktural. Dengan kata lain, tugas utamanya adalah membuat struktur lengkap dari kelas dan objek. Sebuah jembatan melakukan ini dengan membagi satu atau lebih kelas menjadi hierarki terpisah: abstraksi dan implementasi . Perubahan fungsionalitas dalam satu hierarki tidak berarti perubahan di hierarki lainnya. Itu bagus dan bagus, tetapi definisi ini sangat luas dan tidak menjawab pertanyaan yang paling penting: "Apa pola jembatannya?" Saya pikir akan lebih mudah bagi Anda untuk memahami aplikasi praktisnya. Jadi langsung saja, mari buat skenario klasik untuk pola jembatan. Kami memiliki Shapekelas abstrak, yang mewakili sosok geometris umum:
  • Shape.java

    
    public abstract class Shape {
       public abstract void draw();
    }
    

    Saat kami memutuskan untuk menambahkan bentuk seperti segitiga dan persegi panjang, kami akan membuatnya mewarisi kelas Shape:

  • Persegi panjang.java:

    
    public class Rectangle extends Shape {
       @Override
       public void draw() {
           System.out.println("Drawing rectangle");
       }
    }
    
  • Segitiga.java:

    
    public class Triangle extends Shape {
       @Override
       public void draw() {
           System.out.println("Drawing triangle");
       }
    }
    
Semuanya terlihat sederhana hingga saat ini kami memperkenalkan konsep warna. Artinya, setiap bentuk akan memiliki warna tersendiri, dan fungsionalitas metode draw()akan bergantung pada warna ini. Untuk memiliki implementasi metode yang berbeda draw(), maka kita perlu membuat kelas untuk setiap kombinasi bentuk-warna. Jika kita memiliki tiga warna, maka kita membutuhkan enam kelas: TriangleBlack, TriangleGreen, TriangleRed, RectangleBlack, RectangleGreendan RectangleRed. Enam kelas bukanlah masalah besar. Tetapi! Jika kita perlu menambahkan bentuk atau warna baru, maka jumlah kelas bertambah secara eksponensial. Bagaimana cara keluar dari situasi ini? Menyimpan warna dalam bidang dan menghitung semua opsi menggunakan pernyataan bersyarat bukanlah solusi terbaik. Solusi yang baik adalah memindahkan warna ke antarmuka terpisah. Tidak lama setelah selesai: mari buat Colorantarmuka dengan tiga implementasi: BlackColor, GreenColordan RedColor:
  • Warna.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");
       }
    }
    

    Sekarang kita menambahkan Colorbidang ke Shapekelas. Kami akan mendapatkan nilainya di konstruktor.

  • Shape.java:

    
    public abstract class Shape {
       protected Color color;
      
       public Shape(Color color) {
           this.color = color;
       }
    
       public abstract void draw();
    }
    

    Kami akan menggunakan colorvariabel dalam Shapeimplementasi. Ini berarti bahwa bentuk sekarang dapat menggunakan fungsionalitas antarmuka 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();
       }
    }
    
Ta-da! Sekarang kita dapat membuat berbagai warna dan bentuk ad infinitum, dan jumlah kelas hanya akan bertambah secara linier. Field Color coloradalah jembatan yang menghubungkan dua hierarki kelas yang terpisah.

Cara membangun jembatan: abstraksi dan implementasi

Mari kita lihat diagram kelas yang menggambarkan pola jembatan: Memperkenalkan pola desain jembatan - 2Di sini Anda dapat melihat dua struktur independen yang dapat dimodifikasi tanpa memengaruhi fungsionalitas satu sama lain. Dalam kasus kami:
  • Abstraksi adalah Shapekelas
  • RefinedAbstraction adalah Triangledan Rectanglekelas
  • Implementor adalah Colorantarmuka
  • ConcreteImplementor adalah BlackColor, GreenColordan RedColorkelas.
Kelas Shapeadalah abstraksi — mekanisme untuk mengelola pengisian bentuk dengan berbagai warna, yang didelegasikan ke antarmuka Color(Implementor). Kelas Triangleand Rectangleadalah kelas konkret yang menggunakan mekanisme yang disediakan oleh Shapekelas. BlackColor, GreenColordan RedColormerupakan implementasi konkret dalam hirarki Implementasi.

Di mana menggunakan pola jembatan

Manfaat besar menggunakan pola ini adalah Anda dapat membuat perubahan pada kelas fungsional dalam satu hierarki tanpa merusak logika yang lain. Selain itu, pendekatan ini membantu mengurangi penggabungan antar kelas. Persyaratan utama saat menggunakan pola ini adalah "ikuti petunjuk" — jangan abaikan satu pun! Untuk itu, mari kita cari tahu situasi kapan Anda harus menggunakan pola jembatan:
  1. Jika Anda perlu memperluas jumlah entitas berdasarkan kombinasi dua konsep (misalnya bentuk dan warna).

  2. Jika Anda ingin membagi kelas besar yang tidak memenuhi prinsip tanggung jawab tunggal menjadi kelas-kelas kecil yang memiliki fungsi sempit.

  3. Jika perlu, lakukan perubahan pada logika entitas tertentu saat program sedang berjalan.

  4. Jika perlu menyembunyikan implementasi dari klien kelas atau perpustakaan.

Saat Anda menggunakan pola ini, selalu ingat bahwa ini menambahkan entitas tambahan ke kode Anda — mungkin tidak masuk akal untuk menggunakannya dalam proyek di mana hanya ada satu bentuk dan satu atau dua kemungkinan warna.

Pro dan kontra dari pola tersebut

Seperti pola lainnya, jembatan memiliki kelebihan dan kekurangan. Keuntungan dari pola jembatan:
  1. Ini meningkatkan skalabilitas kode — Anda dapat menambahkan fungsionalitas tanpa takut merusak sesuatu di bagian lain program.
  2. Ini mengurangi jumlah subkelas ketika jumlah entitas seharusnya didasarkan pada kombinasi dua konsep (misalnya, bentuk dan warna).
  3. Itu memungkinkan untuk bekerja secara terpisah pada dua hierarki terpisah — Abstraksi dan Implementasi. Dua pengembang yang berbeda dapat membuat perubahan tanpa mempelajari detail kode masing-masing.
  4. Ini mengurangi kopling antar kelas - satu-satunya tempat di mana dua kelas digabungkan adalah jembatan (yaitu bidang Color color).
Kerugian dari pola jembatan:
  1. Bergantung pada situasi spesifik dan keseluruhan struktur proyek, ini dapat berdampak negatif pada kinerja program (misalnya, jika Anda perlu menginisialisasi lebih banyak objek).
  2. Itu membuat kode kurang dapat dibaca karena kebutuhan untuk beralih di antara dua kelas.

Perbedaan dari pola strategi

Pola jembatan sering dibingungkan dengan pola desain lain — strategi. Keduanya menggunakan komposisi (meskipun kami menggunakan agregasi dalam contoh dengan gambar dan warna, pola Bridge juga dapat menggunakan komposisi), mendelegasikan pekerjaan ke objek lain. Tapi ada perbedaan di antara mereka, dan itu sangat besar. Pola strategi adalah pola perilaku: ini memecahkan masalah yang sama sekali berbeda. Strategi memungkinkan algoritme untuk dipertukarkan, sementara jembatan memisahkan abstraksi dari implementasi untuk memilih di antara implementasi yang berbeda. Dengan kata lain, tidak seperti strategi, jembatan berlaku untuk seluruh entitas atau struktur hierarkis. Pola jembatan bisa menjadi senjata yang bagus di gudang pengembang. Hal utama adalah mengidentifikasi situasi di mana layak untuk digunakan dan mengenali kapan beberapa pola lain sesuai.