How to add concrete elements in Runtime in the Visitor project pattern?

Asked

Viewed 91 times

2

I have a question regarding Design Pattern Visitor.

From my studies, if you want to add a new concrete element to the pattern you should add a new abstract method in the Visitor interface and implement this method in the concrete Visitors. This requires the software to be stopped, to be recompiled... anyway.

There is some variation of implementation of this standard where it is possible to add new concrete elements in runtime, as plugin, for example?

1 answer

3

Perhaps it is enough to create a method that serves to visit any object that implements an interface, rather than the final concrete type. Thus, a single abstract method would be responsible for visiting several types of concrete objects that implement that interface, including objects imported via plug-in.

This way it is possible to add more types dynamically, however it would limit the work of the method, which would work on the interface and not on the concrete type... this limitation can be circumvented by making the interface with a method Accept which takes a Visitor object, and is able to pass sub-objects to Visitor.

Example in C#:

class Concrete
{
}

/// <summary>
/// Interface de plug-in que pode ser visitada por um Visitor.
/// </summary>
interface IPlugin
{
    void Accept(Visitor visitor);
}

class Plugin1 : IPlugin
{
    public Concrete Concrete { get; set; }

    public void Accept(Visitor visitor)
    {
        visitor.Visit(this.Concrete);
    }
}

abstract class Visitor
{
    public void Visit(object obj)
    {
        if (obj is Concrete)
            this.Visit(obj as Concrete);
        else if (obj is IPlugin)
            this.Visit(obj as IPlugin);
    }

    public abstract void Visit(Concrete concrete);

    public virtual void Visit(IPlugin plugin)
    {
        plugin.Accept(this);
    }
}
  • Hello Miguel. Interesting your solution, but I don’t understand how I can get around the fact that this unique visitor method works on an interface and not on a concrete type.

  • Everything you want with the concrete type will have to be done through the interface, because the visitor method only knows the interface. For example, if there is a property Nome in the plugins and you want to change the name, so this property will have to be in the interface IPlugin and implemented in all concrete classes that implement the same.

  • But what if I add a new element with particular attributes and want to manipulate them from the implementation of this visit()? No way?

  • It will not be possible for the visiting method to manipulate parts of the concrete object that it does not know. What you can do is implement in the interface methods to list and manipulate such attributes, via string, or use reflection (ai depends on the language).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.