Dalam bentuk murni mereka, pola cukup langka, dan ketika mempelajari pola, terutama pada tahap awal, bukan pola itu sendiri yang penting yang memahami mekanisme (taktik) yang dengannya mereka diterapkan. Dalam artikel ini, saya ingin menggambarkan salah satu mekanisme ini (manajemen ketergantungan), yang digunakan dalam pola Pengamat dan Mediator, tetapi yang sering diabaikan. Jika Anda baru mulai mempelajari pola, selamat datang di kucing.
Manajemen ketergantungan
Mari kita mulai dengan pernyataan: jika kelas A tergantung pada kelas B, maka, tanpa mengubah perilaku, Anda dapat menulis ulang kode sehingga kelas B bergantung pada kelas A atau memperkenalkan kelas C lain sehingga kelas A dan B independen, dan kelas C akan mengikat dan bergantung pada kelas A dan B.

Satu kelas tergantung pada yang lain jika mengacu pada bidang atau metode. Fields mudah ditransfer dari satu kelas ke kelas lain, jadi kami akan membahas metode lebih detail. Misalkan kelas B berisi metode Cetak, yang mencetak tanggal saat ini ke konsol, dan kelas A memanggil metode ini.
class A { private readonly B _b; public A(B b) { _b = b; } public void Run() { _b.Print(); } } class B { public void Print() { Console.WriteLine(DateTime.Now.ToString()); } } public void Test() { var b = new B(); var a = new A(b); a.Run(); }
Dengan demikian, kelas A tergantung pada kelas B. Untuk membalikkan dependensi ini, alih-alih memanggil metode Print secara langsung, kita akan menghasilkan suatu peristiwa. Sekarang kelas A tidak tahu apa-apa tentang kelas B, dan kelas B dapat berlangganan ke acara kelas A. I.e. kelas B akan tergantung pada kelas A.
class A { public event EventHandler PrintRequested; public void Run() { PrintRequested.Invoke(this, EventArgs.Empty); } } class B { private readonly A _a; public B(A a) { _a = a; _a.PrintRequested += (s, e) => Print(); } public void Print() { Console.WriteLine(DateTime.Now.ToString()); } } public void Test() { var a = new A(); var b = new B(a); a.Run(); }
Perilaku kode tidak berubah, dan dalam metode pemanggilan hanya urutan inisialisasi objek dan transfer dependensi ke konstruktor diubah.
Sebenarnya, ini adalah implementasi dari pola
Observer di C #. Kelas A adalah Observable, dan Kelas B adalah Observer. Kelas A adalah kelas independen yang menghasilkan notifikasi (acara). Kelas-kelas lain yang tertarik pada ini dapat berlangganan ke acara-acara ini dan melaksanakan logikanya. Sistem menjadi lebih dinamis karena sekarang kelas A tidak perlu tahu tentang implementasi lain. Kami dapat menambahkan implementasi baru yang akan berlangganan acara, sementara kelas A akan tetap tidak berubah.
Anda dapat melangkah lebih jauh dan menghapus ketergantungan kelas B pada A dengan menambahkan kode eksternal yang akan menautkan kedua kelas, yaitu berlangganan satu objek ke acara lainnya.
class A { public event EventHandler PrintRequested; public void Run() { PrintRequested.Invoke(this, EventArgs.Empty); } } class B { public void Print() { Console.WriteLine(DateTime.Now.ToString()); } } class C { public void Test() { var a = new A(); var b = new B(); a.PrintRequested += (s, e) => b.Print(); a.Run(); } }
Sekarang kelas A dan B sepenuhnya independen, masing-masing melakukan tugasnya dan tidak tahu apa-apa tentang kelas lainnya. Logika untuk interaksi antara objek masuk ke kelas baru. Hanya kelas C yang tahu dalam menanggapi peristiwa apa dan dalam kondisi apa metode kelas B harus dipanggil. Dengan demikian, kelas C menjadi
mediator .
Ringkasan: Memerangi kompleksitas sistem
Salah satu masalah penting dalam pemrograman adalah keberadaan sistem yang kompleks dari kelas-kelas yang terjerat dengan sejumlah besar dependensi (sistem yang digabungkan secara ketat). Dengan mengelola dependensi, Anda dapat mengurangi konektivitas, menyederhanakan sistem, dan mencapai kelincahan dan fleksibilitas yang lebih besar.
Pola
Observer mengurangi konektivitas dengan membalik ketergantungan. Ini berlaku baik ketika ada beberapa sumber acara dan banyak pendengar yang ditambahkan secara dinamis. Contoh lain yang baik dari penggunaan pola ini adalah
pemrograman reaktif , ketika perubahan dalam keadaan satu objek mengarah ke perubahan dalam keadaan semua objek yang bergantung padanya, dan seterusnya.

Pola
Mediator mengurangi keterhubungan sistem karena fakta bahwa semua dependensi masuk ke satu kelas, mediator, dan semua kelas lainnya menjadi independen dan bertanggung jawab hanya untuk logika yang mereka jalankan. Dengan demikian, penambahan kelas baru menjadi lebih mudah, tetapi dengan setiap kelas baru logika mediator sangat rumit. Seiring waktu, jika mediator terus tumbuh tak terkendali, maka menjadi sangat sulit untuk dipertahankan.

Jebakan berbahaya saat menggunakan pola Observer dan Mediator adalah adanya referensi melingkar, ketika peristiwa dari satu kelas, melewati rantai objek, mengarah ke generasi peristiwa yang sama lagi. Masalah ini sulit untuk dipecahkan dan secara signifikan menyulitkan penggunaan pola.
Dengan demikian, dalam keadaan yang berbeda, mengelola dependensi, Anda dapat datang ke pola yang berbeda, kadang-kadang ke campuran mereka, dan kadang-kadang mekanisme ini akan berguna tanpa menggunakan pola sama sekali. Perangi kompleksitas dan jangan menghasilkan entitas.
