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
Questa non è una buona idea e inoltre non ha molto senso .
Se ti prendo in modo corretto, vuoi creare un oggetto che contenga alcuni elementi e1, e2, e3, ... . Ad un certo punto nel tempo, vuoi fare una trasformazione degli elementi finora. In un secondo momento, si desidera eseguire un'altra trasformazione sull'insieme nel suo insieme.
Non è necessario eseguire una trasformazione tra , poiché non fa differenza se la raccolta memorizza i valori plain vanilla o transform . Ad un certo punto, è necessario leggere o modificare i valori trasformati: questo è il punto giusto per eseguire una trasformazione della raccolta ( finora ) nel suo complesso.
Se questo è ciò che desideri, questo sarebbe un caso d'uso perfetto per il modello di visitatore :
Nel caso, hai Python a portata di mano o non ti dispiace installazione , ecco un bell'esempio su come impostare il modello di visitatore
#!/usr/bin/env python3
class Container:
def __init__(self, values):
self._values = values
def transform(self, transformator):
self._values = transformator.transform(self._values)
def accept(self, visitor):
visitor.visit(self)
class Visitor:
pass
class Transformator(Visitor):
pass
class DoublingVisitor(Transformator):
def visit(self, container):
container.transform(self)
def transform(self, values):
return list(map(lambda x: 2*x, values))
def main():
container = Container([1, 2, 3])
doublingVisitor = DoublingVisitor()
container.accept(doublingVisitor)
print(container._values)
if __name__ == '__main__':
main()
Comunque, il codice Python è facile da capire. Il punto è che hai bisogno di una classe che ho chiamato (privo di un nome migliore) Container
, che accepts
un visitatore. D'altra parte, è necessario un oggetto derivato da Visitor
, che contiene come Transformator
l'algoritmo (che era il termine che hai usato). Il Visitor
ha bisogno di un metodo visit
, che ha un parametro (l'oggetto, che visita). Questa è l'intera magia.
Durante la visita, il visitatore chiama transform method
sull'oggetto da visitare, che a sua volta riceve il Visitor
/ Transformator
che implementa un metodo transform
. Questo è tutto.
Ogni volta che vuoi fare qualcosa con la tua raccolta, puoi accettare un'altra Visitor
.