Factory Pattern – Should a Factory Always Create a New Object?

cdependency-injectiondesign-patternsfactoryrepository

we have a hierarchical structure where every node is derived from a node base class public Node(INodeFactory nodeFactory). The factory is injected so the node can create its child nodes using Get(int id)

At a later moment some nodes need a reference to another node in the structure. The information necessary to get the reference might change at runtime and is not necessarily available When the node object was constructed. Basically this method signature looks the same and is Get(int id). This time no new object should be created but an existing one should be returned.

Our first attempt was to pass a INodeLocator that would search for the node. First of all we are not sure 'locator' is a good name and if we are missing some pattern here, maybe the repository pattern (but only to look up?). Second we noticed the method signature is the same.

We were considering to switch the factory from 'creation' to 'lookup' mode after the initial tree has been created but that won't work since later on nodes need to be created as well.

For the 'locator' logic we were thinking of searching (iterating) through the nodes but maybe it is better to keep track of them in a flat dictionary. But then the problem arises that the factory can add to the dictionary but doesn't manage the lifetime. What should happen when a node gets removed.

Edit after Vladimir Stokic's answer:
We're currently thinking of two solutions to keep the dictionary clean. One is to have a dictionary of weak references but then we just move the problem, there will be weak references that need to be removed (using a timer tick from time to time?) Second idea is to have the node notify the factory of deletion.

How can we design for this problem in a proper way?

Best Answer

I don't believe there is a single pattern that would fit the bill here. However, you might use a combination of patterns. What you really need is not a node creator, but more of a node provider.

The node can be provided by creating a new one, or finding an existing one and providing a reference to it. Therefore, you should first abstract that functionality in one class, let's call it NodeProvider. This class would have instances of NodeLocator and NodeFactory. The Get(int id) method of NodeProvider class would first invoke the Get(int id) method of the NodeLocator member. If it does not locate the existing node, then Get(int id) method of the NodeFactory member. Either way, a node is provided. The design pattern that this is most similar to, in my opinion, is Facade Pattern.

Pseudo code (without any checks) is given below:

class NodeProvider
{
    private NodeLocator locator = new NodeLocator();
    private NodeFactory factory = new NodeFactory();

    public Node Get(int id)
    {
        Node retVal = null;
        retVal = locator.Get(id);
        if (retVal == null)
        {
            retVal = factory.Get(id);
        }
        return retVal;
    }
}
Related Topic