Closed creative-resort closed 9 months ago
Hi @creative-resort,
First of all: thank you for your interest in this this package :)
I had to refresh my memory.
https://github.com/amolenaar/roles/blob/24be07e2573b464c619fd87dbb22a53967452d1e/example.py#L49-L62
The TransferMoney
object is where the whole play is staged. A context is created that applies the MoneySource
and MoneySink
roles to the source and destination account. As a result source
and sink
are available in the context.
Since MoneySource
is talking to the sink account via the context, it is in fact talking to the MoneySink
role. Maybe it would be nicer to provide the sink as an argument to the transfer
role method instead?
@creative-resort I did a few updates to the example file. Is the intent more clear now?
Yes Arjan, your package seems very important to me, as DCI (the context aspect in particular) is otherwise missing from Object Oriented programming in Python — at least: a systematic approach to it.
Thank you for making the intent more clear. I understand how you've coupled roles and instances and the exemplary roleplay. As I'm looking at the updated example, I am still missing a couple of tenets of DCI, as James Coplien teaches it:
What I notice in the example, however is:
Right now it is possible within a Role, to call another Role's bound object's (non-role) methods.
e.g. within Role MoneySource I am able to call context.sink.deposit(amount)
, which should result in an access error.
In the updated example, you're explicitly telling the source where to transfer the amount. It should not be necessary to provide that parameter, as the meaning of a "sink" is semantically already clear within the MoneyTransfer context.
Instead, it should be context.MoneySink.receive(amount)
within MoneySource.transfer().
Not the bound object names should be on the context stack, but the Roles.
In my view, only the receive
method (green in the following screenshot) should be available, and instead of sink
(red) it should be MoneySink
.
The MoneyTransfer class itself is not yet a context but only implicitly becomes a context once a context is created inside of it. Though I'm still pondering whether this would finally be a good idea, using a Context metaclass.
Do these points make sense to you?
Here is a code snippet I've created, that shows a bit more of how I'd expect DCI programming to function. See following draft pull request for further discussion: https://github.com/amolenaar/roles/pull/5/commits/2d775895cc3df74981422409c29c2887746c0b3a
Hello Arjan,
I'm looking at the example https://github.com/amolenaar/roles/blob/24be07e2573b464c619fd87dbb22a53967452d1e/example.py#L37-L41 and have the following question:
Shouldn't roles only be interacting with other roles? However, the MoneySource role is interacting with the instance "sink", which the MoneySink role will be bound to only some time later in the context class TransferMoney.
Let's think about it: MoneySource prescribes, which object MoneySink must be bound to in context ... What if that name changes in the context class? Isn't the point of DCI roles to decouple roles from object instances? This is a coupling between object, context and role, that shouldn't be happening before the binding in the context class takes place, correct?
The way it's now, doesn't seem to make sense to me, but I could be wrong. What are your thoughts on this?