Pertama-tama, pertanyaan yang bagus. Saya mengagumi fokus Anda pada utilitas daripada menerima "praktik terbaik" secara membuta. +1 untuk itu.
Saya sudah membaca panduan itu sebelumnya. Anda harus mengingat sesuatu tentang hal itu - itu hanya panduan, terutama untuk pendatang C # yang tahu cara memprogram tetapi tidak begitu akrab dengan cara C # dalam melakukan sesuatu. Ini bukan halaman aturan, melainkan halaman yang menjelaskan bagaimana hal-hal sudah biasa dilakukan. Dan karena mereka sudah melakukan hal ini di mana-mana, mungkin ide yang bagus untuk tetap konsisten.
Saya akan langsung ke intinya, menjawab pertanyaan Anda.
Pertama-tama, saya anggap Anda sudah tahu apa antarmuka itu. Adapun delegasi, itu cukup untuk mengatakan bahwa itu adalah struktur yang mengandung pointer yang diketik ke metode, bersama dengan pointer opsional ke objek yang mewakili this
argumen untuk metode itu. Dalam hal metode statis, penunjuk terakhir adalah nol.
Ada juga delegasi Multicast, yang sama seperti delegasi, tetapi mungkin memiliki beberapa struktur yang ditugaskan untuk mereka (artinya panggilan tunggal untuk Memohon pada delegasi multicast memanggil semua metode dalam daftar permintaan yang ditugaskan).
Apa yang mereka maksud dengan pola desain acara?
Maksudnya menggunakan acara dalam C # (yang memiliki kata kunci khusus untuk menerapkan pola yang sangat berguna ini dengan canggih). Acara di C # didorong oleh delegasi multicast.
Saat Anda menentukan suatu peristiwa, seperti dalam contoh ini:
class MyClass {
// Note: EventHandler is just a multicast delegate,
// that returns void and accepts (object sender, EventArgs e)!
public event EventHandler MyEvent;
public void DoSomethingThatTriggersMyEvent() {
// ... some code
var handler = MyEvent;
if (handler != null)
handler(this, EventArgs.Empty);
// ... some other code
}
}
Compiler sebenarnya mengubah ini menjadi kode berikut:
class MyClass {
private EventHandler MyEvent = null;
public void add_MyEvent(EventHandler value) {
MyEvent += value;
}
public void remove_MyEvent(EventHandler value) {
MyEvent -= value;
}
public void DoSomethingThatTriggersMyEvent() {
// ... some code
var handler = MyEvent;
if (handler != null)
handler(this, EventArgs.Empty);
// ... some other code
}
}
Anda kemudian berlangganan ke suatu acara dengan melakukan
MyClass instance = new MyClass();
instance.MyEvent += SomeMethodInMyClass;
Yang mengkompilasi ke
MyClass instance = new MyClass();
instance.add_MyEvent(new EventHandler(SomeMethodInMyClass));
Jadi itu terjadi di C # (atau. NET secara umum).
Bagaimana komposisi ini menjadi mudah jika delegasi digunakan?
Ini dapat dengan mudah ditunjukkan:
Misalkan Anda memiliki kelas yang bergantung pada serangkaian tindakan yang akan diteruskan ke sana. Anda bisa merangkum tindakan-tindakan itu dalam sebuah antarmuka:
interface RequiredMethods {
void DoX();
int DoY();
};
Dan siapa pun yang ingin memberikan tindakan ke kelas Anda pertama-tama harus mengimplementasikan antarmuka itu. Atau Anda bisa membuat hidup mereka lebih mudah dengan bergantung pada kelas berikut:
sealed class RequiredMethods {
public Action DoX;
public Func<int> DoY();
}
Dengan cara ini, penelepon hanya perlu membuat instance dari RequiredMethods dan mengikat metode kepada delegasi saat runtime. Ini adalah biasanya lebih mudah.
Cara melakukan hal-hal ini sangat bermanfaat dalam keadaan yang tepat. Pikirkan tentang hal ini - mengapa bergantung pada antarmuka saat semua yang Anda benar-benar pedulikan adalah penerapannya diberikan kepada Anda?
Manfaat menggunakan antarmuka saat ada sekelompok metode terkait
Ini bermanfaat untuk menggunakan antarmuka karena antarmuka biasanya memerlukan implementasi waktu kompilasi eksplisit. Ini artinya Anda membuat kelas baru.
Dan jika Anda memiliki sekelompok metode terkait dalam satu paket, sebaiknya paket itu dapat digunakan kembali oleh bagian lain dari kode. Jadi jika mereka dapat membuat instantiate sebuah kelas daripada membangun sekumpulan delegasi, itu lebih mudah.
Manfaat menggunakan antarmuka jika suatu kelas hanya membutuhkan satu implementasi
Seperti disebutkan sebelumnya, antarmuka diimplementasikan dalam waktu kompilasi - yang berarti mereka lebih efisien daripada memanggil delegasi (yang merupakan tingkat tipuan per se).
"Satu implementasi" mungkin berarti implementasi yang ada di satu tempat yang terdefinisi dengan baik.
Kalau tidak, suatu implementasi mungkin datang dari mana saja dalam program yang kebetulan sesuai dengan metode tanda tangan. Itu memungkinkan lebih banyak fleksibilitas, karena metode hanya perlu menyesuaikan diri dengan tanda tangan yang diharapkan, daripada menjadi bagian dari kelas yang secara eksplisit mengimplementasikan antarmuka tertentu. Tetapi fleksibilitas itu mungkin harus dibayar mahal, dan benar-benar melanggar prinsip Pergantian Liskov , karena seringkali Anda menginginkan kesaksian, karena meminimalkan peluang terjadinya kecelakaan. Sama seperti Pengetikan Statis.
Istilah ini juga merujuk pada delegasi multicast di sini. Metode yang dideklarasikan oleh antarmuka hanya dapat diimplementasikan satu kali dalam kelas pelaksana. Tetapi delegasi dapat mengakumulasikan banyak metode, yang akan dipanggil secara berurutan.
Jadi semuanya, sepertinya panduan ini tidak cukup informatif, dan hanya berfungsi seperti apa - panduan, bukan buku aturan. Beberapa saran mungkin terdengar agak kontradiktif. Terserah Anda untuk memutuskan kapan tepat untuk menerapkan apa. Panduan ini sepertinya hanya memberi kita jalan umum.
Saya harap pertanyaan Anda telah dijawab untuk kepuasan Anda. Dan sekali lagi, pujian untuk pertanyaan itu.