A simple but non-contrived example of the Visitor pattern.
Here are the main classes.
// Interface for the visiting system permit populator
public interface IPopulatorVisitor
{
void PopulateVisit(ISet<int> permitSystemsSet);
}
public interface IPermitSystems
{
void AcceptPopulator(IPopulatorVisitor populatorVisitor);
bool PermitRequired(int systemId);
}
// This is the Visitor target
// It stores a set of systems that require a permit for entry
public class PermitSystems : IPermitSystems
{
HashSet<int> _permitRequiredSystemIds = new HashSet<int>();
// Accept Visitors here
public void AcceptPopulator(IPopulatorVisitor populatorVisitor)
{
populatorVisitor.PopulateVisit(_permitRequiredSystemIds);
}
public bool PermitRequired(int systemId)
{
bool res = _permitRequiredSystemIds.Contains(systemId);
return res;
}
}
The Visitor class, this has removed the responsibility for deserialising
the permit data from the the PermitSystems class. In this case the data is
stored in 'JSonl' form, but it could be stored in other formats and a different
visitor would be provided
public class PermitSystemsJsonlDeserialiserVisitor
: IPopulatorVisitor
{
FileInfo _jsonlFilePath;
public void Initialise(string jsonlFilePath)
{
_jsonlFilePath = new FileInfo(jsonlFilePath);
}
public void PopulateVisit(ISet<int> permitSystemsSet)
{
List permitReqdSystems;
if (_jsonlFilePath.TryLoadFromJson(out permitReqdSystems))
{
if (permitReqdSystems != null)
{
PopulateImpl(permitSystemsSet, permitReqdSystems);
}
}
}
private static void PopulateImpl(ISet<int> permitSystemsSet,
List permitReqdSystems)
{
foreach (var sys in permitReqdSystems)
{
Trace.WriteLine(" Permit required for id=" + sys.id + " name=" + sys.name +
" permitRequired=" + sys.permitRequired);
permitSystemsSet.Add(sys.id);
}
}
}
Some sample code to bring it all together
[Test]
public void PermitSystemsExperiment()
{
IPermitSystems permitSystems = new PermitSystems();
PermitSystemsJsonlDeserialiserVisitor jdv = new PermitSystemsJsonlDeserialiserVisitor();
jdv.Initialise(TestFilePaths.PermitRequiredSystemsJSonFilePath);
permitSystems.AcceptPopulator(jdv);
Assert.That(true == permitSystems.PermitRequired(19054));
Assert.That(false == permitSystems.PermitRequired(26));
}