user1357872 user1357872 - 2 months ago 21
C# Question

understanding Visitor design pattern in c#

I have the below classes for datastructure and logic.

public class clsCustomer : ICustomerElements
{
public void accept(IVisitor objVisitor)
{
objVisitor.visit(this);

foreach (clsAddress objAddress in objAddresses)
{
objAddress.accept(objVisitor);
}
}
public string strCustomerName = "";
public ArrayList objAddresses = new ArrayList();
}

public class clsVisitorString : IVisitor
{
public string strData;
public void visit(clsCustomer obj)
{
strData = "Customer Name :- " + obj.strCustomerName + "\r\n";
}
public void visit(clsAddress obj)
{
strData = strData + "Address 1 :- " + obj.strAddress1 + "\r\n";
strData = strData + "Address 2 :- " + obj.strAddress2 + "\r\n";
}
public void visit(clsPhone obj)
{
strData = strData + "Phone :- " + obj.strPhoneNumber + "\r\n";
}
}



  1. So as per the visitor design pattern, the logic should be decoupled
    from the other layers. But here if i change anything in the
    clscustomer class it will impact the visitor class also. for eg: im adding a new datastructure, then the visitor class also will need to change.

  2. Is this the right approach ?

  3. will this not break the Open close principle?


Answer
  1. [...] But here if i change anything in the clsCustomer class it will impact the visitor class also.

Of course it will. Imagine you implemented the behaviour of clsVisitorString without the visitor pattern. Naturally it would be a method in the clsCustomer class, probably implemented according to some interface. Lets call this method public string Print().

  1. Will this not break the Open close principle?

Consider that you want to give your clsCustomer a strCustomerSurname and want to print that as well. Then you'd have to change Print(). Thus you are violating the OCP regardless whether you are using the visitor pattern or not. That's because the visitor pattern's purpose is not to protect developers from those kind of changes.

  1. Is this the right approach?

Whether the visitor pattern is the right tool to use depends on the scenario. It has a very specific purpose, which is to protect a type hierarchy that's not subject to structural changes (i.e. no new types are added to the hierarchy and the internal structure stays the same for all types) from behavioural changes (i.e. a function is to be added to the hierarchy that operates on all the types).

Of course there is a grey area. Structural changes are still manageable to some extent, but at a certain point a visitor pattern implementation in the wrong scenario will turn into a maintenance nightmare.

Below is a UML diagram illustrating the typical "attack vectors" of change and what they lead to in the context of the visitor pattern. The existing types are colored blue; new types and modifications on types are either red or green.

enter image description here