jeudi 30 juillet 2020

How can we implement a stateful visitor pattern?

I have a class similar to Node (There are multiple derivatives of Node). The RecursiveFunction processes the sourceNode referenced by the current node which internally processes its sourceNode. The structure of the graph formed can either be a tree or a DAG. In order to avoid re-processing the same node and reuse the result of the previous processing I need to maintain a map of processed entries and remember a node had already been visited. Adding iteration into node class is not right. One consideration was to use visitor pattern. But then the visitor instance should internal keep a map of previously visited nodes. Essentially introducing state into the visitor. The problem with that is, we cannot enforce that the client should always pass a new visitor instance when RecursiveFunction is called

Class Node {
    public Node SourceNode;

    public Node RecursiveFunction1() {
        //Some logic
        this.SourceNode.RecursiveFunction();
        // Some logic
        return transformedNode;
    }

    public Node RecursiveFunction2(someInput..) {
        //Some logic
        this.SourceNode.RecursiveFunction2(someInput..);
        // Some logic
        return transformedNode;
    }
}

With visitor pattern:

Class Node {
    public Node SourceNode;

    public Node RecursiveFunction(IVisitor1 visitor) {
        return visitor.RecursiveFunction(this);
    }

    public Node RecursiveFunction2(IVisitor2 visitor, SomeInputs..) {
        return visitor.RecursiveFunction2(this, SomeInputs..);
    }
}

class Visitor1 : IVisitor1 {
    private Dictionary<Node,Node> map;

    public Node RecursiveFunction(DerivedNode1 x) {
        if(!this.map.Contains(x)) {
            // Some logic
            x.SourceNode.RecursiveFunction(this);
           // Some logic

            map[x] = result;
        }

        return map[x];
     }

    public Node RecursiveFunction(DerivedNode2 x) {
        if(!this.map.Contains(x)) {
            // Some logic
            x.SourceNode.RecursiveFunction(this);
           // Some logic

            map[x] = result;
        }

        return map[x];
     }
    
}


P.S: The psudo code was just a high level thought to articulate my thought process better. Have not coded it. Could be utterly wrong. Any alternate designs are well appreciated. Goal is to keep iteration away from Node. And in the visitor pattern approach I'm also having to check/populate the map for every function in every visitor. This is a lot of duplication. If the suggestion is to use iterator pattern please provide psudo code as I could not quite grasp how to get that working for this model.

Aucun commentaire:

Enregistrer un commentaire