I have a data structure which has an add function. When the user instantiates a new data structure object, she can specify an algorithm which will be executed each time the add function is called and alters the newly inserted value based on the previous values in the data structure. The algorithm needs to have access to all the data in the data structure
This is not a good idea and besides makes not really sense.
If I get you correctly, you want to create an object which contains some elements e1, e2, e3, .... At a given point in time, you want to do a transformation of the elements so far. At a later point, you want to do another transformation on the collection as a whole.
There is no need to do a transformation in between, since it makes no difference whether the collection stores the values plain vanilla or transformed. At a given point, you need to read or change the transformed values: this is the right point to do a transformation of the colletion (so far) as a whole.
If that is, what you want, this would be a perfect use-case for the visitor pattern:
In case, you have have Python at hand or do not mind installing it, here is a nice example how to set up the visitor pattern
def __init__(self, values):
self._values = values
def transform(self, transformator):
self._values = transformator.transform(self._values)
def accept(self, visitor):
def visit(self, container):
def transform(self, values):
return list(map(lambda x: 2*x, values))
container = Container([1, 2, 3])
doublingVisitor = DoublingVisitor()
if __name__ == '__main__':
Anyways, the python code is easy to understand. The point is, you need one class which I called (lacking of a better name)
accepts a Visitor. On the other hand, you need an object derived from
Visitor, which holds as a
Transformator the algorithm (which was the term you used). The
Visitor needs one method
visit, which has one parameter (the object, which it visits). That is the whole magic.
While visiting, the visitor calls the
transform method on the object to visit, which in turn receives the
Transformator who implements a
transform method. That's it.
Every time, you want to do something with your collection, you could accept another