diff --git a/Program.cs b/Program.cs
index b09cc41..6377c63 100644
--- a/Program.cs
+++ b/Program.cs
@@ -23,6 +23,7 @@ using design_patterns.behavioral.observer;
using design_patterns.behavioral.state;
using design_patterns.behavioral.strategy;
using design_patterns.behavioral.template;
+using design_patterns.behavioral.visitor;
namespace design_patterns
{
@@ -59,7 +60,8 @@ namespace design_patterns
// await ObserverSample.Run();
// await StateSample.Run();
// await StrategySample.Run();
- await TemplateSample.Run();
+ // await TemplateSample.Run();
+ await VisitorSample.Run();
}
catch (System.Exception ex)
{
diff --git a/behavioral/visitor/VisitorSample.cs b/behavioral/visitor/VisitorSample.cs
new file mode 100644
index 0000000..2ff6083
--- /dev/null
+++ b/behavioral/visitor/VisitorSample.cs
@@ -0,0 +1,108 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace design_patterns.behavioral.visitor
+{
+ ///
+ /// Visitor is a behavioral design pattern that lets you
+ /// separate algorithms from the objects on which they operate.
+ ///
+ /// Use it when:
+ /// - you need to perform an operation on all elements of a
+ /// complex object structure (for example, an object tree).
+ /// - to clean up the business logic of auxiliary behaviors.
+ /// - a behavior makes sense only in some classes of a class hierarchy,
+ /// but not in others.
+ ///
+ public class VisitorSample
+ {
+ public static async Task Run()
+ {
+ Console.WriteLine("Behavioral - Visitor");
+ List components = new List();
+ components.Add(new ComponentA());
+ components.Add(new ComponentB());
+
+ System.Console.WriteLine("With Visitor1 ....");
+ Visitor1 visitor1 = new Visitor1();
+ foreach (var component in components)
+ {
+ component.Visit(visitor1);
+ }
+
+ System.Console.WriteLine("With Visitor2 ....");
+ Visitor2 visitor2 = new Visitor2();
+ foreach (var component in components)
+ {
+ component.Visit(visitor2);
+ }
+ }
+
+ // implemented by components/hierarchy that needs to be visited
+ public interface IComponent {
+ void Visit(IVisitor visitor);
+ }
+
+ public class ComponentA : IComponent {
+ public void IamComponentA() {
+ System.Console.WriteLine("IamComponentA");
+ }
+
+ public void Visit(IVisitor visitor)
+ {
+ visitor.VisitComponentA(this);
+ }
+ }
+
+ public class ComponentB : IComponent {
+ public void SomeStuffFromComponentB() {
+ System.Console.WriteLine("SomeStuffFromComponentB");
+ }
+
+ public void Visit(IVisitor visitor)
+ {
+ visitor.VisitComponentB(this);
+ }
+ }
+
+ // visitor interface declares a set of visiting methods that correspond
+ // to component classes. The signature of a visiting method allows the
+ // visitor to identify the exact class of the component that it's dealing
+ // with.
+ public interface IVisitor {
+ void VisitComponentA(ComponentA component);
+ void VisitComponentB(ComponentB component);
+ }
+
+ public class Visitor1 : IVisitor
+ {
+ public void VisitComponentA(ComponentA component)
+ {
+ System.Console.Write($"From {this.GetType().Name} ");
+ component.IamComponentA();
+ }
+
+ public void VisitComponentB(ComponentB component)
+ {
+ System.Console.Write($"From {this.GetType().Name} ");
+ component.SomeStuffFromComponentB();
+ }
+ }
+
+ public class Visitor2 : IVisitor
+ {
+ public void VisitComponentA(ComponentA component)
+ {
+ System.Console.Write($"From {this.GetType().Name} ");
+ component.IamComponentA();
+ }
+
+ public void VisitComponentB(ComponentB component)
+ {
+ System.Console.Write($"From {this.GetType().Name} ");
+ component.SomeStuffFromComponentB();
+ }
+ }
+ }
+}
\ No newline at end of file