Examinez les points suivants CDK en Python (pour cette question, il n'est pas nécessaire d'avoir des connaissances sur AWS et cela devrait être valable pour n'importe quel modèle de construction, j'utilise simplement CDK dans cet exemple car j'ai rencontré le problème en utilisant cette bibliothèque) :
from aws_cdk import aws_stepfunctions as step_fn
from aws_cdk import core
app = core.App()
state_machine = step_fn.Chain.start(
step_fn.Pass(app, 'start')
).next(
step_fn.Pass(app, 'foo1')
).next(
step_fn.Pass(app, 'foo2')
).next(
step_fn.Pass(app, 'bar')
)
Maintenant, si je dois réutiliser la construction
.next(
step_fn.Pass(app, 'foo1')
).next(
step_fn.Pass(app, 'foo2')
)
plusieurs fois, j'ai pu trouver ces approches.
-
Envelopper le code dans une méthode
def foo(chain: step_fn.Chain) -> step_fn.Chain: return chain.next( step_fn.Pass(app, 'foo1') ).next( step_fn.Pass(app, 'foo2') )
This works but it destroys the readability of the chain as the calling order is inverted.
state_machine = foo( step_fn.Chain.start( step_fn.Pass(app, 'start') ) ).next( step_fn.Pass(app, 'bar') )
This is against the builder design to wrap mutability in the builder classes.
state_machine = step_fn.Chain.start( step_fn.Pass(app, 'start') ) state_machine = foo(state_machine) state_machine = state_machine.next( step_fn.Pass(app, 'bar') )
-
Singe Parcheando
Bien que la syntaxe soit apparemment agréable, elle semble sujette aux erreurs et constitue un cauchemar en termes de maintenabilité lorsqu'elle est appliquée à un projet réel avec plusieurs personnes travaillant sur le référentiel :
step_fn.Chain.foo = foo
state_machine = step_fn.Chain.start(
step_fn.Pass(app, 'start')
).foo().next(
step_fn.Pass(app, 'bar')
)
J'ai essayé de voir s'il y avait un moyen d'implémenter des classes de type pour les objets Python, mais je n'ai rien trouvé. J'ai trouvé dry-python mais je ne suis pas sûr qu'il puisse être utilisé pour les méthodes de classe. En Scala, classes implicites pourrait être utilisé pour avoir une syntaxe de constructeur fluide sans altérer aucun état global. Existe-t-il un moyen Pythonique de réaliser la même chose ?
Edit : J'ai découvert plus tard que la chaîne CDK permet d'ajouter d'autres chaînes, ce qui résout ce problème particulier. En général, si vous pouvez influencer la conception des constructeurs, il est probablement préférable d'ajouter une méthode extend
etc. qui permet d'ajouter un autre constructeur au constructeur, ce qui facilite sa réutilisation pour ce type de scénarios.