DCI, trouble with concept of 'context' and what roles within know of each-other
I may just be missing a key concept here. I understand the 'dumb' data objects. I also understand that roles are stateless collections of methods applied to a dumb object when it takes on that role. I also understand that a context assembles the actors that will take place in the algorithm being implemented. But what the roles know about each-other, and weather they must be defined within the context, or outside it is unknown to me.
Say a context has 2 roles, start and end. Our use-case is string concatenation, so we will be assigning a string to each role.
some psudocode:
context concat {
role start {
method concat() {...}
method get_value {self->as_string}
}
role end {
method get_value {self->as_string}
}
// According to the docs I have read, the context simply kicks off a method in
// a role, the role handles the rest.
start.concat(?)
}
Now for 3 different combinations of how concat() (the method) and start.concat(?) (the call) may need to be:
Roles are aware of other roles in the same context (forcing roles to be non-reusable in other contexts, which seems wrong to me.)
concat{ self.get_value + end.get_value }
start.concat() // Not passing 'end' as an argument,
// it is already aware of end because
// it is defined in the same context
Roles are not aware of the other roles in the context, and thus need them passed in as arguments (Which seems a pain as a context could have any number of roles, if the context starts by kicking off a method we could need to pass 30 'roles' into the one method call as arguments, then chain them all the way!) (Note: In this one the role definitions may be mov开发者_开发知识库ed outside the context, and re-used in multiple contexts)
concat( end x ) { self.get_value + x.get_value )
start.concat(x)
To me the most obvious choice seems to be to not force context to kick off a method and nothing more. Then put the interaction logic into the context, and the non-interactive parts into roles. (Note: In this one the role definitions may be moved outside the context, and re-used ina couple of contexts)
concat() UNDEFINED
start.get_value + x.get_value
This seems to contradict this though: http://en.wikipedia.org/wiki/Data,_Context_and_Interaction#Execution_Model
- the Context invokes a Role method on the first object to take part in the use case.
- From that point forward, Roles invoke each others' methods to carry out the use case.
In DCI the roles are usually aware of the context, and the context can act a repository for all the relavant roles. I.e. case number two where the role can access the context, and ask it for the objects playing the other roles it needs. This is implementation detail though. Passing the needed objects into role methods can work too. The important part is that the roles interact with each other through the role methods (that is, not through role player methods, since that creates an unfortunate coupling). Roles are - generally speaking - not expected to be candidates for reuse across contexts. A context roughly corresponds to a use case, and the roles implement the behavior of the use case. In general that logic is not reusable across use cases.
Hope this helps.
Also you may want to check out the artima article introducing DCI, and the object-composition google group.
精彩评论