My friend Jimmy posted a while ago now about how he uses roles in his designs. I had to write and plead ignorant, which was certainly true, I
couldn’t understand what he meant. I was still confused after his reply
until our mutual friend Chris sent a link to this pattern paper. Later jimmy followed up with this which indicates I wasn’t alone. So Jimmy’s post was cleared up, however even with the follow ups my understanding still seemed off.
First of all, my confusion started with the term Role. To my
conventional way of thinking, a person is related to a role, or if not
a person, then an actor in the UML sense of external agents that send
messages. More specifically, the role is the descriptive label,
a certain type of actor that uses the system. The way the term is used
the pattern, the role is more than that label and not restricted to actors,
even though the example given is applied to actors. Perhaps you could
that the label is just more complete with it’s interface. I pondered
that for a few days and was still unhappy, and finally came to the
conclusion that what the pattern is describing as a role is really just
an interface or perhaps a Decorator. Probably the thing closest to what I think of as a role
is called the “Spec’ in the pattern. In Jimmy’s example which he later
clarified as being a snapshot, an interface could have been used that
during construction of the invoice might have been applied to a real
Product, but later could have been applied to an Invoice snapshot. That
may not make sense either, but the point is that the interface
describes a way for the invoice to think of products in the way that
makes sense to an invoice.
That leads to my next issue with that pattern. So you have an interface that makes an Invoice happy about the way it sees a Product. In the role pattern as I understand it, the Invoice would add a role for it’s InvoiceItem with all it’s line item goodness included to the Product class: AddRole(). Then when it wants a InvoiceItem it would ask the for the Product in the InvoiceItem role. It would need the proper Spec to get the correct role. Ah, yes it would have to cast to InvoiceItem.
Why would you do that? Would some other consumer ever care about the InvoiceItem? I really doubt it. Do you like the cast from ProductRole? Would ProductRole ever be useful by itself? Shouldn’t Invoice just wrap this Product the way it wants to itself and use the InvoiceItem directly?
I sat on this post for awhile thinking that I would eventually get it, but there it is.