1

I have a few operations to make over many similar elements. I would like to collect data from each element firstly and next bind all the data to an object (binding is expensive operation so I need to do it once).

Is it consistent with the Visitor pattern?

Example of my problem:

class Element {
    public $name;

    public function accept(VisitorInterface $visitor) {
        $visitor->visitElement($this);
    }
}

class SimpleVisitor implements VisitorInterface {
    private $data = [];

    public function visitElement(Element $element) {
        $this->data[] = $element->name;
    }

    public function bindData(Object $object) {
        $object->setNames($this->data);
    }
}

$visitor = new SimpleVisitor();
$object = new Object();

$elementA = new Element();
$elementA->name = 'test1';
$elementA->accept($visitor);

$elementB = new Element();
$elementB->name = 'test2';
$elementB->accept($visitor);

$visitor->bindData($object);
deem
  • 207
  • 1
  • 6
  • 1
    Yes, it appears to fit the visitor pattern more or less ...however, **this pattern is 100% pointless if you have just one type of element and visitor!** :/ Also, the statefullness and "bindData" is not how visitors are meant to be used. ...just because you have `visit` and `accept` methods doesn't make it a visitor pattern. What you've written sounds more like an indirect registry to me ...which is awkward anyway. – dagnelies Jan 18 '17 at 20:22
  • Ok, but do you know any design pattern that fit my needs? – deem Jan 18 '17 at 21:05
  • It's unclear what your needs are. ("I would like to collect data from each element firstly and next bind all the data to an object") ...well, just do that. Where is the difficulty/issue? Why do you need a "pattern" for it? – dagnelies Jan 19 '17 at 08:15
  • @dagnelies in details... I have a bunch of elements. There is a lot of simple text or numeric elements, but there are complex nested types also. The complex types require making additional external API requests. I don't want to put this "heavy" logic in the element object class. I would like to collect all this kind of values at first and make the request for the whole collection next. So, I will do a single API connection only. – deem Jan 19 '17 at 11:28

1 Answers1

2

In my opinion, it is consistent. You are just implementing stateful visitor. Take a look at my answer to this question. There are some similarities here with the way you are implementing visitor, in terms of initializing visitor first, and then invoking other methods of that visitor.

The only thing that might be somewhat inconsistent with visitor pattern is the bindData method. In my opinion, this is unnecessary here. You already have object->setName method. Use that method, and just expose data field for reading in SimpleVisitor class.

Vladimir Stokic
  • 2,943
  • 14
  • 25