Visitor tasarım deseni, üzerinde çalıştığımız nesnelerin sınıflarını değiştirmeden yeni bir özellik tanımlamamızı sağlayan bir tasarım desenidir.
İşlem yapılacak nesnelerde herhangi bir değişiklik yapılmaz. İşlemi ziyaretçi (Visitor) nesneleri yapar. Eğer sisteme yeni nesneler eklenmiyor, fakat sık sık yeni işlemlerin eklenmesi gerekiyorsa bu tasarım deseni kullanılabilir. Bu tasarım deseninin kullanılmasıyla, yapılacak işlemle ilgili kodların merkezi bir nesnede toplanır.
Bu tasarım desenine ait UML diyagramı aşağıdaki gibidir.
Visitor: Her ConcreteVisitor örneği için metot temsil eder, parametre olarak Element sınıfından türeyen sınıfların örneğini alır.
ConcreteVisitor:Visitor arayüzünü ve burada tanımlı olan metotları uygular. Sonradan eklenmek istenen işlemler burada yer alır.
Element:ConcreteElement sınıfı örneklerinin ortak bir parametre olarak gitmesi için yapılan soyutlamadır.
ConcreteElement:Element sınıfından türer. accept metoduna bulunduğu nesne örneği gönderilir.
Senaryo olarak elimizde kitaplarımızın olduğunu ve bu kitap bilgilerinin farklı şekillerde XML ya da JSON gibi çıktılarının alındığını düşünelim.
C# Kod Örneği:
// Temel sınıftır.// Yeni davranışları Accept metotu ile alır.// UML diyagramındaki Element yapısına denk gelmektedir.abstractclassBook{publicstring name;publicstring author;publicstring categoryName;publicabstractvoidAccept(IBookExportVisitor visitor);}
// UML diyagramındaki Element'ten türer.// Accept metoduna bulunduğu nesne örneği gönderilir.// UML diyagramındaki ConcreteElement yapısına denk gelir.classEncyclopedia:Book{publicoverridevoidAccept(IBookExportVisitor visitor) {visitor.ExportVisit(this); }}
// UML diyagramındaki Element'ten türer.// Accept metoduna bulunduğu nesne örneği gönderilir.// UML diyagramındaki ConcreteElement yapısına denk gelir.classMagazine:Book{publicoverridevoidAccept(IBookExportVisitor visitor) {visitor.ExportVisit(this); }}
// Her ConcreteVisitor örneği için metot temsil eder.// Parametre olarak Element sınıfından türeyen sınıfların örneğini alır.// UML diyagramındaki Visitor yapısına denk gelir.interfaceIBookExportVisitor{voidExportVisit(Magazine magazine);voidExportVisit(Encyclopedia encyclopedia);}
// Visitor arayüzünü ve burada tanımlı olan metotları uygular.// Sonradan eklenmek istenen işlemler burada yer alır.// UML diyagramındaki ConcreteVisitor yapısına denk gelir.classXmlExportVisitor:IBookExportVisitor{publicvoidExportVisit(Magazine magazine) { // Parametre olarak gelen örneğin XML'e çevrilmesi işlemleri yer alacaktır.Console.WriteLine($"{magazine.name} exported by XmlExportVisitor"); }publicvoidExportVisit(Encyclopedia encyclopedia) { // Parametre olarak gelen örneğin XML'e çevrilmesi işlemleri yer alacaktır.Console.WriteLine($"{encyclopedia.name} exported by XmlExportVisitor"); }}
// Visitor arayüzünü ve burada tanımlı olan metotları uygular.// Sonradan eklenmek istenen işlemler burada yer alır.// UML diyagramındaki ConcreteVisitor yapısına denk gelir.classJsonExportVisitor:IBookExportVisitor{publicvoidExportVisit(Magazine magazine) { // Parametre olarak gelen örneğin JSON'a çevrilmesi işlemleri yer alacaktır.Console.WriteLine($"{magazine.name} exported by JsonExportVisitor"); }publicvoidExportVisit(Encyclopedia encyclopedia) { // Parametre olarak gelen örneğin JSON'a çevrilmesi işlemleri yer alacaktır.Console.WriteLine($"{encyclopedia.name} exported by JsonExportVisitor"); }}
Book earth =newEncyclopedia();earth.name="Big Earth!";earth.author="Jose S. Massey";earth.categoryName="Encyclopedia";Book daily =newMagazine();daily.name="Daily Magazine";daily.author="Wayne D. Eakin";daily.categoryName="Magazine";IBookExportVisitor xmlExportVisitor =newXmlExportVisitor();IBookExportVisitor jsonExportVisitor =newJsonExportVisitor();earth.Accept(xmlExportVisitor);daily.Accept(jsonExportVisitor);// output:// Big Earth!exported by XmlExportVisitor// Daily Magazine exported by XmlExportVisitor