﻿
{"id":23208,"date":"2021-10-09T13:58:48","date_gmt":"2021-10-09T13:58:48","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=23208"},"modified":"2021-10-09T13:58:48","modified_gmt":"2021-10-09T13:58:48","slug":"c-visitor-design-patternvisitor-tasarim-deseni","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/c-visitor-design-patternvisitor-tasarim-deseni\/","title":{"rendered":"C# Visitor Design Pattern(Visitor Tasar\u0131m Deseni)"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Bu i\u00e7eri\u011fimizde Davran\u0131\u015fsal Tasar\u0131m Kal\u0131plar\u0131ndan(Behavioral Patterns) olan Visitor Tasar\u0131m Desenini(Visitor Design Pattern) tam teferruatl\u0131 inceleyecek ve hangi senaryolarda, ne ama\u00e7la bu pattern&#8217;\u0131 kullanabilece\u011fimize dair teorik sorgulamada bulunurken bir yandan da pratiksel olarak birka\u00e7 \u00f6rnek \u00fczerinde isti\u015fare edece\u011fiz. O halde fazla vakit kaybetmeksizin buyrun konuya ba\u015flayal\u0131m&#8230;<\/p>\n<h5>Visitor Design Pattern Nedir?<\/h5>\n<p>Uygulamalarda belirli s\u0131n\u0131flara, o s\u0131n\u0131flar\u0131n fiziksel yap\u0131lar\u0131n\u0131 de\u011fi\u015ftirmeksizin yeni fonksiyonaliteler eklemek gerekti\u011fi durumlarda kullan\u0131lan bir tasar\u0131m desenidir. Evet&#8230; Bazen belirli nesneler \u00fczerinde var olan \u00f6zelliklerin d\u0131\u015f\u0131nda yeni davran\u0131\u015flara sahip farkl\u0131 \u00f6zelliklere ihtiyac\u0131m\u0131z olabilmektedir. Ee zaten bu durum OOP yakla\u015f\u0131ml\u0131 yaz\u0131l\u0131m in\u015fa s\u00fcre\u00e7lerinin en do\u011fal halidir. Haliyle genellikle, biz yaz\u0131l\u0131mc\u0131lar bu tarz durumlarda ilgili s\u0131n\u0131flar\u0131 fiziksel olarak onarmay\u0131 ve yeni \u00f6zellikleri manuel olarak eklemeyi tercih ederek bu do\u011fal duruma kar\u015f\u0131 en temel refleksi g\u00f6steriyoruz, \u00f6yle de\u011fil mi?<\/p>\n<p>Amma velakin, yeni \u00f6zelli\u011fin eklenece\u011fi s\u0131n\u0131flar\u0131n de\u011fi\u015ftirilmesi istenmedi\u011fi ya da kaynak kodu elimizde olmayan bir s\u0131n\u0131fa yeni bir fonksiyonalitenin eklenmek istendi\u011fi durumlar\u0131 ya\u015fad\u0131n\u0131z m\u0131 hi\u00e7? Ya\u015fad\u0131ysan\u0131z e\u011fer bu pattern&#8217;\u0131n k\u0131ymetini zaten bildi\u011finize \u015f\u00fcphem yok, yok e\u011fer ya\u015famad\u0131ysan\u0131z i\u015fte bu tarz durumlar i\u00e7in bi\u00e7ilmi\u015f kaftan olan bu pattern&#8217;\u0131 sindirip haf\u0131zaya atman\u0131zda fayda var! <\/p>\n<p>Visitor Design Pattern, yukar\u0131da bahsedildi\u011fi gibi uyguland\u0131\u011f\u0131 nesnelere yeni fonksiyonaliteler ekleyebilmemizi sa\u011flamaktad\u0131r. B\u00f6ylece eklenecek olan fonksiyonalitedeki davran\u0131\u015f\u0131 ya da algoritmay\u0131(her ne ise), ilgili nesnelerden ay\u0131rmam\u0131za olanak sa\u011flayan bir stratejidir. \u00c7\u00fcnk\u00fc yaz\u0131m\u0131z\u0131n devam\u0131nda g\u00f6rece\u011finiz \u00fczere bu davran\u0131\u015flar\/algoritmalar\/fonksiyonaliteler(bundan sonra sadece davran\u0131\u015f denecek) hedef nesnelerden ziyade farkl\u0131 s\u0131n\u0131flarda tan\u0131mlanm\u0131\u015f olacakt\u0131r. <strong><em>Peki bu ne i\u015fe yarayacakt\u0131r?<\/em><\/strong> diye sordu\u011funuzda; bir davran\u0131\u015f\u0131, \u00fczerinde \u00e7al\u0131\u015ft\u0131r\u0131laca\u011f\u0131 nesneden ay\u0131rabilmek, o davran\u0131\u015f i\u00e7in y\u00f6netilebilirlik ve geli\u015ftirilebilirlik a\u00e7\u0131s\u0131ndan daha s\u00fcrd\u00fcr\u00fclebilirlik kazand\u0131r\u0131rken nesne a\u00e7\u0131s\u0131ndan da farkl\u0131 davran\u0131\u015flara kar\u015f\u0131 olu\u015fabilecek direnci ortadan kald\u0131rmaktad\u0131r.<\/p>\n<blockquote><p><em>Visitor Design Pattern, dokunulmazl\u0131\u011f\u0131 olan s\u0131n\u0131flara yeni i\u015flevler\/fonksiyonlar\/\u00f6zellikler eklenmesi gerekti\u011finde kullan\u0131lan bir stratejidir.<\/em><\/p><\/blockquote>\n<h5>Bu Pattern&#8217;\u0131n Ad\u0131 Neden &#8216;Visitor&#8217; ?<\/h5>\n<p>Yukar\u0131daki sat\u0131rlarda, <em style=\"font-size:12px;\">-uygulamalarda belirli s\u0131n\u0131flara, o s\u0131n\u0131flar\u0131n fiziksel yap\u0131lar\u0131n\u0131 de\u011fi\u015ftirmeksizin yeni fonksiyonaliteler eklemek gerekti\u011fi durumlarda kullan\u0131lan bir tasar\u0131m desenidir-<\/em> \u015feklinde Visitor pattern&#8217;\u0131n\u0131n amac\u0131n\u0131 yazm\u0131\u015ft\u0131k. <strong><em>Peki bu davran\u0131\u015fa kar\u015f\u0131l\u0131k &#8216;Visitor&#8217; ismi neden kullan\u0131lmaktad\u0131r?<\/em><\/strong> dedi\u011finizi duyar gibiyim&#8230; Bunu \u015f\u00f6yle izah edelim;<\/p>\n<p>Bir s\u0131n\u0131fa eklenecek yeni fonksiyonalite, Visitor pattern sayesinde o s\u0131n\u0131f\u0131n bir member\u0131 olmaks\u0131z\u0131n ilgili s\u0131n\u0131fa enjekte edilebilmektedir. Misal olarak, evinize gelen bir ziyaret\u00e7iyi d\u00fc\u015f\u00fcn\u00fcrsek e\u011fer esas\u0131nda bu ziyaret\u00e7i evin bir \u00fcyesi olmasa da baz\u0131 i\u015flerde size yard\u0131m ederek yeni bir fonksiyonellik kazand\u0131rabilir \u00f6yle de\u011fil mi? Hah i\u015fte s\u0131n\u0131fa eklenecek yeni fonksiyonaliteleri de ekleme s\u00fcrecinde izleyece\u011fimiz strateji bu mant\u0131kla Visitor olarak nitelendirilmektedir. Yani s\u0131n\u0131f\u0131n bir \u00fcyesi olmadan, misafir gibi gelen ve i\u015f yap\u0131p sonra giden farkl\u0131 nesneler kastedilmektedir.<\/p>\n<p>Benzer mant\u0131kla, bu durum ihtiyaca binaen ba\u015fka bir fonksiyonaliteye ihtiya\u00e7 duyuldu\u011funda farkl\u0131 bir misafirin gelmesini ifade etmektedir. Dolay\u0131s\u0131yla bizler de yaz\u0131l\u0131mdaki s\u0131n\u0131flar\u0131m\u0131zda farkl\u0131 fonksiyonalitelere olas\u0131 ihtiya\u00e7lara binaen Visitor pattern sayesinde bunlar\u0131 enjekte edebilir ve ihtiyaca ba\u011fl\u0131 bir \u015fekilde eski visitor&#8217;\u0131n katt\u0131\u011f\u0131 fonksiyonelli\u011fi g\u00f6ndererek yerine yeni visitor&#8217;\u0131n katt\u0131\u011f\u0131 fonksiyonelli\u011fi kullanabiliriz.<\/p>\n<h5>Visitor Design Pattern&#8217;in Stratejisi Nas\u0131ld\u0131r?<\/h5>\n<p><div id=\"attachment_23233\" style=\"width: 299px\" class=\"wp-caption alignleft\"><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/10\/C-Visitor-Design-PatternVisitor-Tasarim-Deseni.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-23233\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/10\/C-Visitor-Design-PatternVisitor-Tasarim-Deseni-289x300.png\" alt=\"C# Visitor Design Pattern(Visitor Tasar\u0131m Deseni)\" width=\"289\" height=\"300\" class=\"size-medium wp-image-23233\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/10\/C-Visitor-Design-PatternVisitor-Tasarim-Deseni-289x300.png 289w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/10\/C-Visitor-Design-PatternVisitor-Tasarim-Deseni.png 520w\" sizes=\"auto, (max-width: 289px) 100vw, 289px\" \/><\/a><p id=\"caption-attachment-23233\" class=\"wp-caption-text\"><span style=\"font-size:10px;\">Kaynak : https:\/\/refactoring.guru\/design-patterns\/visitor<\/span><\/p><\/div>Visitor Design Pattern&#8217;da ihtiya\u00e7 duyulan davran\u0131\u015f\u0131 ger\u00e7ekle\u015ftirecek ya da bir ba\u015fka deyi\u015fle ihtiya\u00e7 duyulan fonksiyonelli\u011fi bar\u0131nd\u0131racak visitor\/ziyaret\u00e7i nesnesi ger\u00e7ek\/orjinal nesneye bir parametre olarak iletilir. Ard\u0131ndan i\u015flevsel a\u00e7\u0131dan davran\u0131\u015f ger\u00e7ek\/orjinal nesne taraf\u0131ndan visitor&#8217;a b\u0131rak\u0131larak ger\u00e7ekle\u015ftirilmesine m\u00fcsaade edilir.<\/p>\n<p>Bu mant\u0131\u011f\u0131 uygulayabilmek i\u00e7in yandaki \u015femada g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere <strong><em>Visitor<\/em><\/strong>, <strong><em>Concrete Visitor<\/em><\/strong>, <strong><em>Element<\/em><\/strong> ve <strong><em>Concrete Element<\/em><\/strong> akt\u00f6rleri e\u015fli\u011finde Visitor pattern stratejisi sergilenebilmektedir. \u015eimdi gelin bu yap\u0131lar\u0131n stratejik rollerini ve operasyon s\u00fcrecinde ne gibi sorumluluklar ta\u015f\u0131d\u0131klar\u0131n\u0131 inceleyelim;<\/p>\n<ul>\n<li><strong><em>Visitor<\/em><\/strong><br \/>\nUygulamada ihtiyaca binaen yeni fonksiyonaliteleri bar\u0131nd\u0131racak olan ziyaret\u00e7i s\u0131n\u0131flar\u0131n\u0131n aray\u00fcz\u00fcd\u00fcr. T\u00fcm ziyaret\u00e7iler bu aray\u00fczden t\u00fcreyerek ger\u00e7ek nesnelere birden fazla davran\u0131\u015f\u0131 <a href=\"https:\/\/www.gencayyildiz.com\/blog\/dependency-injection-nedir-nasil-uygulanir\/\" rel=\"noopener\" target=\"_blank\">dependency injection<\/a> sayesinde kazand\u0131rabilmemizi sa\u011flar.\n<\/li>\n<li><strong><em>Concrete Visitor<\/em><\/strong><br \/>\n\u0130htiya\u00e7 duyulan fonksiyonaliteleri bar\u0131nd\u0131ran somut ziyaret\u00e7i nesneleridir. <em>Visitor<\/em> aray\u00fcz\u00fcnden t\u00fcrerler.\n<\/li>\n<li><strong><em>Element<\/em><\/strong><br \/>\n\u0130htiya\u00e7 duyulan yeni fonksiyonaliteleri ger\u00e7ek nesnelere enjekte edebilmek i\u00e7in gerekli metodun imzas\u0131n\u0131 bar\u0131nd\u0131ran aray\u00fczd\u00fcr. Bahsi ge\u00e7en metot <em>Visitor<\/em> referans\u0131nda bir parametreye sahiptir ve istenilen davran\u0131\u015f\u0131 bar\u0131nd\u0131ran <em>Concrete Visitor<\/em> bu parametre arac\u0131l\u0131\u011f\u0131yla ilgili ger\u00e7ek nesneye iletilir. B\u00f6ylece bu aray\u00fcz\u00fc uygulayan t\u00fcm ger\u00e7ek nesneler sistemdeki <em>Visitor<\/em>&#8216;dan t\u00fcreyen t\u00fcm <em>Concrete Visitor<\/em>&#8216;lar\u0131 b\u00fcnyelerine alarak farkl\u0131 davran\u0131\u015flar\u0131 h\u0131zl\u0131ca sergileyebilir hale gelebilirler.\n<\/li>\n<li><strong><em>Concrete Element<\/em><\/strong><br \/>\nUygulamada yeni fonksiyonalitelerin kazand\u0131r\u0131lmak istendi\u011fi ger\u00e7ek\/orjinal nesnelerdir. Yani, aile \u00fcyesi olmasa da ziyaret\u00e7ilerin u\u011fray\u0131p i\u015f yapt\u0131\u011f\u0131 s\u0131n\u0131ft\u0131r. <em>Element<\/em> aray\u00fcz\u00fcn\u00fc uygular.\n<\/li>\n<\/ul>\n<h5>Pratik Olarak Visitor Design Pattern<\/h5>\n<p>\u015eimdi Visitor pattern&#8217;\u0131 daha iyi anlayabilmek ve stratejik olarak yorumlayabilmek i\u00e7in \u00fc\u00e7 farkl\u0131 \u00f6rnek senaryo \u00fczerinden pratik ger\u00e7ekle\u015ftirelim.<\/p>\n<h6 style=\"color:red;text-align:center;\">1. Senaryo<\/h6>\n<div style=\"color:green;text-align:center;font-size:11px;line-height: 1.5;\">\nBir uygulamada HP ve Lexmark olmak \u00fczere sadece yazd\u0131rma niteliklerine sahip iki printer&#8217;\u0131n var oldu\u011funu ve bu printer&#8217;lara Faks \u00f6zelli\u011finin de eklenmek istendi\u011fini d\u00fc\u015f\u00fcnelim. Haliyle bu ihtiyac\u0131 Visitor Design Pattern&#8217;\u0131 kullanarak \u00e7\u00f6z\u00fcmleyelim.\n<\/div>\n<div style=\"font-size:.875em;\">\n<strong>\u00c7\u00f6z\u00fcm<\/strong><\/p>\n<ul>\n<li><em>Ad\u0131m 1<\/em><br \/>\n\u0130lk olarak <em>Visitor<\/em> aray\u00fcz\u00fcn\u00fc olu\u015fturarak ba\u015flayal\u0131m.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    \/\/Visitor Interface\r\n    public interface IVisitor\r\n    {\r\n        void Visit(HPPrinter hpPrinter);\r\n        void Visit(LexmarkPrinter lexmarkPrinter);\r\n    }\r\n<\/pre>\n<p>Bu aray\u00fcz, Faks \u00f6zelli\u011fine kavu\u015fmas\u0131 gereken t\u00fcm <em>Concrete Element<\/em>&#8216;ler i\u00e7in ilgili davran\u0131\u015f\u0131 bar\u0131nd\u0131ran bir &#8216;Visit&#8217; metodu bar\u0131nd\u0131rmaktad\u0131r. Yukar\u0131da g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere bu metotlar ilgili aray\u00fcz\u00fc implemente eden <em>Concrete Visitor<\/em> taraf\u0131ndan uygulanacak ve i\u00e7leri gerekti\u011fi gibi <em>Concrete Element<\/em>&#8216;e \u00f6zel Faks \u00f6zelli\u011fi ile doldurulacakt\u0131r.<\/p>\n<p>Ayr\u0131ca burada dikkat edilmesi gereken husus <em>Concrete Visitor<\/em> nesnelerinde hangi <em>Concrete Element<\/em> i\u00e7in hangi &#8216;Visit&#8217; metodunun \u00e7al\u0131\u015ft\u0131r\u0131laca\u011f\u0131 parametredeki t\u00fcrden(overload&#8217;\u0131ndan) belli olacakt\u0131r. Buradaki manevray\u0131 birazdan daha net bir \u015fekilde g\u00f6rm\u00fc\u015f olaca\u011f\u0131z.\n<\/li>\n<li><em>Ad\u0131m 2<\/em><br \/>\n\u015eimdi <em>Concrete Element<\/em>&#8216;lere eklenecek yeni fonksiyonaliteyi fiziksel olarak bar\u0131nd\u0131ran <em>Concrete Visitor<\/em> s\u0131n\u0131f\u0131n\u0131 olu\u015ftural\u0131m.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    \/\/Concrete Visitor\r\n    public class FaxVisitor : IVisitor\r\n    {\r\n        public void Visit(HPPrinter hpPrinter)\r\n        {\r\n            \/\/...Process\r\n            Console.WriteLine($&quot;{nameof(HPPrinter)}'dan faks g\u00f6nderiliyor...&quot;);\r\n        }\r\n\r\n        public void Visit(LexmarkPrinter lexmarkPrinter)\r\n        {\r\n            \/\/...Process\r\n            Console.WriteLine($&quot;{nameof(LexmarkPrinter)}'dan faks g\u00f6nderiliyor...&quot;);\r\n        }\r\n    }\r\n<\/pre>\n<p>Yukar\u0131da ilgili <em>Concrete Visitor<\/em> s\u0131n\u0131f\u0131n\u0131n &#8216;IVisitor&#8217; aray\u00fcz\u00fcnden t\u00fcredi\u011fine dikkatinizi \u00e7ekerim. Ayr\u0131ca burada t\u00fcm <em>Concrete Element<\/em>&#8216;ler i\u00e7in gerekli faks operasyonlar\u0131 y\u00fcr\u00fct\u00fclmelidir. Bizler farazi olarak yukar\u0131daki gibi g\u00f6stermelik i\u015flemler ger\u00e7ekle\u015ftirmi\u015f bulunmaktay\u0131z.\n<\/li>\n<li><em>Ad\u0131m 3<\/em><br \/>\nArd\u0131ndan <em>Visitor<\/em> aray\u00fcz\u00fcn\u00fcn referans\u0131 arac\u0131l\u0131\u011f\u0131yla, <em>Concrete Element<\/em>&#8216;lerle yeni fonksiyonaliteyi bar\u0131nd\u0131ran <em>Concrete Visitor<\/em> s\u0131n\u0131f\u0131n\u0131 ili\u015fkilendirebilmek i\u00e7in i\u00e7inde &#8216;Accept&#8217; fonksiyonunu bar\u0131nd\u0131ran bir aray\u00fcz tan\u0131mlayal\u0131m.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public interface IPrinter\r\n    {\r\n        \/\/Yaz\u0131c\u0131larda zaten var olan yazd\u0131rma \u00f6zelli\u011fi.\r\n        void Print();\r\n        \/\/Concrete Visitor nesnesiyle bu Concrete Element nesnesini\r\n        \/\/ili\u015fkilendirip, s\u00fcreci Concrete Visitor nesnesine b\u0131rakmam\u0131z\u0131\r\n        \/\/sa\u011flayan metot.\r\n        void Accept(IVisitor visit);\r\n    }\r\n<\/pre>\n<p>Bu aray\u00fcze g\u00f6z atarsak e\u011fer, i\u00e7erisinde &#8216;Print&#8217; ve &#8216;Accept&#8217; fonksiyonlar\u0131n\u0131n imzalar\u0131 bulunmaktad\u0131r. &#8216;Print&#8217;, yaz\u0131c\u0131lar\u0131m\u0131zda zaten hali haz\u0131rda bulunan yazd\u0131rma \u00f6zelli\u011fini ifade ederken, &#8216;Accept&#8217; ise bu nesneye o anda laz\u0131m olan farkl\u0131\/yeni davran\u0131\u015f\u0131 kazand\u0131racak olan <em>Concrete Visitor<\/em> nesnesiyle ili\u015fki kurulmas\u0131n\u0131 ifade eder. &#8216;Accept&#8217; alm\u0131\u015f oldu\u011fu <em>Concrete Visitor<\/em> nesnesi sayesinde, i\u015flevsel s\u00fcrecin ziyaret\u00e7iye devredilmesini sa\u011flamaktad\u0131r.\n<\/li>\n<li><em>Ad\u0131m 4<\/em><br \/>\nVe son olarak <em>Concrete Element<\/em> nesnelerini tasarlayal\u0131m.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    \/\/Concrete Element\r\n    public class HPPrinter : IPrinter\r\n    {\r\n        public void Print()\r\n        {\r\n            \/\/...Process\r\n            Console.WriteLine($&quot;{nameof(HPPrinter)} yazd\u0131r\u0131yor...&quot;);\r\n        }\r\n\r\n        public void Accept(IVisitor visit)\r\n            =&gt; visit.Visit(this);\r\n    }\r\n<\/pre>\n<p>Yukar\u0131daki kod blo\u011funa g\u00f6z atarsan\u0131z e\u011fer HP yaz\u0131c\u0131s\u0131n\u0131 temsil eden <em>Concrete Element<\/em>&#8216;in in\u015fa edildi\u011fi g\u00f6r\u00fclmektedir. Burada &#8216;Accept&#8217; metoduna dikkat ederseniz e\u011fer kendisine gelen &#8216;IVisitor&#8217; t\u00fcr\u00fcnden nesnenin &#8216;Visit&#8217; metodunu \u00e7a\u011f\u0131rarak <code>this<\/code> keyword\u00fc e\u015fli\u011finde ger\u00e7ek nesneyi <em>Concrete Visitor<\/em> nesnesine g\u00f6ndermekte ve bir \u00f6nceki ad\u0131mda bahsedildi\u011fi gibi i\u015flevsel s\u00fcre\u00e7teki sorumluluk art\u0131k <em>Concrete Visitor<\/em> nesnesine verilmektedir.<\/p>\n<p><em>1. Ad\u0131m<\/em>da vurgulanan bu manevraya Double Dispatch ismi verilmi\u015ftir.<\/p>\n<blockquote><p><em style=\"color:blue;\">Bir objeye, herhangi bir metot \u00fczerinden parametre olarak gelen farkl\u0131 bir objenin, herhangi bir fonksiyonu arac\u0131l\u0131\u011f\u0131yla parametresinden <code style=\"font-size:13px;\">this (C#)<\/code> keyword\u00fc ile ilgili nesneyi kendi i\u00e7erisine alarak kontrol\u00fcn kendisine devredilmesine <u>Double Dispatch<\/u> ad\u0131 verilir.<\/em><\/p><\/blockquote>\n<p>Ayn\u0131 mant\u0131kla Lexmark yaz\u0131c\u0131s\u0131 i\u00e7inde <em>Concrete Element<\/em> s\u0131n\u0131f\u0131n\u0131 tasarlayal\u0131m.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    \/\/Concrete Element\r\n    public class LexmarkPrinter : IPrinter\r\n    {\r\n        public void Print()\r\n        {\r\n            \/\/...Process\r\n            Console.WriteLine($&quot;{nameof(LexmarkPrinter)} yazd\u0131r\u0131yor...&quot;);\r\n        }\r\n\r\n        public void Accept(IVisitor visit)\r\n            =&gt; visit.Visit(this);\r\n    }\r\n<\/pre>\n<\/li>\n<li><em>Ad\u0131m 5<\/em><br \/>\nYap\u0131lan in\u015fa neticesinde art\u0131k tasar\u0131msal testimizi ger\u00e7ekle\u015ftirebiliriz.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    class Program\r\n    {\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            HPPrinter hp = new();\r\n            LexmarkPrinter lexmark = new();\r\n\r\n            hp.Print();\r\n            lexmark.Print();\r\n\r\n            IVisitor fax = new FaxVisitor();\r\n            hp.Accept(fax);\r\n            lexmark.Accept(fax);\r\n        }\r\n    }\r\n<\/pre>\n<p>Yukar\u0131daki kod blo\u011funda 5 ile 9. sat\u0131r aral\u0131\u011f\u0131nda yaz\u0131c\u0131 nesneleri tan\u0131mlanmakta ve &#8216;Print&#8217; fonksiyonu sayesinde yazd\u0131rma i\u015flemleri ger\u00e7ekle\u015ftirilmektedir. Buraya kadar ilgili nesneler kendilerinde dahili olan fonksiyonalitelerini \u00e7al\u0131\u015ft\u0131rmaktad\u0131rlar. 11 ile 13. sat\u0131r aral\u0131\u011f\u0131nda ise yeni bir &#8216;FaxVisitor&#8217; tan\u0131mlanmakta ve bu ziyaret\u00e7i &#8216;Accept&#8217; fonksiyonu ile yaz\u0131c\u0131 s\u0131n\u0131flar\u0131na verilerek, kontrol\u00fcn ziyaret\u00e7iye ge\u00e7ip gerekli faks operasyonlar\u0131n\u0131n yap\u0131lmas\u0131 sa\u011flanmaktad\u0131r.\n<\/li>\n<li><em>Sonu\u00e7<\/em><br \/>\nUygulamay\u0131 derleyip \u00e7al\u0131\u015ft\u0131rd\u0131\u011f\u0131m\u0131z da a\u015fa\u011f\u0131daki ekran g\u00f6r\u00fcnt\u00fcs\u00fcndeki \u00e7\u0131kt\u0131y\u0131 verecektir.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/10\/C-Visitor-Design-PatternVisitor-Tasarim-Deseni-1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/10\/C-Visitor-Design-PatternVisitor-Tasarim-Deseni-1.png\" alt=\"C# Visitor Design Pattern(Visitor Tasar\u0131m Deseni)\" width=\"504\" height=\"265\" class=\"aligncenter size-full wp-image-23272\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/10\/C-Visitor-Design-PatternVisitor-Tasarim-Deseni-1.png 504w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/10\/C-Visitor-Design-PatternVisitor-Tasarim-Deseni-1-300x158.png 300w\" sizes=\"auto, (max-width: 504px) 100vw, 504px\" \/><\/a>\n<\/li>\n<\/ul>\n<\/div>\n<p>\u0130\u015fte bu kadar \ud83d\ude42 G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere dokunulmazl\u0131\u011f\u0131 olan nesnelere yeni davran\u0131\u015flar\u0131 Visitor Design Pattern ile ba\u015far\u0131yla aktarm\u0131\u015f bulunmaktay\u0131z. \u015eimdi di\u011fer \u00f6rnek senaryolara ge\u00e7meden \u00f6nce bir duruma istinaden fark\u0131ndal\u0131k olu\u015fturmakta fayda g\u00f6rmekteyim. Dikkat ederseniz e\u011fer Visitor Design Pattern&#8217;\u0131 belirli nesnelerde kullanabilmek i\u00e7in tabi ki de uygulama ona uygun \u015fekilde tasarlan\u0131p, kodlanmal\u0131d\u0131r. \u00d6yle ha babam deyip herhangi bir &#8216;X&#8217; s\u0131n\u0131f\u0131na filanca visitor&#8217;\u0131 verelim de yeni davran\u0131\u015f kazans\u0131n demek m\u00fcmk\u00fcn de\u011fildir! Bu durum, &#8216;X&#8217; nesnesi visitor alacak \u015fekilde tasarland\u0131\u011f\u0131 s\u00fcrece m\u00fcmk\u00fcnd\u00fcr. Yani bu tasar\u0131m ba\u015fta planlan\u0131p uygulanmal\u0131d\u0131r! Aksi taktirde bu pattern&#8217;\u0131n uygulanmad\u0131\u011f\u0131 bir nesnede yine bu pattern&#8217;\u0131n kullan\u0131lmas\u0131 imkans\u0131zd\u0131r!<\/p>\n<blockquote><p><em style=\"color:#e83e8c;\">Bir s\u0131n\u0131f\u0131n herhangi bir fonksiyonunun i\u015flevini daha da geni\u015fletmek i\u00e7in <a href=\"https:\/\/www.gencayyildiz.com\/blog\/c-decorator-design-patterndecorator-tasarim-deseni\/\" rel=\"noopener\" target=\"_blank\">Decorator<\/a>, s\u0131n\u0131f\u0131n yeni davran\u0131\u015f\/i\u015flev\/fonksiyon kazanmas\u0131 i\u00e7in Visitor kullan\u0131l\u0131r!<\/em><\/p><\/blockquote>\n<p>\u015eimdi di\u011fer senaryolar\u0131m\u0131z\u0131 canland\u0131rmaya ge\u00e7ebiliriz.<\/p>\n<h6 style=\"color:red;text-align:center;\">2. Senaryo<\/h6>\n<div style=\"color:green;text-align:center;font-size:11px;line-height: 1.5;\">\n&#8216;Dot(Nokta)&#8217;, &#8216;Circle(Daire)&#8217; ve &#8216;Rectangle(Dikd\u00f6rtgen)&#8217; \u015feklinde \u00fc\u00e7 geometrik \u015feklin oldu\u011fu bir uygulamada t\u00fcm bu \u015fekilleri JSON yahut XML format\u0131nda bizlere verecek bir \u00e7al\u0131\u015fman\u0131n Visitor Design Pattern ile nas\u0131l yap\u0131ld\u0131\u011f\u0131n\u0131 inceleyelim.\n<\/div>\n<div style=\"font-size:.875em;\">\n<strong>\u00c7\u00f6z\u00fcm<\/strong><br \/>\nArt\u0131k mevcut s\u0131n\u0131flar\u0131m\u0131z\u0131n var olan herhangi bir fonksiyonunun i\u015flevini geni\u015fletmekten ziyade bu s\u0131n\u0131flara yeni bir i\u015flev kazand\u0131rmam\u0131z gerekti\u011finin fark\u0131na vararak Visitor Design Pattern ile \u00e7\u00f6z\u00fcm\u00fc d\u00fc\u015f\u00fcn\u00fcp, ger\u00e7ekle\u015ftirmeye ba\u015flayabiliriz.<\/p>\n<ul>\n<li><em>Ad\u0131m 1<\/em><br \/>\n\u00d6nceki senaryoda oldu\u011fu gibi yine ilk etapta <em>Visitor<\/em> aray\u00fcz\u00fcn\u00fc tasarlayarak ba\u015flayal\u0131m.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    \/\/Visitor Interface\r\n    public interface IShapeVisitor\r\n    {\r\n        void Visit(Dot dot);\r\n        void Visit(Circle circle);\r\n        void Visit(Rectangle rectangle);\r\n    }\r\n<\/pre>\n<\/li>\n<li><em>Ad\u0131m 2<\/em><br \/>\nArd\u0131ndan <em>Concrete Visitor<\/em> s\u0131n\u0131flar\u0131n\u0131 olu\u015ftural\u0131m. Evet, s\u0131n\u0131f(lar)\u0131n\u0131 diyoruz \u00e7\u00fcnk\u00fc bu senaryoda JSON ve XML format\u0131nda veri verecek farkl\u0131 davran\u0131\u015flara ihtiyac\u0131m\u0131z vard\u0131r. Dolay\u0131s\u0131yla her iki davran\u0131\u015f\u0131 sa\u011flayacak iki farkl\u0131 <em>Concrete Visitor<\/em>&#8216;a ihtiyac\u0131m\u0131z olacakt\u0131r.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    \/\/Concrete Visitor\r\n    public class JSONExportVisitor : IShapeVisitor\r\n    {\r\n        public void Visit(Dot dot)\r\n            =&gt; Console.WriteLine(JsonSerializer.Serialize(new\r\n            {\r\n                Location = new Point(dot.X, dot.Y),\r\n                dot.Shape\r\n            }));\r\n\r\n        public void Visit(Circle circle)\r\n            =&gt; Console.WriteLine(JsonSerializer.Serialize(new\r\n            {\r\n                Location = new Point(circle.X, circle.Y),\r\n                circle.Shape,\r\n                circle.Radius\r\n            }));\r\n\r\n        public void Visit(Rectangle rectangle)\r\n            =&gt; Console.WriteLine(JsonSerializer.Serialize(new\r\n            {\r\n                Location = new Point(rectangle.X, rectangle.Y),\r\n                rectangle.Shape,\r\n                Size = new Size(rectangle.Width, rectangle.Height)\r\n            }));\r\n    }\r\n<\/pre>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    \/\/Concrete Visitor\r\n    public class XMLExportVisitor : IShapeVisitor\r\n    {\r\n        void Report(object data)\r\n        {\r\n            XmlSerializer xmlSerializer = new(data.GetType());\r\n            StringWriter stringWriter = new();\r\n            xmlSerializer.Serialize(stringWriter, data);\r\n            Console.WriteLine(stringWriter.ToString());\r\n        }\r\n        public void Visit(Dot dot)\r\n            =&gt; Report(dot);\r\n\r\n        public void Visit(Circle circle)\r\n            =&gt; Report(circle);\r\n\r\n        public void Visit(Rectangle rectangle)\r\n            =&gt; Report(rectangle);\r\n    }\r\n<\/pre>\n<\/li>\n<li><em>Ad\u0131m 3<\/em><br \/>\nS\u0131ra <em>Concrete Element<\/em>&#8216;lerle yeni fonksiyonaliteyi bar\u0131nd\u0131ran <em>Concrete Visitor<\/em> s\u0131n\u0131flar\u0131n\u0131 ili\u015fkilendirebilmek i\u00e7in &#8216;Accept&#8217; fonksiyonunu bar\u0131nd\u0131ran aray\u00fcz\u00fc tan\u0131mlamaya gelmi\u015ftir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public interface IShape\r\n    {\r\n        void Move(int x, int y);\r\n        void Draw();\r\n        void Accept(IShapeVisitor shapeVisitor);\r\n    }\r\n<\/pre>\n<\/li>\n<li><em>Ad\u0131m 4<\/em><br \/>\nSon olarak <em>Concrete Element<\/em> nesnelerimizi tasarlayal\u0131m.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    \/\/Concrete Element\r\n    public class Dot : IShape\r\n    {\r\n        public int X { get; set; }\r\n        public int Y { get; set; }\r\n        public string Shape { get; } = &quot;.&quot;;\r\n\r\n        public void Accept(IShapeVisitor shapeVisitor)\r\n            =&gt; shapeVisitor.Visit(this);\r\n\r\n        public void Draw()\r\n            =&gt; Console.WriteLine(Shape);\r\n\r\n        public void Move(int x, int y)\r\n            =&gt; Console.WriteLine($&quot;Nokta X: {(X = x)} | Y: {(Y = y)} koordinatlar\u0131na ta\u015f\u0131nm\u0131\u015ft\u0131r.&quot;);\r\n    }\r\n<\/pre>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    \/\/Concrete Element\r\n    public class Circle : IShape\r\n    {\r\n        public int Radius { get; set; } = 10;\r\n        public int X { get; set; }\r\n        public int Y { get; set; }\r\n        public string Shape { get; } = &quot;\u2b24&quot;;\r\n\r\n        public void Accept(IShapeVisitor visitor)\r\n            =&gt; visitor.Visit(this);\r\n\r\n        public void Draw()\r\n            =&gt; Console.WriteLine(Shape);\r\n\r\n        public void Move(int x, int y)\r\n            =&gt; Console.WriteLine($&quot;Daire X: {(X = x)} | Y: {(Y = y)} koordinatlar\u0131na ta\u015f\u0131nm\u0131\u015ft\u0131r.&quot;);\r\n    }\r\n<\/pre>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    \/\/Concrete Element\r\n    public class Rectangle : IShape\r\n    {\r\n        public int Width { get; set; } = 20;\r\n        public int Height { get; set; } = 5;\r\n        public int X { get; set; }\r\n        public int Y { get; set; }\r\n        public string Shape { get; } = &quot;\u25ad&quot;;\r\n\r\n        public void Accept(IShapeVisitor visitor)\r\n            =&gt; visitor.Visit(this);\r\n\r\n        public void Draw()\r\n            =&gt; Console.WriteLine(Shape);\r\n\r\n        public void Move(int x, int y)\r\n            =&gt; Console.WriteLine($&quot;Dikd\u00f6rtgen X: {(X = x)} | Y: {(Y = y)} koordinatlar\u0131na ta\u015f\u0131nm\u0131\u015ft\u0131r.&quot;);\r\n    }\r\n<\/pre>\n<\/li>\n<li><em>Ad\u0131m 5<\/em><br \/>\nNihai olarak in\u015fa edilen bu tasar\u0131m\u0131 a\u015fa\u011f\u0131daki gibi test edelim.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    class Program\r\n    {\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            Dot dot = new();\r\n            Circle circle = new();\r\n            Rectangle rectangle = new();\r\n\r\n            dot.Move(3, 5);\r\n            circle.Move(13, 15);\r\n            rectangle.Move(23, 25);\r\n\r\n            Console.WriteLine(&quot;-----------&quot;);\r\n\r\n            IShapeVisitor shapeVisitor = new JSONExportVisitor();\r\n            dot.Accept(shapeVisitor);\r\n            circle.Accept(shapeVisitor);\r\n            rectangle.Accept(shapeVisitor);\r\n\r\n            Console.WriteLine(&quot;-----------&quot;);\r\n\r\n            shapeVisitor = new XMLExportVisitor();\r\n            dot.Accept(shapeVisitor);\r\n            circle.Accept(shapeVisitor);\r\n            rectangle.Accept(shapeVisitor);\r\n        }\r\n    }\r\n<\/pre>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/10\/C-Visitor-Design-PatternVisitor-Tasarim-Deseni-2.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/10\/C-Visitor-Design-PatternVisitor-Tasarim-Deseni-2.png\" alt=\"C# Visitor Design Pattern(Visitor Tasar\u0131m Deseni)\" width=\"885\" height=\"420\" class=\"aligncenter size-full wp-image-23292\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/10\/C-Visitor-Design-PatternVisitor-Tasarim-Deseni-2.png 885w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/10\/C-Visitor-Design-PatternVisitor-Tasarim-Deseni-2-300x142.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/10\/C-Visitor-Design-PatternVisitor-Tasarim-Deseni-2-768x364.png 768w\" sizes=\"auto, (max-width: 885px) 100vw, 885px\" \/><\/a>\n<\/li>\n<\/ul>\n<\/div>\n<p>Evet, bu \u00f6rne\u011fimizde i\u015fte bu kadar. \u015eimdi konuya dair son teorik temaslarda bulunmadan \u00f6nce s\u0131ca\u011f\u0131 s\u0131ca\u011f\u0131na sonuncu senaryomuz \u00fczerinden pratik ger\u00e7ekle\u015ftirelim.<\/p>\n<h6 style=\"color:red;text-align:center;\">3. Senaryo<\/h6>\n<div style=\"color:green;text-align:center;font-size:11px;line-height: 1.5;\">\n&#8216;TextBox&#8217;, &#8216;ComboBox&#8217; ve &#8216;RadioButton&#8217; gibi toollar\u0131n hem stillerini tasarlamam\u0131z\u0131 sa\u011flayacak hem de member bilgilerini verecek olan \u00e7al\u0131\u015fmay\u0131 Visitor Design Pattern ile ger\u00e7ekle\u015ftirelim.\n<\/div>\n<div style=\"font-size:.875em;\">\n<strong>\u00c7\u00f6z\u00fcm<\/strong><br \/>\nNe demi\u015ftik! Mevcudiyetteki s\u0131n\u0131flara yeni bir i\u015flev kazand\u0131r\u0131lmas\u0131 gerekti\u011fi zaman akl\u0131m\u0131za Visitor Design Pattern gelmeli&#8230; Haliyle bu senaryoda da mevcut olan toollara stil \u00e7al\u0131\u015fmas\u0131 ve member bilgisi davran\u0131\u015flar\u0131 eklenece\u011finden dolay\u0131 \u00e7\u00f6z\u00fcm\u00fc ilgili pattern ile d\u00fc\u015f\u00fcnmeye ba\u015fl\u0131yoruz. Tabi bu senaryomuzu di\u011ferlerine nazaran daha yal\u0131n bir \u015fekilde uygulayacak ve direkt \u00e7\u00f6z\u00fcm odakl\u0131 bir yakla\u015f\u0131m sergileyece\u011fiz.<\/p>\n<ul>\n<li><em>Ad\u0131m 1<\/em><br \/>\n<em>Visitor<\/em> aray\u00fcz\u00fcn\u00fc olu\u015ftural\u0131m.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    \/\/Visitor Interface\r\n    public interface IToolVisitor\r\n    {\r\n        void Visit(TextBox textBox);\r\n        void Visit(ComboBox comboBox);\r\n        void Visit(RadioButton radioButton);\r\n    }\r\n<\/pre>\n<\/li>\n<li><em>Ad\u0131m 2<\/em><br \/>\n<em>Concrete Visitor<\/em> s\u0131n\u0131flar\u0131n\u0131 olu\u015ftural\u0131m.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    \/\/Concrete Visitor\r\n    public class MemberDetailVisitor : IToolVisitor\r\n    {\r\n        public void Visit(TextBox textBox)\r\n            =&gt; Console.WriteLine($&quot;{nameof(TextBox)} tool detay\u0131...&quot;);\r\n\r\n        public void Visit(ComboBox comboBox)\r\n            =&gt; Console.WriteLine($&quot;{nameof(ComboBox)} tool detay\u0131...&quot;);\r\n\r\n        public void Visit(RadioButton radioButton)\r\n            =&gt; Console.WriteLine($&quot;{nameof(RadioButton)} tool detay\u0131...&quot;);\r\n    }\r\n<\/pre>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    \/\/Concrete Visitor\r\n    public class StyleVisitor : IToolVisitor\r\n    {\r\n        public void Visit(TextBox textBox)\r\n        {\r\n            \/\/...Process\r\n            Console.WriteLine($&quot;{nameof(TextBox)}'a stil uygulanm\u0131\u015ft\u0131r.&quot;);\r\n        }\r\n\r\n        public void Visit(ComboBox comboBox)\r\n        {\r\n            \/\/...Process\r\n            Console.WriteLine($&quot;{nameof(ComboBox)}'a stil uygulanm\u0131\u015ft\u0131r.&quot;);\r\n        }\r\n\r\n        public void Visit(RadioButton radioButton)\r\n        {\r\n            \/\/...Process\r\n            Console.WriteLine($&quot;{nameof(RadioButton)}'a stil uygulanm\u0131\u015ft\u0131r.&quot;);\r\n        }\r\n    }\r\n<\/pre>\n<\/li>\n<li><em>Ad\u0131m 3<\/em><br \/>\n&#8216;Accept&#8217; fonksiyonunu uygulatacak olan aray\u00fcz\u00fc olu\u015ftural\u0131m.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public interface ITool\r\n    {\r\n        void Accept(IToolVisitor visitor);\r\n        void Use();\r\n    }\r\n<\/pre>\n<\/li>\n<li><em>Ad\u0131m 4<\/em><br \/>\n<em>Concrete Element<\/em> s\u0131n\u0131flar\u0131n\u0131 olu\u015ftural\u0131m.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    \/\/Concrete Element\r\n    public class TextBox : ITool\r\n    {\r\n        public string Name { get; set; }\r\n        public Color FontColor { get; set; }\r\n        public Color BackGroundColor { get; set; }\r\n\r\n        public void Accept(IToolVisitor visitor)\r\n            =&gt; visitor.Visit(this);\r\n\r\n        public void Use()\r\n            =&gt; Console.WriteLine($&quot;{nameof(TextBox)} kullan\u0131lm\u0131\u015ft\u0131r.&quot;);\r\n    }\r\n<\/pre>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    \/\/Concrete Element\r\n    public class ComboBox : ITool\r\n    {\r\n        public bool ScrollBar { get; set; }\r\n\r\n        public void Accept(IToolVisitor visitor)\r\n            =&gt; visitor.Visit(this);\r\n\r\n        public void Use()\r\n            =&gt; Console.WriteLine($&quot;{nameof(ComboBox)} kullan\u0131lm\u0131\u015ft\u0131r.&quot;);\r\n    }\r\n<\/pre>\n<p>ban<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    \/\/Concrete Element\r\n    public class RadioButton : ITool\r\n    {\r\n        public bool Selected { get; set; } = false;\r\n        public string Text { get; set; }\r\n\r\n        public void Accept(IToolVisitor visitor)\r\n            =&gt; visitor.Visit(this);\r\n\r\n        public void Use()\r\n            =&gt; Console.WriteLine($&quot;{nameof(RadioButton)} kullan\u0131lm\u0131\u015ft\u0131r.&quot;);\r\n    }\r\n<\/pre>\n<\/li>\n<li><em>Ad\u0131m 5<\/em><br \/>\nTest Edelim.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    class Program\r\n    {\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            TextBox textBox = new();\r\n            ComboBox comboBox = new();\r\n            RadioButton radioButton = new();\r\n\r\n            textBox.Use();\r\n            comboBox.Use();\r\n            radioButton.Use();\r\n\r\n            Console.WriteLine(&quot;--------------&quot;);\r\n\r\n            IToolVisitor toolVisitor = new MemberDetailVisitor();\r\n            textBox.Accept(toolVisitor);\r\n            comboBox.Accept(toolVisitor);\r\n            radioButton.Accept(toolVisitor);\r\n\r\n            Console.WriteLine(&quot;--------------&quot;);\r\n\r\n            toolVisitor = new StyleVisitor();\r\n            textBox.Accept(toolVisitor);\r\n            comboBox.Accept(toolVisitor);\r\n            radioButton.Accept(toolVisitor);\r\n        }\r\n    }\r\n<\/pre>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/10\/C-Visitor-Design-PatternVisitor-Tasarim-Deseni-3.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/10\/C-Visitor-Design-PatternVisitor-Tasarim-Deseni-3.png\" alt=\"C# Visitor Design Pattern(Visitor Tasar\u0131m Deseni)\" width=\"352\" height=\"181\" class=\"aligncenter size-full wp-image-23301\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/10\/C-Visitor-Design-PatternVisitor-Tasarim-Deseni-3.png 352w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/10\/C-Visitor-Design-PatternVisitor-Tasarim-Deseni-3-300x154.png 300w\" sizes=\"auto, (max-width: 352px) 100vw, 352px\" \/><\/a>\n<\/li>\n<\/ul>\n<\/div>\n<blockquote><p><em style=\"color:purple;\">Visitor Design Pattern, yeni fonksiyonlar\u0131n \u00fcretim maliyetlerini ana nesnelerden ar\u0131nd\u0131r\u0131p olu\u015fturabilmek i\u00e7in kullan\u0131l\u0131r!<\/em><\/p><\/blockquote>\n<h5>Lehte ve Aleyhte Durumlar<\/h5>\n<table>\n<thead>\n<tr>\n<th>\u2713<\/th>\n<th>\uab55<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><em><strong><a href=\"https:\/\/www.gencayyildiz.com\/blog\/acik-kapali-prensibiopen-closed-principle-ocp\/\" rel=\"noopener\" target=\"_blank\">A\u00e7\u0131k Kapal\u0131 Prensibi(Open Closed Principle \u2013 OCP)<\/a><\/strong><\/em><br \/>\n<em>Concrete Element<\/em> s\u0131n\u0131flar\u0131n\u0131 de\u011fi\u015ftirmeksizin farkl\u0131 davran\u0131\u015flar\u0131 kazand\u0131rabilmektedir.\n<\/td>\n<td>S\u00fcrece yeni bir <em>Concrete Element<\/em> eklendi\u011finde <em>Visitor<\/em> aray\u00fcz\u00fc ile birlikte <em>Concrete Visitor<\/em> s\u0131n\u0131flar\u0131 g\u00fcncellenmelidir!<\/td>\n<\/tr>\n<tr>\n<td>\n<em><strong><a href=\"https:\/\/www.gencayyildiz.com\/blog\/tek-sorumluluk-prensibisingle-responsibility-principle-srp\/\" rel=\"noopener\" target=\"_blank\">Tek Sorumluluk Prensibi(Single Responsibility Principle \u2013 SRP)<\/a><\/strong><\/em><br \/>\n<em>Concrete Visitor<\/em> s\u0131n\u0131flar\u0131, tek bir davran\u0131\u015fa odaklanm\u0131\u015ft\u0131r.\n<\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h5>Kritik<\/h5>\n<blockquote><p><em style=\"color:green;\">Visitor Design Pattern ile kod <code>if(x is Type1) ... else if(x is Type2) ...<\/code> gibi kontrollerden ar\u0131nd\u0131r\u0131lm\u0131\u015f olur&#8230;<\/em><\/p><\/blockquote>\n<p>Evet, Visitor pattern bir grup s\u0131n\u0131f \u00fcyesine dahil edilecek yeni fonksiyonaliteyi sa\u011flarken, overloading sayesinde <code style=\"color:red; font-size:13px;\">if(x is Type1) ... else if(x is Type2) ...<\/code> gibi kontrollerden kodu ar\u0131nd\u0131r\u0131r ve b\u00f6ylece daha dinamik ve geli\u015ftirilebilir bir yap\u0131 ortaya koyar.<\/p>\n<p>Bunu genellikle birden \u00e7ok t\u00fcrden nesne bar\u0131nd\u0131ran koleksiyonlarda toplu i\u015flemler yaparken kullanabiliriz. \u00d6rne\u011fin; i\u00e7erisinde &#8216;Product&#8217; ve &#8216;Employee&#8217; nesnelerini kar\u0131\u015f\u0131k olarak bar\u0131nd\u0131ran bir koleksiyondaki &#8216;Product&#8217; ve &#8216;Employee&#8217; bazl\u0131 toplam gideri Visitor Design Pattern ile hesaplayan a\u015fa\u011f\u0131daki yap\u0131y\u0131 inceleyiniz.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    class Program\r\n    {\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            List&lt;IOperation&gt; operations = new()\r\n            {\r\n                new Product { ProductId = 1, Price = 10 },\r\n                new Employee { EmployeeId = 1, Salary = 20 },\r\n                new Product { ProductId = 2, Price = 5 },\r\n                new Employee { EmployeeId = 2, Salary = 7 },\r\n                new Product { ProductId = 3, Price = 21 },\r\n                new Employee { EmployeeId = 3, Salary = 13 },\r\n                new Product { ProductId = 4, Price = 33 },\r\n                new Employee { EmployeeId = 4, Salary = 12 },\r\n                new Product { ProductId = 5, Price = 15 },\r\n                new Employee { EmployeeId = 6, Salary = 14 },\r\n            };\r\n\r\n            CalculateCostVisitor calculateCostVisitor = new();\r\n            operations.ForEach(o =&gt; o.Accept(calculateCostVisitor));\r\n\r\n            Console.WriteLine($&quot;Calculated Employee Cost : {calculateCostVisitor.CalculatedEmployeeCost}&quot;);\r\n            Console.WriteLine($&quot;Calculated Product Cost : {calculateCostVisitor.CalculatedProductCost}&quot;);\r\n        }\r\n    }\r\n\r\n    \/\/Visitor Interface\r\n    public interface IVisitor\r\n    {\r\n        void Visit(Product product);\r\n        void Visit(Employee employee);\r\n    }\r\n\r\n    \/\/Concrete Visitor\r\n    public class CalculateCostVisitor : IVisitor\r\n    {\r\n        public int CalculatedProductCost { get; set; }\r\n        public int CalculatedEmployeeCost { get; set; }\r\n\r\n        public void Visit(Product product)\r\n            =&gt; CalculatedProductCost += product.Price;\r\n\r\n        public void Visit(Employee employee)\r\n            =&gt; CalculatedEmployeeCost += employee.Salary;\r\n    }\r\n\r\n    public interface IOperation\r\n    {\r\n        void Accept(IVisitor visitor);\r\n    }\r\n\r\n    \/\/Concrete Element\r\n    public class Product : IOperation\r\n    {\r\n        public int ProductId { get; set; }\r\n        public int Price { get; set; }\r\n\r\n        public void Accept(IVisitor visitor)\r\n            =&gt; visitor.Visit(this);\r\n    }\r\n\r\n    \/\/Concrete Element\r\n    public class Employee : IOperation\r\n    {\r\n        public int EmployeeId { get; set; }\r\n        public int Salary { get; set; }\r\n\r\n        public void Accept(IVisitor visitor)\r\n            =&gt; visitor.Visit(this);\r\n    }\r\n<\/pre>\n<h5>Di\u011fer Kal\u0131plarla \u0130li\u015fkisi<\/h5>\n<p>Visitor Design Pattern&#8217;\u0131n, s\u0131n\u0131flara yeni fonksiyonalite ekleme amac\u0131ndan \u00f6t\u00fcr\u00fc genellikle ak\u0131llara <a href=\"https:\/\/www.gencayyildiz.com\/blog\/c-decorator-design-patterndecorator-tasarim-deseni\/\" rel=\"noopener\" target=\"_blank\">Decorator Design Pattern<\/a> gelmektedir. Lakin Decorator, bir s\u0131n\u0131fa yeni bir metot eklemekten ziyade mevcut metodun i\u015flevselli\u011fini zenginle\u015ftirmek i\u00e7in kullan\u0131lmaktad\u0131r.<\/p>\n<h5>Visitor Pattern&#8217;\u0131n Extension Function \u0130le Benzerli\u011fi<\/h5>\n<p>C# programlama dili, kaynak kodu elimizde olmayan\/eri\u015filemeyen yahut de\u011fi\u015fmemesi gereken bir s\u0131n\u0131fa yeni bir fonksiyonalite\/operasyon ekleyebilmemiz i\u00e7in <a href=\"https:\/\/www.gencayyildiz.com\/blog\/extension-metod-yazilisi-ve-kullanimi\/\" rel=\"noopener\" target=\"_blank\">Extension Function<\/a> \u00f6zelli\u011fini sunmaktad\u0131r. Extension Function, C# a\u00e7\u0131s\u0131ndan bir <code>syntactic sugar<\/code>&#8216;d\u0131r. Yani C# syntax&#8217;\u0131n da var olan bir \u00f6zelliktir.<\/p>\n<p>\u0130lgilenenlerin faydalanmas\u0131 dile\u011fiyle&#8230;<br \/>\nSonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere&#8230;<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar&#8230;<\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, Bu i\u00e7eri\u011fimizde Davran\u0131\u015fsal Tasar\u0131m Kal\u0131plar\u0131ndan(Behavioral Patterns) olan Visitor Tasar\u0131m Desenini(Visitor Design Pattern) tam teferruatl\u0131 inceleyecek ve hangi senaryolarda, ne ama\u00e7la bu pattern&#8217;\u0131 kullanabilece\u011fimize dair teorik sorgulamada bulunurken bir yandan da pratiksel olarak birka\u00e7&#46;&#46;&#46;<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":23233,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2739,153],"tags":[4414,2197,4412,4413,4411,4410],"class_list":["post-23208","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net-core","category-design-pattern","tag-double-dispatch","tag-syntactic-sugar","tag-visitor","tag-visitor-d-p","tag-visitor-design-pattern","tag-visitor-tasarim-desenini"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/23208","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/comments?post=23208"}],"version-history":[{"count":103,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/23208\/revisions"}],"predecessor-version":[{"id":23316,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/23208\/revisions\/23316"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/23233"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=23208"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=23208"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=23208"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}