Pola pengunjung adalah mekanisme untuk mensimulasikan penjilidan rangkap dalam bahasa pemrograman yang hanya mendukung penjilidan tunggal. Sayangnya, pernyataan itu mungkin tidak menjelaskan banyak hal, jadi izinkan saya menjelaskan dengan contoh sederhana.
Di .NET dan C #, platform yang Anda gunakan, objek dapat dikonversi menjadi string menggunakan ToString()
fungsi. Apa yang dilakukan funtion, yaitu kode yang dieksekusi, tergantung pada jenis objek yang Anda terapkan (ini adalah metode virtual). Kode apa yang dieksekusi tergantung pada satu hal, satu jenis objek, maka mekanisme yang digunakan disebut pengikatan tunggal.
Tetapi bagaimana jika saya ingin memiliki lebih dari satu cara untuk mengubah objek menjadi string, untuk setiap jenis objek yang berbeda? Bagaimana jika saya ingin memiliki dua cara untuk mengubah objek menjadi string, sehingga kode yang dieksekusi tergantung pada dua hal: tidak hanya objek yang akan dikonversi, tetapi juga cara kita ingin dikonversi?
Itu bisa diselesaikan dengan baik jika kita memiliki ikatan ganda. Tetapi sebagian besar bahasa OO, termasuk C #, hanya mendukung pengikatan tunggal.
Pola pengunjung menyelesaikan masalah, dengan mengubah ikatan ganda menjadi dua ikatan tunggal berturut-turut.
Dalam contoh kami di atas, itu akan menggunakan metode virtual di objek untuk mengkonversi, yang memanggil metode virtual kedua di objek yang mengimplementasikan algoritma konversi.
Tapi itu menyiratkan bahwa objek yang ingin Anda terapkan algoritma perlu berkolaborasi dengan ini: ia perlu memiliki dukungan untuk pola pengunjung yang dipanggang.
Anda tampaknya menggunakan kelas .NET's Windows Forms, yang tidak memiliki dukungan untuk pola pengunjung. Lebih khusus lagi, mereka perlu memiliki public virtual void Accept(IVisitor)
metode, yang jelas tidak mereka miliki.
Jadi, apa alternatifnya? Nah, .NET tidak hanya mendukung pengikatan tunggal, juga mendukung pengikatan dinamis, yang bahkan lebih kuat dari pengikatan ganda.
Untuk informasi lebih lanjut tentang cara menerapkan teknik itu, yang akan memungkinkan Anda untuk menyelesaikan masalah Anda (jika saya memahaminya dengan baik), lihat Farewell Visitor .
MEMPERBARUI:
Untuk menerapkan teknik ini ke masalah spesifik Anda, tentukan terlebih dahulu metode ekstensi Anda:
public static XmlDocument ToXml(this Control control)
{
XmlDocument xml = new XmlDocument();
XmlElement root = xml.CreateElement(control.GetType().Name);
xml.AppendChild(root);
Visit(control, xml, root);
return xml;
}
Buat operator dinamis:
private static void Visit(Control control, XmlDocument xml, XmlElement root)
{
dynamic dynamicControl = control; //notice the 'dynamic' type.
//this is the key to dynamic dispatch
VisitCore(dynamicControl, xml, root);
}
Kemudian isi metode spesifik:
private static void VisitCore(Control control, XmlDocument xml, XmlElement root)
{
// TODO: specific Control handling
}
private static void VisitCore(ContainerControl control, XmlDocument xml, XmlElement root)
{
// call the "base" method
VisitCore(control as Control, xml, root);
// TODO: specific ContainerControl handling
// for example:
foreach (Control child in control.Controls)
{
XmlElement element = xml.CreateElement(child.GetType().Name);
root.AppendChild(element);
// call the dynamic dispatcher method
Visit(child, xml, element);
}
}
private static void VisitCore(Form control, XmlDocument xml, XmlElement root)
{
// call the "base" method
VisitCore(control as ContainerControl, xml, root);
// TODO: specific Form handling
}