Identifying Roles

68 views
Skip to first unread message

Ant Kutschera

unread,
Aug 19, 2011, 10:08:34 AM8/19/11
to object-composition
Hi,

I need help identifying the roles for the following use case.

I have my own ideas, but wanted some validation from the group please.

Background:
The client wants some software to be built which lets a cashier scan
books which the customer wants to buy. Once all the books are
scanned, the cashier can take money and the system prints a receipt.

------------ USE CASE ------------

Assumptions:
1. The inventory is out of scope at the moment.
2. Sales Tax will be calculated using a hard coded value. Its
configuration in the master data can be done later.
3. A payment partner is integrated with the credit/debit card reader.
The card reader verifies the PIN and obtains a transaction ID from the
partner which confirms the payment will be made. We write this
transaction ID to a sales log, and the back office use it at the end
of the month to confirm payments are complete.

Description: Deals with completing a sale at a till in a store.

Steps:

--- Users View ---

1. A customer approaches the sales desk and hands over books to the
sales agent and asks to buy those books.

2. The sales agent scans each book in, using the scanning device, or
enters the barcode numbers manually.

3. As each book is scanned, the till shows the price and title of the
book. The agent needs to check the price of the book against that
shown on the screen. If the screen has a different price, they need
to inform the customer that the price is different than advertised and
conform the customer still wants the book. If not, the book can be
removed from the list using the “R” key.

4. The till displays the total price of the order, as well as the
sales tax which has been applied

5. The user chooses a payment type and finishes off the sale by
taking either cash or an electronic payment. Sales tax is calculated
as 4.00% (hard coded for the moment).


--- Technical Notes ---

- User can also enter the barcode number, if it cannot be scanned.
Manual entries need to have the check digit validated and if there is
a problem, the till needs to inform the user to try again.

- Upon number entry, we do a lookup to find it in the catalogue, and
display the results out of the catalogue. The price used comes out of
the catalogue.

- Payment methods are toggled with the “T” key: Cash – simply open
the till once the agent hits the “C” key. Once the till is closed,
the receipt is printed. Electronic Payment – the agent hits the “C”
key and the card reader waits for the customer to enter their card.
Once the transaction ID is known from the payment partner, it is
written with the sale to the sales log.

- Check we have paper in the till before we complete the sale.

- The sales log is a place where we write the financials of the
sale. This is typically delivered to the back office dealing with
accounts. Any discounts that have been applied are listed with the
relevant account number to which they are booked.

- A sales order, is an entry in the sales database, which contains
all the details of the sale. Every item sold is copied from the
catalogue, into the sales database, so that an auditable history is
created. Things like the discounts applied are listed here too.

Pre-Conditions: Sales Agent has completed the last sale, or has just
logged in.

Post-Conditions: The sale is completed. The sales database contains
the order. The inventory is reduced (out of scope now). A sales log
is written, containing the payment partners transaction ID if the
payment was electronic.

------ END OF USE CASE -------

So, I have been able to identify these actors:

Customer
Sales Agent (cashier)

And I have identified these objects, which I feel are the relevant
ones:

Book
Till
Sales Log
Sales Order
Catalogue

I have even extracted the following behaviours:

1. Retrieve Product based on barcode, triggered by scanning of a
product, or when user enters a barcode number and hits enter.
a. Displays results on till screen.
b. Updates total and tax showed on screen
2. Toggle Payment type, triggered by agent hitting the “T” key
3. Create Sale, triggered by agent hitting the “C” key
a. Check paper in receipt printer
b. Single Transaction:
i. Create sales order
ii. Create sales log entry
iii. Reduce inventory (out of scope)
4. Print Receipt, triggered by creation of sale
5. Reset till, ready for next sale

So, what are the ROLES that you can identify, and which behaviours
belong to those roles?

Cheers,
Ant

Ant Kutschera

unread,
Aug 20, 2011, 2:07:59 AM8/20/11
to object-composition
Hmm...

If I were building an OO solution, it would build a big fat Till
class. It would contain a Keyboard class, for processing user input;
a Scanner for receiving ISBN numbers; a Printer, for printing receipts
and Screen for displaying stuff to the user. The Catalogue would be
able to read Books from the database given their ISBN number. And the
sales log and sales order classes would be used for persisting the
actual sale.

If I were building a SOA solution, I would build some MVC at the front
(the View would be the Screen, the Keyboard and Scanner would trigger
calls to the Controller, the Model would be a list of Books to be
displayed on the screen). The Controller would then use a Catalogue
Service to load books based on their ISBN, an AccountingService and a
SalesService for creating the sales log and sales orders
respectively. And to print, I would probably have an OO style class
to wrap the hardware to do the printing of receipts.

Both of those are very different from the Use Case - the use case
would be fragmented all over the place.

So I would like to build a DCI solution.

But I get the feeling, that the use case is very badly written.

If I were to work backwards, I could imagine the following:

In the context of the user entering input or scanning, the Till plays
the role of a keyboard or scanner.
In the context of doing a book lookup in the database, the Till plays
the role of a Catalogue(?) or plays the role of a CatalogueReader in
order to find the relevant book. The till then plays the role of a
Screen and displays what the user sees.
In the context of completing a sale, the Till plays the role of both
an AccountingEntryCreator and a SalesOrderCreator. The till then
finishes by playing the role of a printer, and prints out a receipt.

So... I have two problems...

1) The use case, so far, doesnt really explicitly mention all of those
roles. It doesn't mention a screen or keyboard. So my question here:
is it acceptable in DCI, or even sometimes necessary in DCI, to modify
use cases, so that the software can implement them in a readable way?
That feels a little weird, but I guess it's OK for analysts to modify
their work, because the analysts are after all the use case owners,
and they are on board as far as wanting to do DCI, because DCI isn't a
technical solution, its a paradigm.

2) All my roles are being played by one object, the Till. Anyone
think that is weird?

Cheers,
Ant

Ant Kutschera

unread,
Aug 21, 2011, 4:24:38 PM8/21/11
to object-composition
My questions aren't trick questions - I'm really stumped!

Help!!!

Am I supposed to be looking for the roles names in the use case?

Or maybe everyone else is stumped too - then please say so.

Or... maybe no one cares? Then say that too please!

Wenig, Stefan

unread,
Aug 22, 2011, 10:03:10 AM8/22/11
to object-co...@googlegroups.com
What's the system?

A simulation of customers buying books?

Or a piece of software to run on a till? If so, why would the customer be an actor (doesn't interact with the system)? Why would the till want to know about books (and not EAN codes etc)?

Stefan

> - Payment methods are toggled with the "T" key: Cash - simply


> open
> the till once the agent hits the "C" key. Once the till is closed,

> the receipt is printed. Electronic Payment - the agent hits the "C"

> --
> You received this message because you are subscribed to the Google
> Groups "object-composition" group.
> To post to this group, send email to object-
> compo...@googlegroups.com.
> To unsubscribe from this group, send email to object-
> composition...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/object-composition?hl=en.

Ant Kutschera

unread,
Aug 22, 2011, 2:58:19 PM8/22/11
to object-composition
Hi Stefan,

It is supposed to be software that will run on the till.

Thanks for the tip that a customer is not an actor.

The till probably wants to know about something like a product (i.e.
something that has a price and an EAN or ISBN or other product code).
So maybe a book could play the role of a product.

But am I supposed to guess and make it up as I go along? Or am I
meant to be looking for nouns and verbs which the person who wrote the
use case used? I want to model their world, not something based on
guesses.

Do you think the use case is badly written?

Thanks,
Ant

Wenig, Stefan

unread,
Aug 22, 2011, 3:11:45 PM8/22/11
to object-co...@googlegroups.com
I don't think if you really build software for a till that it will occur to you to create classes like book.

My best bet for DCI is to apply all your OO skills. Roles are just objects, only you need to think of them in terms of the roles they play, not so much their actual class. (But I'm not sold to the idea that this comes naturally and is really just the mental model of the user put to work, so I'm really not the best person to ask here. My guess would be that users rather think within concepts that are closer to classes, and that class-independent roles are an additional step towards more abstraction.)

In classic OO, your design decisions are among other things guided by technical realities. Say, if you put method X in the wrong class, your design might suffer in the category of cohesion/coupling, or open/closed. In DCI, I don't see any of these consequences within a single context, so I guess you can concentrate fully on implementing as truthful to your mental model as you want.

Also, I think role modeling will get more interesting as additional roles are added. A method-call ping-pong between roles might not be too much help compared to simpler designs. What's the problem you're trying to solve? Where in the design is your challenge? What's the easiest way to think about it? I would assume the answers are somewhere there.

Don't know if this answer is any help.

Stefan

> -----Original Message-----
> From: object-co...@googlegroups.com [mailto:object-
> compo...@googlegroups.com] On Behalf Of Ant Kutschera

James O. Coplien

unread,
Aug 22, 2011, 4:28:46 PM8/22/11
to object-co...@googlegroups.com

On Aug 22, 2011, at 7:58 , Ant Kutschera wrote:

> Thanks for the tip that a customer is not an actor.


Why not?

James O. Coplien

unread,
Aug 22, 2011, 4:30:17 PM8/22/11
to object-co...@googlegroups.com

On Aug 22, 2011, at 8:11 , Wenig, Stefan wrote:

> Roles are just objects,

Well, not in DCI, not in UML, not in English. Where is a role an object?

Ant Kutschera

unread,
Aug 22, 2011, 4:47:14 PM8/22/11
to object-composition
Hi Stefan,

I have no problems taking this use case and creating a good OO or
service based design.

If I knew what the roles were, I could create a DCI solution.

I can guess what the roles might be, but I don't want to guess. I
want the person who wrote the use case to tell me. Just like they
told me what objects were involved in their model, and the potential
actors.

> Don't know if this answer is any help.

To be frank, not really :-) But thank you anyway, at least you tried
- no one else has!

Maybe one way to identify role is to look for verbs (behaviour) in the
use case?

If I look for the verbs, they are (sort of):

- Retrieve Product
- Display results
- Updates total and tax on screen
- Toggle Payment type
- Check paper
- Create sales order
- Create sales log entry
- Print Receipt

Assuming this is the correct approach to identifying roles, I guess I
now have to ask myself who plays the roles, and what would the role be
called. I had hoped that the role name would be in the use case, but
I don't think it is. Maybe because the use case is badly written, or
maybe because that's normal. I don't know...

So players could be:

- Till: retrieve product -> the role
is a "Catalogue", or "ProductFinder"
- Till: display results, update total/tax -> the role is a
"Screen"
- User: toggle payment -> the role is
PaymentToggler (hehe, crazy!), or simply SalesAgent*
- Till: check paper, print receipt -> the role is
"Printer"
- Till: create Sales order -> the role
is , "SalesOrderCreator" or maybe accountant
- Till: create sales log -> the role
is "Accountant"

* I identified the sales agent as an actor. Perhaps that is the
role, and the data is a human or employee?

I had hoped "Printer" would have been explicitly mentioned in the use
case. But it isn't.

Does that mean I have modified the mental model???

Trygve Reenskaug

unread,
Aug 23, 2011, 1:17:18 AM8/23/11
to object-co...@googlegroups.com
I think of the difference between procedure oriented and object oriented programming as being that procedure oriented answers the question: "What happens?". Object oriented answers an additional question: "Who does it?" So a way to find the roles could be to first getting a clear understanding of the "what?" and then chop it up into a"who?" for each part. (May be that's the essence of FullOO; it describes the more than one "who?")

Just an idea.

--Trygve
--

Trygve Reenskaug       mailto: try...@ifi.uio.no

Morgedalsvn. 5A         http://folk.uio.no/trygver/

N-0378 Oslo               Tel: (+47) 22 49 57 27

Norway

Ant Kutschera

unread,
Aug 23, 2011, 2:34:50 AM8/23/11
to object-composition
Hi Trygve,

That is pretty much what I have done. Thanks for validating my
thought process.

Ant
> Norway Tel: (+47) 22 49 57 27
>
> Norway

Wenig, Stefan

unread,
Aug 23, 2011, 7:49:29 AM8/23/11
to object-co...@googlegroups.com
> From: James O. Coplien
> Sent: Monday, August 22, 2011 10:29 PM

>
> On Aug 22, 2011, at 7:58 , Ant Kutschera wrote:
>
> > Thanks for the tip that a customer is not an actor.
>
>
> Why not?

Actors interact with the system, so what is an actor and what is not depends on your system boundaries. A business use case would include the customer, this system use case does not because the customer only interacts with the employee (an actor), not the system (till).

At least that's what I always thought.
http://practicalanalyst.com/2008/05/21/quick-tip-to-help-identify-use-case-actors/

Stefan

Wenig, Stefan

unread,
Aug 23, 2011, 7:58:30 AM8/23/11
to object-co...@googlegroups.com
> From: James O. Coplien
> Sent: Monday, August 22, 2011 10:30 PM

Of course, it is played by an object. But thinking about which role gets a method is not so much different from thinking which object should get it, is it?

Let's look at how the system evolves. A typical situation is that you identify the main use cases and design an object model around them with the help of domain experts (what the system is). Then you implement more and more use cases on this model (what the system does), and they evolve together, incrementally.

Now one difference in DCI is that the use case is implemented in its own module, with all the behavior isolated from the objects. But we still need objects to play these roles, so we cannot look at it isolated. There need to be objects (or systems of objects) in the object model that can play these roles.

(And of course roles can serve as an additional abstraction, they do not necessarily depend on concrete or abstract classes. They do have structural requirements though.)

My conclusion is that we can fully exploit our OO experience when modeling roles and role methods within a context, and any other mindset could possibly be misleading (e.g. SOA). There are differences, some additional things to consider, maybe some to unlearn, but it's a good starting point.

Stefan

Wenig, Stefan

unread,
Aug 23, 2011, 8:47:25 AM8/23/11
to object-co...@googlegroups.com
> -----Original Message-----
> From: Ant Kutschera
> Sent: Monday, August 22, 2011 10:47 PM
>
> Hi Stefan,
>
> I have no problems taking this use case and creating a good OO or
> service based design.

Do you think this is an either/or decision?

Even in OO, we (hopefully) tend to service-shaped interfaces within applications where they make sense.

So it won't make much of a difference whether we do SOA or OO, in any case the interface between the part that adds product prices and the part that handles the payment will end up being a service, not a collection of fine-grained objects interacting with each other.

SOA goes further because there are additional constraints (e.g. can't join simply data from different services in a query). But the seed of this thought is already in OO.

So it won't be identical, but we can try and think of services as contexts and operations as interactions. SOA stops here, DCI starts here: How do we implement a context?

Lets model the objects to support the operation, or look at the existing object model if we already have one.

Context: Credit Card Payment
Interaction: Pay

Puh. Probably just a call to a subroutine that blocks execution until payment is completed or cancelled. No luck doing role modeling here.
Next try.

Context: Till
Interaction: Price Entry

Let's assume a loop that get's keyboard/scanner input until the bill is complete. I would not model keyboard, scanner screen etc. as objects/roles, assuming there are system classes/methods to access them. It's really just a loop of readline, dispatch, process, printline.

So we're left with what? I/O. A product DB/service that gives us a price for each EAN code. A bill that accumulates all prices. I don't see anything else.

> If I knew what the roles were, I could create a DCI solution.
>
> I can guess what the roles might be, but I don't want to guess. I
> want the person who wrote the use case to tell me. Just like they
> told me what objects were involved in their model, and the potential
> actors.

Now who does what? The only active object/roles I can see here are the till itself (processing input, creating output), the bill and maybe the log.

Everything from adding/removing products/quantities to calculating sales tax is probably going to be part of the bill, partly in its core object form, partly attached as role methods.

The till has methods that dispatch line input into methods that process it. It's not a business entity, more of a controller.

But I don't see the customer arriving at this conclusion. We have to guide them there, work together.

> > Don't know if this answer is any help.
>
> To be frank, not really :-) But thank you anyway, at least you tried
> - no one else has!

Getting some flak already here for stepping out of my comfort zone. Glad you appreciate it.

> Maybe one way to identify role is to look for verbs (behaviour) in the
> use case?
>
> If I look for the verbs, they are (sort of):
>
> - Retrieve Product
> - Display results
> - Updates total and tax on screen
> - Toggle Payment type
> - Check paper
> - Create sales order
> - Create sales log entry
> - Print Receipt
>
> Assuming this is the correct approach to identifying roles, I guess I
> now have to ask myself who plays the roles, and what would the role be
> called.

Exactly. What objects are already available in my object model? Does the concept of a bill or a log already exist? Do I have to modify or extend it? Create new ones?

What is the role contract of bill? Does the role contract alone tell me that it's a bill? Then why not call it bill? Or is there a better contextual name?
Or can it be described with more abstract words, leaving the context open to other implementations? Then I should express this in the role name.

In this sample, I'd probably go for role name 'bill'.

> I had hoped that the role name would be in the use case, but
> I don't think it is. Maybe because the use case is badly written, or
> maybe because that's normal. I don't know...
>
> So players could be:
>
> - Till: retrieve product -> the role
> is a "Catalogue", or "ProductFinder"
> - Till: display results, update total/tax -> the role is a
> "Screen"
> - User: toggle payment -> the role is
> PaymentToggler (hehe, crazy!), or simply SalesAgent*
> - Till: check paper, print receipt -> the role is
> "Printer"
> - Till: create Sales order -> the role
> is , "SalesOrderCreator" or maybe accountant
> - Till: create sales log -> the role
> is "Accountant"
>
> * I identified the sales agent as an actor. Perhaps that is the
> role, and the data is a human or employee?
>
> I had hoped "Printer" would have been explicitly mentioned in the use
> case. But it isn't.
>
> Does that mean I have modified the mental model???

Maybe the mental model was just too detailed in the first place? We model with the customer, we try to speak the same language, guide them into understanding how the system works in order to get better results quicker.

Does any of this really depend on the customer understanding how the printer works? If yes (say, a complex interaction between printing and paper refills), then we should model it. If it's just a technical detail, let's keep it that. We don't model database access or window management with the customer either.

Again, might not help you a lot. Helps me to sort my own thoughts though, so thanks for starting this thread.

Stefan

Ant Kutschera

unread,
Aug 23, 2011, 4:39:55 PM8/23/11
to object-composition
On Aug 23, 2:47 pm, "Wenig, Stefan" <stefan.we...@rubicon.eu> wrote:
> The only active object/roles I can see here are the till itself (processing input, creating output), the bill and maybe the log.

Aha! The "bill"? What is that? It's not mentioned at all in the use
case...

So our mental models are different. We need to unify them, before we
continue - except we won't because I already started programming ;-)

I guess an important insight here is that the use case does not always
list the roles or role names, but it probably does list the data class
names.

Alternatively, perhaps we should introduce some role names and then
modify the use case to use them. That is the part I am still unsure
about. One goal of DCI is that the code should read like the use
case. In OO and SOA it is quite acceptable (in my experience) for use
cases to differ from the implementation, because there is the design
which sits between them which maps the use cases to the design.

Does anyone have a problem if we go back and modify the use case?

And if we do, does it make using an agile process a prerequisite for
using DCI? In say RUP or the Waterfall process, I would have
difficulty modifying use cases when I come to do the design, because
the use cases are completed and signed up before I am allowed to start
the design. I have even worked in places where the sign off is a
prerequisite for getting the design/implementation budget.


> Again, might not help you a lot. Helps me to sort my own thoughts though, so thanks for starting this thread.

Yes, this thread is a good one I think - it's helping me too :-)

Risto Välimäki

unread,
Aug 23, 2011, 5:36:51 PM8/23/11
to object-co...@googlegroups.com
2011/8/23 Ant Kutschera <ant.ku...@gmail.com>

I guess an important insight here is that the use case does not always
list the roles or role names, but it probably does list the data class
names.

When is that the case? I suppose that then for example Data class Till is used in Role of Till. And if you don't have any needed Role methods, you maybe just use the variable name as a role:

Till firstTill = new Till();, where the "firstTill" is the role of that till.

Object Human could easily play also the Role of Human, when needed.

-Risto

Ant Kutschera

unread,
Aug 23, 2011, 6:07:54 PM8/23/11
to object-composition
I have a lot of needed role methods!

All of the behaviour listed at the top, needs to be in role methods
(since in this case I want to do the entire implementation in DCI,
just to see what happens).

If the till plays the roll of till, not only do I confuse everyone and
make the mental model cloudy, but all the functionality lands in one
role and that isn't so good for reading or maintaining.


On Aug 23, 11:36 pm, Risto Välimäki <risto.valim...@gmail.com> wrote:
> 2011/8/23 Ant Kutschera <ant.kutsch...@gmail.com>

James O. Coplien

unread,
Aug 23, 2011, 6:53:33 PM8/23/11
to object-co...@googlegroups.com
A lot of the roles being mentioned here don't sound like the roles one would use in use cases, in the contexts where people are describing them. Alistair Cockburn's book has some great tips that help you find good roles. These map pretty closely onto many DCI roles.

His use case book is worth a read.

(Alistair worked a bit with Trygve some time back, too... :-) )

> --
> You received this message because you are subscribed to the Google Groups "object-composition" group.

> To post to this group, send email to object-co...@googlegroups.com.
> To unsubscribe from this group, send email to object-composit...@googlegroups.com.

Wenig, Stefan

unread,
Aug 24, 2011, 5:23:57 AM8/24/11
to object-co...@googlegroups.com
> From: Ant Kutschera
> Sent: Tuesday, August 23, 2011 10:40 PM

>
> On Aug 23, 2:47 pm, "Wenig, Stefan" <stefan.we...@rubicon.eu> wrote:
> > The only active object/roles I can see here are the till itself
> (processing input, creating output), the bill and maybe the log.
>
> Aha! The "bill"? What is that? It's not mentioned at all in the use
> case...

I think it should. It's the object in the center of everything your use case does. You add items to a bill, calculate the tax and put it on the bill, and then have the customer pay the bill's total amount. There might be other useful models too, but you need some business-centric way to think of and speak about this use case in order to get the user involved in modeling.

Your use case description is extremely UI centric. That's natural, users think in terms of UI interactions. But if you want to take it all a step further and model objects and roles together with the users, you need to lead them there. The DDD blue book says it best, I think.

> So our mental models are different. We need to unify them, before we
> continue - except we won't because I already started programming ;-)
>
> I guess an important insight here is that the use case does not always
> list the roles or role names, but it probably does list the data class
> names.

It can list the roles and names if you guide the user there.

You will need to write the use case in a way that lets the users see and understand the UI interactions that are so important to them, but still be precise about what goes on with business objects. (e.g. in terms of a ubiquitous language in DDD)

The implementation will want to separate these things. Whether the UI can or should be implemented using DCI too, and how this will look, is a separate discussion. Forget what I wrote about having a read/dispatch/execute loop in a till object/role, that's UI code and should be kept separate.

> Alternatively, perhaps we should introduce some role names and then
> modify the use case to use them. That is the part I am still unsure
> about. One goal of DCI is that the code should read like the use
> case. In OO and SOA it is quite acceptable (in my experience) for use
> cases to differ from the implementation, because there is the design
> which sits between them which maps the use cases to the design.

If you want to keep them in sync, you have to either modify the use case or adjust your code to any nonsensical use case description. Few use cases will be fit to be coded literally from the start.

> Does anyone have a problem if we go back and modify the use case?

I don't. But you can work together with the user on the mental model, the ubiquitous language etc. from the start. Maybe you'll manage to get the use cases right from the start?

> And if we do, does it make using an agile process a prerequisite for
> using DCI? In say RUP or the Waterfall process, I would have
> difficulty modifying use cases when I come to do the design, because
> the use cases are completed and signed up before I am allowed to start
> the design. I have even worked in places where the sign off is a
> prerequisite for getting the design/implementation budget.

That's one of the problems with waterfalls. Requirements engineers write stuff that can't be designed. Designers and architects take the requirements and create designs that can't be implemented. Waterfall doesn't work, with or without DCI.

RUP is prescriptive and heavy, but iterative. Get sign off for baselines and go into detail later, you can always go back and improve artifacts. Think of use case analysis in RUP: you begin with an unstructured collection of textual descriptions, and then you start modeling them using extends and include relationships.

I'm more inclined towards Agile/Lean, but I don't think it's specific for DCI.


Now let me try and rephrase your use case in a way that lets us see actual business objects, roles, and interactions. I'll go with the bill object.

Assumption: your description does not go into a lot of detail about credit card payments, though that's at least as complex as the rest of the use case. I'll assume that credit card payments are handled by another system. It could also be an internal operation, but then it would most likely be a separate use case with an include-relationship from this one. Maybe not from the start, but definitely when our use cases are detailed enough to be implemented in a literal way.

Use case: Sales transaction

A sales agent enters several items into the till and then has the customer pay the amount.

Actors:
- Sales Agent (primary actor)
- Payment System (secondary actor)
- Customer (optional, could be modeled as an offstage actor if we want. Just found out that those exist.)

Basic flow:
1. for each item the customer brings
1.1 the Sales Agent scans the barcode
1.2 the till looks up the barcode in the catalog
1.3 the till adds the product name and price to the bill
1.4 salex tax is calculated
1.5 the bill's total is updated to include the new item and sales tax
1.6 the till shows this bill item and the bill's new total amount on the screen
2. the Sales Agent completes the bill by chosing a payment type
3. if the payment is cash
3.1 the Sales Agent enters the amount received
3.2 the till displays the change
3.2 the till's drawer opens and the total amount is logged as cash in the Sales Log
4. if the payment type is credit card
4.1 the amount is sent to the Payment System
4.2 the Payment System returns a transaction number
4.3 the amount is logged in the Sales Log with the transaction number
5. the till prints a receipt for the bill
6. the items on the bill get logged to the Sales Log

Alternative flows:
- barcode must be entered manually
- cancel a product (prices don't match)
- cancel the whole transaction
- payment cannot be completed
- printer runs out of paper

Now, still ignoring the UI, it's pretty easy to find roles for a DCI implementation.

Catalog
Bill
Sales Log

Should product be a role too? That's tougher. If it is, we need to create a new context whenever we retrieve a product, because it can't be bound to a context while an interaction is already running. But maybe we can take a shortcut and just pass the product around as a parameter, without role binding? It would be a methodless role anyway.

The role contract will probably include these methods:

Catalog: GetProduct
Bill: AddProduct, RemoveProduct, GetTotal
Sales Log: AddItem (description, amount) (just to make it interesting, I assume that the sales log can only log individual lines)

The only methodful role in my implementation is Sales Log. Role methods:
AddCashTransaction (bill)
AddCreditCardTransaction (bill, transactionID)

So let's create a SalesTransaction context with several operations. (Alternatively several contexts depending on whether we need product as a role. I assume we don't.)

context SalesTransaction (Catalog, Bill, SalesLog)

interaction AddProduct (barcode) {
p = Catalog.GetProduct (barcode)
Bill.AddProduct (p)
}

We could also implement this as a RoleMethod of Bill and have the interaction just invoke Bill.AddProduct(barcode), but I don't see the advantage.

interaction PayWithCreditCard {
transactionID = PaymentSystem.Pay (Bill.GetTotal())
SalesLog.AddCreditCardTransaction (Bill, transactionID)
}

role method SalesLog.AddCreditCardTransaction (bill, transactionID) {
for each item in bill
self.Log (product.Name, product.Amount)
self.Log ("Credit card payment " + transactionID, bill.GetTotal()
}


If we have a use case description that tells us what really happens to our objects, it's quite straightforward to identify and implement roles.

Are the role names good?

Bill could also be CurrentBill, but I think that goes without saying
There's only one Catalog and one Sales Log in the system, so they don't need to be qualified further.

Would we want more abstract role names? Such that the use case would not be bound to Catalogs and Bills, but more abstract concepts? Like I said before, I think that's another level of abstraction that doesn't come naturally and should only applied when necessary. I can't even think of an abstract role that fulfills the Bill contract but is not a bill.

It's quite a good sample to work on, I only wish the role methods were a bit more interesting.

Stefan

Raoul Duke

unread,
Aug 24, 2011, 1:32:59 PM8/24/11
to object-co...@googlegroups.com
hi,

how does this use case and dci code help get away from
functional/procedural decomposition, if at all?

thanks.

James O. Coplien

unread,
Aug 24, 2011, 1:45:03 PM8/24/11
to object-co...@googlegroups.com

On Aug 24, 2011, at 6:32 , Raoul Duke wrote:

> how does this use case and dci code help get away from
> functional/procedural decomposition, if at all?

By thinking about the algorithm in terms of roles, and thinking about the system structure in terms of objects, both at the same time.

Data structures aren't a bad thing.

Procedural decomposition isn't a bad thing. We all chunk algorithms into decomposed procedures. The question is: What are the procedure boundaries? Most users model them as falling along role boundaries.

There are no role boundaries in FORTRAN or Pascal.

Raoul Duke

unread,
Aug 24, 2011, 2:02:53 PM8/24/11
to object-co...@googlegroups.com
On Wed, Aug 24, 2011 at 10:45 AM, James O. Coplien <jcop...@gmail.com> wrote:
> Procedural decomposition isn't a bad thing. We all chunk algorithms into decomposed procedures. The question is: What are the procedure boundaries? Most users model them as falling along role boundaries.

yeah, i can grok that. if i were a master's student with free time i'd
try to do an overview paper of how people see that gray area /
spectrum / range of options / context-dependent-ness.

Ant Kutschera

unread,
Aug 24, 2011, 3:01:26 PM8/24/11
to object-composition
I'll try and get a copy. I can well imagine, I am making things up as
I go along.

As you have read his book, what would you say the roles could be?

Ant Kutschera

unread,
Aug 24, 2011, 3:15:45 PM8/24/11
to object-composition
On Aug 24, 11:23 am, "Wenig, Stefan" <stefan.we...@rubicon.eu> wrote:

Hi Stefan,

Excellent reply, thanks :-)

The use case as you described it is pretty much what I have
implemented. The Bill I call the Cart - same concept. I have a
catalogue too, and an Accountant instead of Sales Log, but I think
SalesLog is better - after all, I did mention it in the behavioural
steps of the use case at the top of this thread :-)

Interestingly I have ended up with roles interacting very much like
the model, view and controller in MVC. But instead of abstract names
like View, Model and Controller, I have names like Screen,
ScannerAndKeyboard, InputHandler (the Till plays this while deciding
what to do with the input, I don't really like that name though).

Thanks,
Ant

Raoul Duke

unread,
Aug 24, 2011, 3:16:52 PM8/24/11
to object-co...@googlegroups.com
On Wed, Aug 24, 2011 at 12:01 PM, Ant Kutschera <ant.ku...@gmail.com> wrote:
> I'll try and get a copy.  I can well imagine, I am making things up as
> I go along.

or google up some summaries.
http://faculty.washington.edu/jtenenbg/courses/360/f02/project/usecaseguidelines.html

Ant Kutschera

unread,
Aug 24, 2011, 3:24:00 PM8/24/11
to object-composition
Next problem...

I have a role called Catalogue. It is used in the SalesContext, to
look up a Product based on the scanned bar code.

I now want to add a new use case. This use case is based on the
requirement for a sales person to be able to help a customer locate a
book, by searching for the title or ISBN number, which returns the
books details, including its location in the shop (like a shelf number
for example).

I have identified the role Catalogue which could be used to do this
search. The search is very similar to the search done in the sales
context. In order to reduce code duplication, I would like to add
this behaviour to the same role which looks up products in the sales
context.

But this is a different use case, so I cannot reuse the role!

One solution would be that using the catalogue would be done within a
new sub-context. If the sales context needs to look up a book, it
does so by starting a sub-context. If the customer wants to search
for a book, its done using that sub-context, this time as a main
context.

Does anyone else have any other ideas how similar/same behaviour can
be shared by several contexts?

Thanks,
Ant

James O. Coplien

unread,
Aug 24, 2011, 4:04:33 PM8/24/11
to object-co...@googlegroups.com

On Aug 24, 2011, at 8:24 , Ant Kutschera wrote:

> But this is a different use case, so I cannot reuse the role!


Grumble. I have run into this a number of times. We've discussed it before with an "ideological" conclusion that roles are indeed local to Contexts. There's something about that that I still find unsatisfying.

I have also worked this into my forthcoming example (it's coming... really...)

I think there is something worth pursuing here.

James O. Coplien

unread,
Aug 24, 2011, 4:06:17 PM8/24/11
to object-co...@googlegroups.com

On Aug 24, 2011, at 7:02 , Raoul Duke wrote:

> yeah, i can grok that. if i were a master's student with free time i'd
> try to do an overview paper of how people see that gray area /
> spectrum / range of options / context-dependent-ness.


Just become a professor and then make it the problem of your Ph.D. and MS students :-) (I seriously wish that I could do that!)

Risto Välimäki

unread,
Aug 24, 2011, 4:28:50 PM8/24/11
to object-co...@googlegroups.com


2011/8/24 James O. Coplien <jcop...@gmail.com>
I have found, that oftentimes similar things needed in different use cases need at leas a bit customization. And if you have to write for example a Role so that it fits two different Contexts, you quite likely have to add "ifs", parameters and so on so that the clean Role code gets polluted. And when you need to change the Use Case 1 a little bit, you make just a little change to your (shared) Role, and then your Use Case 2 will accidentally blow out.

For the sake of maintainability, cleaner code and even faster development, just keep your Roles local to the Context. (And yes, there are lots of other reasons to do this also.)

Btw. while we obviously think in terms of Roles when we think about UCs, the fact that a Catalog is a Role doesn't mean that we could not have Catalog Data class as well. To me, Catalog doesn't sound like much of a interaction, but more like database search. So in this case the solution is quite obvious (to me, at least, you may disagree with this):

1. Have a (or many, if you need to, and you may) Data class called Catalog, that has needed data abstraction methods and means of search Products (Product ids?) from the database.

2. Have a Catalog Role for each UC you need Catalog. Add all your Context-related Catalog methods into those Roles. If I am right, you are mostly just asking your Data object to get Products from database.

-Risto

Serge Beaumont

unread,
Aug 24, 2011, 4:35:10 PM8/24/11
to object-co...@googlegroups.com
I find it very good that roles are local to contexts: makes things very clean...

Just a thought: if you feel a need to share roles, would that mean that your roles and contexts are too coarse-grained? I can imagine that an often used "protocol" could be factored out into its own context-and-roles set (what's the name for that btw? a design pattern? ;-) ), which would then be triggered or wired in some way so that other sets can benefit from the behavior.

> --
> You received this message because you are subscribed to the Google Groups "object-composition" group.

> To post to this group, send email to object-co...@googlegroups.com.
> To unsubscribe from this group, send email to object-composit...@googlegroups.com.

Johan Eltes

unread,
Aug 24, 2011, 4:38:07 PM8/24/11
to object-co...@googlegroups.com
Alternatively, it may be an indication that it is a feature of the data (domain)?

/Johan

irwan azam

unread,
Aug 24, 2011, 10:02:37 PM8/24/11
to object-co...@googlegroups.com
Hi Ant
Do you really need to create a role just for doing lookup/query into the database? Eg : Catalogue/ProductFinder




--

Risto Välimäki

unread,
Aug 25, 2011, 1:14:30 AM8/25/11
to object-co...@googlegroups.com

To me, the simplest for of a role is just well choosed variable name for an object.

Such as:

var source = new Account();
var destination = new Account();

Above you see two Roles: source(account) and destination(account).

Usually that is not enough, but we need Roles with methods instead.

We think about use cases and algorithm in terms of roles. We have always thought. It's just DCI that finally supports that thinking.

-Risto

Ant Kutschera

unread,
Aug 25, 2011, 2:41:56 AM8/25/11
to object-composition
We have to be careful, not to fill that sub-context with lots and lots
of similar things (hence reducing code duplication), because doing so
pushes us in the direction of a service based solution. What I mean
is, all the behaviour which acts on a certain type of data is found in
one component. We could end up with this sub context being a
CatalogueService.

Doing so is better than having an OO style Catalogue, because the data
and behaviour are seperate. But we fail in terms of reviewability,
because if we deliver the sub context as part of the code to review,
it may contain stuff not directly related to the use case under
review.



So, "similar" behaviours each belong within the context to which they
apply.

That leaves "same" behaviour, where two use cases do identical stuff.
Imagine an admin screen where the user updates the price of a
product. The search by product code.

I've been using wrappers to write this project (because its really
simple, and I'm trying to experience problems with schizophrenia). As
such, the source code file for a context contains source for the
context and just the role interfaces. The role implementations are in
different source files, but scoped in the same Java package. Thinking
outside of the box, why couldn't I put any shared behaviour into a
common package, which any context can use? Any role implementations
in that common package would probably end up quite fine grained. I
don't know, I might try it out to see how satisfactory it is...

Antxt with lots and lots of similar things (hence reducing code
duplication), because doing so pushes us in the direction of a service
based solution. What I mean is, all the behaviour which acts on a
certain type of data is found in one component. We could end up with
this sub context being a CatalogueService.

Doing so is better than having an OO style Catalogue, because the data
and behaviour are seperate. But we fail in terms of reviewability,
because if we deliver the sub context as part of the code to review,
it may contain stuff not directly related to the use case under
review.



So, "similar" behaviours each belong within the context to which they
apply.

That leaves "same" behaviour, where two use cases do identical stuff.
Imagine an admin screen where the user updates the price of a
product. The search by product code.

I've been using wrappers to write this project (because its really
simple, and I'm trying to experience problems with schizophrenia). As
such, the source code file for a context contains source for the
context and just the role interfaces. The role implementations are in
different source files, but scoped in the same Java package. Thinking
outside of the box, why couldn't I put any shared behaviour into a
common package, which any context can use? Any role implementations
in that common package would probably end up quite fine grained. I
don't know, I might try it out to see how satisfactory it is...

Ant











Ant Kutschera

unread,
Aug 25, 2011, 2:50:24 AM8/25/11
to object-composition
Except that article doesn't contain the word "role".

I've searched in the past for roles in use cases and found very
little. A book (in german) which our analysts use as their main UML
reference has about two sentences on roles :-(

James O. Coplien

unread,
Aug 25, 2011, 4:22:54 AM8/25/11
to object-co...@googlegroups.com
There are two notions of the word "role" in DCI. One is the identifier, as Risto indicates below. In the book I call those "methodless roles." They are just a name.

Names evoke a meaning in a Context. (Read that fist as a statement purely about natural language, then about programming.) Identifiers alone have no meaning, no semantics. The semantics are in methodful roles.

One might be led to believe that Risto's mail confuses the two. It's a problem to have two copies of a substantial body of code, because the cost of coordinated update is substantial. It is not a problem to have the same methodless role name in several Contexts from the perspective of coordinated update, because the cost of such update is trivial.

James O. Coplien

unread,
Aug 25, 2011, 4:23:41 AM8/25/11
to object-co...@googlegroups.com

On Aug 25, 2011, at 7:41 , Ant Kutschera wrote:

> We have to be careful, not to fill that sub-context

Ant, I don't understand what you mean by "sub-context".

James O. Coplien

unread,
Aug 25, 2011, 4:24:56 AM8/25/11
to object-co...@googlegroups.com

On Aug 25, 2011, at 7:41 , Ant Kutschera wrote:

> We have to be careful, not to fill that sub-context with lots and lots
> of similar things (hence reducing code duplication), because doing so
> pushes us in the direction of a service based solution. What I mean
> is, all the behaviour which acts on a certain type of data is found in
> one component. We could end up with this sub context being a
> CatalogueService.


Are you referring to something like RM-ODP did with their universal notion of Account, Customer, etc., independent of context?

James O. Coplien

unread,
Aug 25, 2011, 4:25:56 AM8/25/11
to object-co...@googlegroups.com

On Aug 25, 2011, at 3:02 , irwan azam wrote:

Hi Ant
Do you really need to create a role just for doing lookup/query into the database? Eg : Catalogue/ProductFinder



I vote for it, probably. I'm doing much the same thing.

James O. Coplien

unread,
Aug 25, 2011, 4:29:31 AM8/25/11
to object-co...@googlegroups.com

On Aug 24, 2011, at 9:35 , Serge Beaumont wrote:

> Just a thought: if you feel a need to share roles, would that mean that your roles and contexts are too coarse-grained?

Maybe.

I'm doing an exercise in a Manhattan version of Dijkstra's algorithm. One context implements the use case of creating the path. Another context computes the minimum distance between nodes. Both of them have a role called Map (the map of the grid), which is identical.

I feel uncomfortable merging these two contexts, which makes me lean in the direction of answering "no" to your question. What do you think?

My current thinking on this is that we're looking at this all wrong, constrained by current languages. I think that the right way might be radically different than anything we've yet talked about here. The fundamental problem is that the structure of the issue is multi-dimensional, and we tend to think in about two and a half dimensions.

irwan azam

unread,
Aug 25, 2011, 4:31:19 AM8/25/11
to object-co...@googlegroups.com
I don't see any interaction involve and advantage to have it unless there are business process involve with other object.




--

James O. Coplien

unread,
Aug 25, 2011, 4:36:18 AM8/25/11
to object-co...@googlegroups.com
Rather than give an answer from what may be an inappropriate perspective let's explore it together.

The usual sequence for developing a use case is: user story –> user narrative –> use case. User stories are good for little more than tagging other artefacts, so we'll skip that.

Start by writing a user narrative (NOT a user story). It is just an informal story that describes, from a human perspective, around the use case. Choose names carefully as they will be hints for an actor. It should be a half page or so in length.

Risto Välimäki

unread,
Aug 25, 2011, 4:37:15 AM8/25/11
to object-co...@googlegroups.com
2011/8/25 James O. Coplien <jcop...@gmail.com>

There are two notions of the word "role" in DCI. One is the identifier, as Risto indicates below. In the book I call those "methodless roles." They are just a name.

I avoided using term "methodless role", since usage of that has been quite ambiguous in this list.
 
Names evoke a meaning in a Context. (Read that fist as a statement purely about natural language, then about programming.) Identifiers alone have no meaning, no semantics. The semantics are in methodful roles.

Huh? "var sourceaccount" itself doesn't have meaning or semantics? That's news to me. If I wanted no meaning or no semantics, I could have used "var a" instead. Which, is quite standard with for example "int i, j, k" and so on with meaningless variables without any kind of semantics.

We probably have really different definitions for terms "meaning" and "semantics".

One might be led to believe that Risto's mail confuses the two.

I guess you didn't read carefully my post? I wrote:
>> Usually that is not enough, but we need Roles with methods instead. 

For example, in canonical MoneyTransfer Context example it's very possible that only SourceAccounts "methodful role" has any methods in it (method transferTo).

It's a problem to have two copies of a substantial body of code, because the cost of coordinated update is substantial. It is not a problem to have the same methodless role name in several Contexts from the perspective of coordinated update, because the cost of such update is trivial.

Agreed. And of course it's not a problem to have the same methodless or methodful role name in several Context, because those Roles are always local to their Contexts.

-Risto 

On Aug 25, 2011, at 6:14 , Risto Välimäki wrote:

To me, the simplest for of a role is just well choosed variable name for an object.

Such as:

var source = new Account();
var destination = new Account();

Above you see two Roles: source(account) and destination(account).

Usually that is not enough, but we need Roles with methods instead.

We think about use cases and algorithm in terms of roles. We have always thought. It's just DCI that finally supports that thinking.


James O. Coplien

unread,
Aug 25, 2011, 4:47:53 AM8/25/11
to object-co...@googlegroups.com

On Aug 25, 2011, at 9:37 , Risto Välimäki wrote:

Huh? "var sourceaccount" itself doesn't have meaning or semantics? That's news to me. If I wanted no meaning or no semantics, I could have used "var a" instead. Which, is quite standard with for example "int i, j, k" and so on with meaningless variables without any kind of semantics.

We probably have really different definitions for terms "meaning" and "semantics".

You're right; I apologize. It lacks an epistemological grounding sufficient to represent the mental model and to support the hermeneutical run-time enactment of the semantics, outside the context of the user perception alone.

James O. Coplien

unread,
Aug 25, 2011, 4:49:38 AM8/25/11
to object-co...@googlegroups.com
On Aug 25, 2011, at 9:37 , Risto Välimäki wrote:

And of course it's not a problem to have the same methodless or methodful role name in several Context, because those Roles are always local to their Contexts.

Yes, it is a problem. I think that's the point of the original posting.

Procedures were a wonderful invention because they provided a single, closed copy of commonly used code. That meant that there was a single locus of understanding the system in general, and the algorithm in particular. More importantly, if the world changed, you'd have a single locus of change rather than having to change all of the open copies.

Ant Kutschera

unread,
Aug 25, 2011, 5:10:45 AM8/25/11
to object-composition
I have another bit of code which is causing me mental problems.

My data has been refactored, so that I have a Till (contains the cash
balance, the selected payment type). The Till contains a Basket
(contains a list of scanned products). The Till also contains an
optional Customer, if the customers loyalty card was scanned (not sure
I mentioned that in the original use case, but that card discounts
everything in the basket). The Till also contains a Catalogue, which
is a list of every product, and the search results. At the moment, I
haven't connected to a database, so the Catalogue is indeed data.
(There is also a role called Catalogue, which does the work to search
for books in the Catalogue data.)

So, I have a tree like structure in my data.

I have a role called Screen, which needs to be played. It's main job
is to list the objects in the basket on the monitor. So originally it
was the Basket which played the roll of Screen. But, the user also
needs to see the payment type that is currently selected, and that
data is part of the Till. So should the screen be played by the Till
rather than the Basket, even though most of the data it uses comes
from the basket? Or should it be played by the Basket, but be passed
the Till (or the payment type?) so that it can draw that data on the
monitor?

I guess the Screen should be played by the Till, because the Till
contains all the data which the screen needs, but I am finding that
all my roles are played by the Till.

This exercise is really a good one, because I'm am finding that there
are so many questions popping up in my head about how to design a DCI
solution. Reading this makes me sound like a total newbie... I have
no problems designing nice maintainable software in very complex
domains, when I use SOA mixed with OO on the client. But DCI is
(again) causing me headaches.

Here is another question: I've been trying to avoid putting business
code into the context, because how I understand it, the context is
there to do role assignment and start the interaction. But I have
several cases where I would like to have my roles methods return data,
which I can use to update my model in the context. That way, my role
only needs to know about a small part of the data, rather than always
knowing about the Till.

Wenig, Stefan

unread,
Aug 25, 2011, 5:13:04 AM8/25/11
to object-co...@googlegroups.com
Are you mixing UI and business logic in one context?

You would not do that in a real-world app, so why to it in a sample?


Stefan

> --
> You received this message because you are subscribed to the Google
> Groups "object-composition" group.
> To post to this group, send email to object-

> compo...@googlegroups.com.


> To unsubscribe from this group, send email to object-

> composition...@googlegroups.com.

Trygve Reenskaug

unread,
Aug 25, 2011, 5:13:55 AM8/25/11
to object-co...@googlegroups.com
UML 2.x has a whole package devoted to Collaborations and their roles. Their use the word 'role'  corresponds roughly to our usage.
UML Collaborations stem from my old role modeling and, IMO, they have got it right this time by making the role an instance variable in the Collaboration class. (As opposed to UML 1.x, where a role was a classifier with instances.)

Authors on UML seem to be hemmed in by class thinking. I am not surprised that your author hasn't understood roles and Collaborations. I think you will be best served by looking up the UML 2.x superstructure specification and read the Collaborations package. You can download the latest official version (UML 2.3)) from
    http://www.omg.org/spec/UML/2.3/Superstructure/PDF/
The Collaboration class is described in section 9.3.3 on page 174 and the description there is a quite readable introduction, IMO

I expect you will enjoy this quote is from the introduction to Composite structures (section 9.1). It  may be sufficient for your purpose and save you  reading the admittedly unreadable and sometimes inconsistent document:

"Collaborations
Objects in a system typically cooperate with each other to produce the behavior of a system. The behavior is the
functionality that the system is required to implement.

A behavior of a collaboration will eventually be exhibited by a set of cooperating instances (specified by classifiers) that
communicate with each other by sending signals or invoking operations. However, to understand the mechanisms used in
a design, it may be important to describe only those aspects of these classifiers and their interactions that are involved in
accomplishing a task or a related set of tasks, projected from these classifiers. Collaborations allow us to describe only
the relevant aspects of the cooperation of a set of instances by identifying the specific roles that the instances will play.
Interfaces allow the externally observable properties of an instance to be specified without determining the classifier that
will eventually be used to specify this instance. Consequentially, the roles in a collaboration will often be typed by
interfaces and will then prescribe properties that the participating instances must exhibit, but will not determine what class
will specify the participating instances.
"

--Trygve.
--

Trygve Reenskaug       mailto: try...@ifi.uio.no

Morgedalsvn. 5A         http://folk.uio.no/trygver/

N-0378 Oslo               Tel: (+47) 22 49 57 27

Norway

Risto Välimäki

unread,
Aug 25, 2011, 5:32:47 AM8/25/11
to object-co...@googlegroups.com
Why not first explain the use case in common words such as:

"Customer buys books"

1. Customer finds Interesting Books (from where?, I guess from Catalog?)
2. Customer adds books to Basket
3. Customer pays for content of the Basket (to whom? I guess to the Till?)

Now you have 5 different roles here:

A) Customer (played by Human)
B) Interesting Book(s) (played by Book(s))
C) Catalog of books (quite likely played by a Catalog Data object)
D) Basket containing those Interesting Books (and probably other things), (played by some sort of Container)
E) Till for paying contents of the Basket

Think of these first. Do not start thinking about Views and user interfaces untill all your Roles, roleplayers and UC steps are defined.

Btw. I have found it quite natural to have (at least) one View per Context. 

-Risto

2011/8/25 Ant Kutschera <ant.ku...@gmail.com>

Ant Kutschera

unread,
Aug 25, 2011, 5:43:53 AM8/25/11
to object-composition
Here is a perfect example of my head aches:

To complete a sale, I have these steps to implement:

0. Check i have enough paper in the printer
1. Create the sales order (a sales order is an auditing thing which
describes exactly what was sold)
2. Create the sales log (this is a simple set of records saying which
product code was sold for how much, and what discounts were applied,
and is delivered to the accounting department)*
3. Update the till's cash balance, if the sale was with the cash
payment type
4. Print the receipt using the printer (involves a lot of logic to do
with how to layout the lines to be printed)
5. Reset the Till (empty the basket, remove the customer from the
model, etc.)

(* let's not discuss that a sales order and sales log are really
similar - I have modelled this on something that a real customer of
mine has done)

I have a context, the SalesContext, which does all this stuff.

In that context, I have these roles:

- Printer (played by Till, because I need basket info, and the
customer number out of the Customer object which is part of the Till)
- Accountant (persists the audit objects and sales log, updates the
till's cash balance if required)

I did have this code:

// ***********
// ROLE ASSIGNMENT
// ***********
Accountant accountant = new AccountantImpl(till);
Printer printer = new PrinterImpl(till);

// ***********
// start the interaction
// ***********
accountant.completeSale(printer);

Two problems:

1) the till is playing all the roles, not so bad I guess
2) the accountant starts the interaction. That means, it checks the
printer has enough paper and the accountant tells the printer to print
- I dont like this at all! The accountant has the responsibilities
listed above, namely:

"persists the audit objects and sales log, updates the till's cash
balance if required"

It does not have the responsibility to talk to the printer.

So... I moved the printing back into the context. My context now
looks like this:

if(till.hasEnoughPaper()){
accountant.completeSale();
printer.printReceipt();
}else{
till.getErrorInformation().setError("Not enough paper!");
}

Now, I have another problem. The acountant has already updated the
till as part of completing the sale, which causes it to reset itself.
That means, the list of products, which the printer needs, is empty!

So... I need to split the role method "completeSale" into two:

if(!till.getBasket().isEmpty()){
if(till.hasEnoughPaper()){
accountant.completeSale();
printer.printReceipt();
accountant.updateTill();
}else{
till.getErrorInformation().setError("Not enough paper!");
}
}else{
till.getErrorInformation().setError("Nothing to sell!");
}

I also added a check that I have something to sell.

This is all code which is in the context - seems like a lot really.
I think it looks good like this, but I'm worried that it will be
criticized for having business code outside of roles.

Or do you think it is OK to put lots of code and decision making in
the context?

Ant Kutschera

unread,
Aug 25, 2011, 5:48:16 AM8/25/11
to object-composition
On Aug 25, 11:13 am, "Wenig, Stefan" <stefan.we...@rubicon.eu> wrote:
> Are you mixing UI and business logic in one context?
>
> You would not do that in a real-world app, so why to it in a sample?

I don't think so. Where do you think I am mixing things up?

Ant Kutschera

unread,
Aug 25, 2011, 5:59:31 AM8/25/11
to object-composition
On Aug 25, 11:32 am, Risto Välimäki <risto.valim...@gmail.com> wrote:
> 1. Customer finds Interesting Books (from where?, I guess from Catalog?)
> 2. Customer adds books to Basket
> 3. Customer pays for content of the Basket (to whom? I guess to the Till?)

Completing a sale is a different use case than searching for books.
The original use case in this thread dealt only with completing the
sale.

> A) Customer (played by Human)
> C) Catalog of books (quite likely played by a Catalog Data object)
> D) Basket containing Books (and probably other things),
> E) Till for paying contents of the Basket

pretty much what I have

> B) Interesting Book(s) (played by Book(s))
not relevant to this use case

> Think of these first. Do not start thinking about Views and user interfaces
> untill all your Roles, roleplayers and UC steps are defined.

The use case talks a lot about the UI. I wrote it that way, since I
think that is how James did it in his Lean Arch. book (can't quite
remember, and don't have Jims book to hand right now). I then listed
the behaviours which the system should do, as part of the use case -
perhaps not conventional, but I wanted to show the steps which the
system does. They hardly mention UI.

> Btw. I have found it quite natural to have (at least) one View per Context.

In web yes, but this is a rich client - so I only have one view. The
screen (or page) which is displayed is in fact always the same one.
There is definitely only one view in my mental model.

Thanks for the inputs - this is a great thread :-)

Ant

Trygve Reenskaug

unread,
Aug 25, 2011, 6:04:49 AM8/25/11
to object-co...@googlegroups.com
Many people find there is a need for sharing RoleMethods between Contexts. It looks like might be an as yet unrecognized requirement deep down. On the face of it, reusing the exactly same code in different Contexts seems very exotic to me. The code for a RoleMethod references RolePlayers by name. The names are bound to objects by the CurrentContext at runtime. So two Conexts sharing a RoleMethod must at least have a common set of role names. It also seems to me that the RolePlayers must have the same responsibilities since a RoleMethod satisfies its part of the Context's total responsibility. Further, The RolePlayers must have a shared interface,.

I suspect that it is easy to be led astray by analogies to human behavior and language. A human waiter is a waiter is a waiter. Our mind and language has no problem with combining the waiter's behavior when he (1) gives us a new fork because we lost our own on the floor and (2) gives us the bill after we have waited for a long time. It's the same waiter, for heaven's sake. But imagine that you are to program a waiter robot. Then you will have to face how hard it is to change context programatically in a situation where our mind does it subconsciously.

I also suspect that there may be an overuse of DCI behind it. I am writing a message that reports an experiment with implementing and using the GOF Observer pattern. I have found that DCI has nothing to offer in this case. A very satisfactory solution is to implement is as UML Collaboration; we could probably call it a mechanism. See my message about it that I sent less than an hour ago. More about this solution later.

Cheers
--Trygve

Risto Välimäki

unread,
Aug 25, 2011, 6:15:57 AM8/25/11
to object-co...@googlegroups.com
2011/8/25 Ant Kutschera <ant.ku...@gmail.com>

On Aug 25, 11:32 am, Risto Välimäki <risto.valim...@gmail.com> wrote:
> Think of these first. Do not start thinking about Views and user interfaces
> untill all your Roles, roleplayers and UC steps are defined.

The use case talks a lot about the UI.  I wrote it that way, since I
think that is how James did it in his Lean Arch. book (can't quite
remember, and don't have Jims book to hand right now).  I then listed
the behaviours which the system should do, as part of the use case -
perhaps not conventional, but I wanted to show the steps which the
system does.  They hardly mention UI.

Talking about specific things about UI in UC definition is usually considered Bad Idea. 

Use Case definition should express the needs of users. UX and UI teams then should translate those UCs into sketch wireframes (some prefer working prototypes though, but they are expensive) and then after some iterations into polished UIs.

Requirements elicitation guy write those UCs. Usability guy turn those UCs into usable wireframes. Graphical designer turns those wireframes into attractive layouts. UI coder turns those layouts into working UIs. And all the way, that annoying usability guy is giving his annoying opinions. (In the real world, that RE+UX+GD+UI -guy might be just one person. Been there, done that.)

-Risto

Wenig, Stefan

unread,
Aug 25, 2011, 6:22:34 AM8/25/11
to object-co...@googlegroups.com
I didn't see the code, so I might be wrong, but it seems you have a Screen role in the same context you use to handle your business logic (filling carts, calculating taxes...)

These things are usually in different layers (separate assemblies/packages/...). I don't see a single context span both UI and domain.

Stefan

> -----Original Message-----
> From: object-co...@googlegroups.com [mailto:object-
> compo...@googlegroups.com] On Behalf Of Ant Kutschera
> Sent: Thursday, August 25, 2011 11:48 AM
> To: object-composition
> Subject: Re: Identifying Roles
>

James O. Coplien

unread,
Aug 25, 2011, 6:23:58 AM8/25/11
to object-co...@googlegroups.com

On Aug 25, 2011, at 11:04 , Trygve Reenskaug wrote:

we could probably call it a mechanism.


Wow. There's an old term. Grady Booch has been using this term since the 1980s. There is an extensive introduction to mechanisms in the last chapter of the old Advanced C++ book. It will be 20 years old on 9 September.

And I think it's exactly the right word in this context. I'll wait to see your report, because I'm not yet sure that DCI mechanisms are disjoint.

James O. Coplien

unread,
Aug 25, 2011, 6:32:09 AM8/25/11
to object-co...@googlegroups.com
On Aug 25, 2011, at 11:15 , Risto Välimäki wrote:

Talking about specific things about UI in UC definition is usually considered Bad Idea. 

+1


Use Case definition should express the needs of users. UX and UI teams then should translate those UCs into sketch wireframes (some prefer working prototypes though, but they are expensive) and then after some iterations into polished UIs.

Even better, it's usually sufficient either to employ use cases or the usual UX artefacts (e.g., see Beyer and Holtzblatt) to support communication of requirements between the business and the team. Using both is usually overkill, and from experience we find that no one really uses them.

At least, this is the Lean / Agile view of things. It's important to realize that use cases are not the requirements: they just represent the requirements. Use cases are used to document agreements and decisions between the business and the developers. Using use cases to communicate requirements usually doesn't work. What does work is to convey the human mental model in one-on-one conversation.

See Chapter 3 (http://www.leansoftwarearchitecture.com/home/engaging-the-stakeholders) and Chapter 7 in the Lean Arch book.

Ant Kutschera

unread,
Aug 25, 2011, 6:55:28 AM8/25/11
to object-composition
On Aug 25, 12:22 pm, "Wenig, Stefan" <stefan.we...@rubicon.eu> wrote:
> I didn't see the code, so I might be wrong, but it seems you have a Screen role in the same context you use to handle your business logic (filling carts, calculating taxes...)
>
> These things are usually in different layers (separate assemblies/packages/...). I don't see a single context span both UI and domain.

No, the code which responds to user inputs (call it a controller,
although for experimentation, it is actually a role in my code), calls
a context to do the business stuff, which modifies the data. After
that context completes, the controller tells the UI to update itself.

I am not sure I would really use DCI for the view and controller. But
I did it to see what the code looked like. It's readible and not bad
actually. It was fun to do it like that, and doesn't really cause the
problems I talk about.

Ant Kutschera

unread,
Aug 25, 2011, 7:00:01 AM8/25/11
to object-composition
On Aug 25, 12:32 pm, "James O. Coplien" <jcopl...@gmail.com> wrote:

Didn't your Lean Architecture book have a use case that had two
columns, one with the users perspective, and one with a more techie
one (or at least from the point of view of what the system does)?

It's been a year since I read it, and I've put it someplace I cant
find it...

Ant Kutschera

unread,
Aug 25, 2011, 7:40:13 AM8/25/11
to object-composition
On Aug 25, 11:43 am, Ant Kutschera <ant.kutsch...@gmail.com> wrote:
> Here is a perfect example of my head aches:

I have a similar problem when in the context called "Add to
Cart" (I've broken my original UC into smaller steps, since the
original was too messy to program in one context).

In the context of putting things into the cart, I have the Catalogue
(role), which finds the book based on the product code, and I have the
Cart (role) which adds the product to the cart.

Catalogue catalogue = new CatalogueImpl(till);
Cart cart = new CartImpl(till);

(the cart is a role, because adding to the cart isn't as simple as
adding to a list. I have to make a copy of the book, for technical
reasons, so that if I modify that instance's discount, I don't modify
the original book in the catalogue! this is just techie stuff though,
so ignore it).

I then start the interaction:

// ***********
// ROLE NETWORK
// tell roles about each other so they can interact
// ***********
catalogue.setCart(cart);

// ***********
// start the interaction
// ***********
catalogue.retrieveProductAndAddToCart(productCode);

Now that looks ok. But, there are failure cases to be handled. What
if the catalogue cannot find the book?

The role method in the catalogue currently does this:

public void retrieveProductAndAddToCart(String productCode) {
Book book = self.getAllProducts().get(productCode);
getLog().info("found for product code '" + productCode + "': " +
book);

if(book != null){
cartAdder.addToCart(book);
}else{
getLog().info("Unknown product. Getting price...");
self.getErrorInformation().setError("Book unknown. Please enter
price:");
self.getErrorInformation().setWaitingForPrice(productCode);
}
}

But I don't like this. Firstly, it is not the responsibility (in my
mental model) for the catalogue to add the book to the cart. That is
more like something which the system does. The system uses the
catalogue to find the book, and then uses the cart to add the book to
the cart. But, I don't have a role called System (if I did, I fear I
would give up and build a SOA solution).

Also, the Catalogue is being played by the Till, rather than the
Catalogue (data), because the role method above needs access to the
error information in the till, so it can inform the user of an error,
the next time the screen is refreshed. The use case states that the
system should stop the user from scanning any more books, and it
should request the price that is printed on the books price tag.

So, I'm doing things in this Catalogue role, which I don't think
belong are the responsibility of the Catalogue.

Ideally, I would remove the code to somewhere else... How about the
context? That way, the Catalogue (data) can play the role of the
Cataloge (role), and the Basket (data) can play the role Cart:


/** this is the context in which we add products to the cart */
public class AddToCartContext {

private final Till till;

public AddToCartContext(Till till) {
this.till = till;
}

/** role for retrieving products from the database */
protected interface Catalogue {
/** @return retrieves the product based the code, or null if not
found. */
Book retrieveProduct(String productCode);
}

/** role for working with the cart */
protected interface Cart {
/** adds the given book to the cart */
void addToCart(Book book);
}

public void executeAdd(String productCode) {

// ***********
// ROLE ASSIGNMENT
// the till needs to be cast to several roles in order to be able to
do anything useful
// ***********
Catalogue catalogue = new CatalogueImpl(till.getCatalogue());
Cart cart = new CartImpl(till.getBasket());

// ***********
// start the interaction
// ***********
Book book = catalogue.retrieveProduct(productCode);
if(book != null){
cart.addToCart(book);
}else{
till.getErrorInformation().setError("Book unknown. Please enter
price:");
till.getErrorInformation().setWaitingForPrice(productCode);
}
}

}


Again, I have code in the context. I can live with that - it seems to
fit better there, than in a role method. Anyone disagree? the use
case code for adding to the cart is entirely contained in the context
and its two roles - its very reviewable.

James O. Coplien

unread,
Aug 25, 2011, 7:40:15 AM8/25/11
to object-co...@googlegroups.com

On Aug 25, 2011, at 10:32 , Risto Välimäki wrote:

"Customer buys books"

1. Customer finds Interesting Books (from where?, I guess from Catalog?)
2. Customer adds books to Basket
3. Customer pays for content of the Basket (to whom? I guess to the Till?)

Gotta close off those open questions.

Good use cases avoid roles like "Customer" and "User." You want to drive towards personæ. The use case for a College Student is different for that for a Senior Citizen which is different from that for an Engineer. Some will browse; some will use the Catalog; some will ask an Employee for help. Getting these variations is hard, but having personæ helps.

Once you've developed a few personæ you can move on to developing user profiles. Most professional requirements efforts start with market characterizations that give them user profiles; personæ are usually done by organizations who want to do this "on the cheap." Once you have the profiles, you can develop a user narrative for each and then go forward in developing the use case with its scenarios.

James O. Coplien

unread,
Aug 25, 2011, 7:41:26 AM8/25/11
to object-co...@googlegroups.com

On Aug 25, 2011, at 11:55 , Ant Kutschera wrote:

> On Aug 25, 12:22 pm, "Wenig, Stefan" <stefan.we...@rubicon.eu> wrote:
>> I didn't see the code, so I might be wrong, but it seems you have a Screen role in the same context you use to handle your business logic (filling carts, calculating taxes...)
>>
>> These things are usually in different layers (separate assemblies/packages/...). I don't see a single context span both UI and domain.
>
> No, the code which responds to user inputs (call it a controller,
> although for experimentation, it is actually a role in my code), calls
> a context to do the business stuff, which modifies the data. After
> that context completes, the controller tells the UI to update itself.

It might be better to use MVC. In MVC it's not the controller's job to tell the UI to update itself. Updating the UI is the UI's decision. All that the UI needs to know is that there is a potential for change in its View, and it's the Model role's job to let the Views know that — not the Controller.


> I am not sure I would really use DCI for the view and controller.

It's been done and I liked what I saw then. Trygve, where does your example live?

Ant Kutschera

unread,
Aug 25, 2011, 7:46:50 AM8/25/11
to object-composition
Do you mean you vote to use a role, or not?

Ant Kutschera

unread,
Aug 25, 2011, 7:48:10 AM8/25/11
to object-composition
A sub-context: A role method within a context, creates and starts a
different context. OK?

On Aug 25, 10:23 am, "James O. Coplien" <jcopl...@gmail.com> wrote:
> On Aug 25, 2011, at 7:41 , Ant Kutschera wrote:
>
> > We have to be careful, not to fill that sub-context
>
> Ant, I don't understand what you mean by "sub-context".

Ant Kutschera

unread,
Aug 25, 2011, 7:57:15 AM8/25/11
to object-composition
On Aug 25, 10:24 am, "James O. Coplien" <jcopl...@gmail.com> wrote:
> On Aug 25, 2011, at 7:41 , Ant Kutschera wrote:
>
> > We have to be careful, not to fill that sub-context with lots and lots
> > of similar things (hence reducing code duplication), because doing so
> > pushes us in the direction of a service based solution. What I mean
> > is, all the behaviour which acts on a certain type of data is found in
> > one component.  We could end up with this sub context being a
> > CatalogueService.
>
> Are you referring to something like RM-ODP did with their universal notion of Account, Customer, etc., independent of context?

I don't think so, I don't know what RM-ODP is ;-) Or is it related to
the "Party" role, for representing people?

My thinking here was this: I created a context for doing product
retrieval. Initially, it did the retrieval by a primary key lookup.
The context contained one role: Catalogue, and that had one role
method: getProduct(productCode).

Then in a different context, I wanted to do a different but similar
kind of search in the catalogue (data). So that second context had
the role Catalogue. But this catalogue role was different to the
first one, because it had a role method: findProduct(pattern).

I realised that there was some code that I was duplicating (but not
all of it).

So I decided to merge the two contexts (seeing as they were both
concerned with searching in the catalogue).

(Maybe worth mentioning, that context isn't useful on its own, but is
a sub-context called by other contexts, such as "locate book", "update
book price", "add to basket").

So, what I was trying to warn against, was to keep adding more and
more role methods to this new (merged) (sub) context. The problem
with bloating it is that if you want to give some code to a reviewer,
they end up with code which is not related to the use case which they
are reviewing. That is bad. And it is effectively the same as
building a "CatalogueService", whose responsibility is to contain all
behaviour related to the catalogue (data).

Make sense?

Ant Kutschera

unread,
Aug 25, 2011, 8:05:38 AM8/25/11
to object-composition
On Aug 25, 1:41 pm, "James O. Coplien" <jcopl...@gmail.com> wrote:
> It might be better to use MVC. In MVC it's not the controller's job to tell the UI to update itself. Updating the UI is the UI's decision. All that the UI needs to know is that there is a potential for change in its View, and it's the Model role's job to let the Views know that — not the Controller.

Absolutely. Although, I did wonder if by not using the Observer-
Observable pattern, I had made the code more readable... namely I can
explicitly see the call to the screen to update itself, right after I
change the model. With O-O, I don't see that at all, it happens
magically. It's sometimes worth trying crazy things, just to see if
they can improve the world :-)

James O. Coplien

unread,
Aug 25, 2011, 9:21:38 AM8/25/11
to object-co...@googlegroups.com

On Aug 25, 2011, at 12:46 , Ant Kutschera wrote:

> Do you mean you vote to use a role, or not?

Let me defer my answer until we get the user narrative down and some use cases developed. To me, a Catalog is a perfectly good role that is rich with many operations. It can be implemented in many ways. Sounds like a role to me.

James O. Coplien

unread,
Aug 25, 2011, 9:22:51 AM8/25/11
to object-co...@googlegroups.com

On Aug 25, 2011, at 1:05 , Ant Kutschera wrote:

> It's sometimes worth trying crazy things, just to see if
> they can improve the world :-)


You radical, you.

Wenig, Stefan

unread,
Aug 25, 2011, 9:25:40 AM8/25/11
to object-co...@googlegroups.com
Then I'm just losing track of the various contexts you're talking about. Maybe email doesn't do it any more for such an elaborate sample.

> -----Original Message-----
> From: object-co...@googlegroups.com [mailto:object-
> compo...@googlegroups.com] On Behalf Of Ant Kutschera
> Sent: Thursday, August 25, 2011 12:55 PM
> To: object-composition
> Subject: Re: Identifying Roles
>

Ant Kutschera

unread,
Aug 25, 2011, 10:39:32 AM8/25/11
to object-composition
Well, no worries, I will be (already have been) writing all this up,
as I go.

James O. Coplien

unread,
Aug 26, 2011, 2:58:23 PM8/26/11
to object-co...@googlegroups.com
On Aug 23, 2011, at 1:49 , Wenig, Stefan wrote:

Actors interact with the system, so what is an actor and what is not depends on your system boundaries. A business use case would include the customer, this system use case does not because the customer only interacts with the employee (an actor), not the system (till).

At least that's what I always thought. 
http://practicalanalyst.com/2008/05/21/quick-tip-to-help-identify-use-case-actors/

Use cases are about collections of possible scenarios between end users and a system under construction. That is, a use case is an analysis entity that drives towards a business goal (what Cockburn calls a goal).

The practicalanalyst article suggests that we include customers. Customers are one of the actors. It says: "I’ve found that it’s easy to identify the actors that are users of the system." I do think the practicalanalyst page departs both from Jacobsson and Cockburn when it takes design issues into consideration: that's usually viewed as being outside the realm of use case expression or consideration.

The distinction between system and business use cases very rarely adds value. It usually adds confusion. It relates more closely to Jacobsson's use case theory than to anything in practice. We've seen it useful only once: in a legal registration system, where the process is so large and encompasses so many bank contexts that it was useful to characterize business use cases for the big picture view, and system use cases for each business within the bank where registration was a small part of a larger use case. The latter was useful for developing the system. The business use cases really weren't useful for what we call Contexts in DCI: they were useful for delineating the what-the-system-is part of domain analysis. But to call both of these "use cases" just added confusion for all but the use case experts, and it would have maybe been better just to use the system use cases, because they are what drive the functional implementation.


James O. Coplien

unread,
Aug 26, 2011, 3:00:40 PM8/26/11
to object-co...@googlegroups.com
O.K., so a role is not an object. Agreed.

I find the rest of your points to be right on: refreshingly poignant, in the best possible way.


On Aug 23, 2011, at 1:58 , Wenig, Stefan wrote:

>> From: James O. Coplien
>> Sent: Monday, August 22, 2011 10:30 PM
>>
>> On Aug 22, 2011, at 8:11 , Wenig, Stefan wrote:
>>
>>> Roles are just objects,
>>
>> Well, not in DCI, not in UML, not in English. Where is a role an
>> object?
>
> Of course, it is played by an object. But thinking about which role gets a method is not so much different from thinking which object should get it, is it?
>
> Let's look at how the system evolves. A typical situation is that you identify the main use cases and design an object model around them with the help of domain experts (what the system is). Then you implement more and more use cases on this model (what the system does), and they evolve together, incrementally.
>
> Now one difference in DCI is that the use case is implemented in its own module, with all the behavior isolated from the objects. But we still need objects to play these roles, so we cannot look at it isolated. There need to be objects (or systems of objects) in the object model that can play these roles.
>
> (And of course roles can serve as an additional abstraction, they do not necessarily depend on concrete or abstract classes. They do have structural requirements though.)
>
> My conclusion is that we can fully exploit our OO experience when modeling roles and role methods within a context, and any other mindset could possibly be misleading (e.g. SOA). There are differences, some additional things to consider, maybe some to unlearn, but it's a good starting point.
>
> Stefan


>
> --
> You received this message because you are subscribed to the Google Groups "object-composition" group.

> To post to this group, send email to object-co...@googlegroups.com.
> To unsubscribe from this group, send email to object-composit...@googlegroups.com.

James O. Coplien

unread,
Aug 27, 2011, 4:19:44 PM8/27/11
to object-co...@googlegroups.com
There is a tradeoff here between keeping all the scenarios of a use case together (good cohesion) and separating each scenario into its separate context (more easily readable chunks of code, but poor cohesion and potentially high inter-Context coupling).

I think there are no final answers: it comes down to good taste and good design.

On Aug 24, 2011, at 10:28 , Risto Välimäki wrote:



2011/8/24 James O. Coplien <jcop...@gmail.com>

On Aug 24, 2011, at 8:24 , Ant Kutschera wrote:

> But this is a different use case, so I cannot reuse the role!


Grumble. I have run into this a number of times. We've discussed it before with an "ideological" conclusion that roles are indeed local to Contexts. There's something about that that I still find unsatisfying.

I have also worked this into my forthcoming example (it's coming... really...)

I think there is something worth pursuing here.

I have found, that oftentimes similar things needed in different use cases need at leas a bit customization. And if you have to write for example a Role so that it fits two different Contexts, you quite likely have to add "ifs", parameters and so on so that the clean Role code gets polluted. And when you need to change the Use Case 1 a little bit, you make just a little change to your (shared) Role, and then your Use Case 2 will accidentally blow out.

For the sake of maintainability, cleaner code and even faster development, just keep your Roles local to the Context. (And yes, there are lots of other reasons to do this also.)

Btw. while we obviously think in terms of Roles when we think about UCs, the fact that a Catalog is a Role doesn't mean that we could not have Catalog Data class as well. To me, Catalog doesn't sound like much of a interaction, but more like database search. So in this case the solution is quite obvious (to me, at least, you may disagree with this):

1. Have a (or many, if you need to, and you may) Data class called Catalog, that has needed data abstraction methods and means of search Products (Product ids?) from the database.

2. Have a Catalog Role for each UC you need Catalog. Add all your Context-related Catalog methods into those Roles. If I am right, you are mostly just asking your Data object to get Products from database.

-Risto

James O. Coplien

unread,
Aug 27, 2011, 4:23:26 PM8/27/11
to object-co...@googlegroups.com

On Aug 25, 2011, at 1:00 , Ant Kutschera wrote:

> Didn't your Lean Architecture book have a use case that had two
> columns, one with the users perspective, and one with a more techie
> one (or at least from the point of view of what the system does)?


The columnar format is Rebecca Wirfs-Brocks. The first column is for the primary actor(s) and the second is for the system and its response.

The second column is NOT a techie perspective. It is a business perspective on the responses of the system under construction. Good use cases leave convey the business needs without constraining the technology: you don't want to over-constrain the developers.

This is a common error and misapplication of use cases, especially when developers, nerds, and CS people write them.

Ant Kutschera

unread,
Aug 27, 2011, 5:29:38 PM8/27/11
to object-composition
Ah, I remember now - thanks.

Ant Kutschera

unread,
Aug 28, 2011, 5:13:24 PM8/28/11
to object-composition
Hi all,

Based on the discussion on the "GOF Observer Pattern" Thread (http://
groups.google.com/group/object-composition/browse_thread/thread/
c4752b3e88686607#1875d66d51efdf4a), I have rewritten my use case, and
taken a look at identifying roles from a different angle. The results
are really good, so I shall share them. The only bit I am unsure of
is near the bottom, and I am interested in getting feedback...

Here is the use case (it might not be perfect, but the important part
is the steps which it lists). I have written the important words in
CAPITALS.

Use Case: "Sell items in basket".
Triggered by: SALES AGENT (primary actor), when they hit the "C" key.
Steps:

1. Check if the BASKET contains items. If not, just show an error.
2. Check the PRINTER has paper. If not, just show an error.
3. If the payment type is electronic, then:
3.1 get authorization from the PAYMENT PARTNER
3.2 if no authorization is given, just show an error.
4. create the SALES ORDER in the SALES ORDER DATABASE (auditing)
5. create the SALES LOG RECORDS in the SALES LOG (accounting)
6. print the receipt on the PRINTER
7. update TILL's cash balance, if the payment type was cash
8. empty BASKET

Now, here is a quick list of the objects that I have previously
identified, while looking at "what the system is". These objects
contain no system behaviour, just system state.

TILL
- cashBalance : double //how much cash is in the till
- amountOfPaper : double //how much paper is in the printer

BASKET
- products : List //the products in the basket
- customer : Customer //if a loyalty card was scanned, this is the
customer, otherwise null

So, looking at the use case, and all the words in capitals, I have:

- SALES AGENT
- BASKET
- PRINTER
- PAYMENT PARTNER
- SALES LOG RECORDS
- SALES LOG
- SALES ORDER
- SALES ORDER DATABASE
- TILL

The SALES AGENT isn't really relevant, other than being the primary
actor and the trigger. We don't need to implement either "what the
system is" or "what the system does" for this thing. This object is
simply the triggerer (if that is a word).

The BASKET is already part of "what the system is". Does it need
behaviour specific to this use case? No, it can already do things
like "empty the basket".

The PRINTER - this isn't part of "what the system is". It is
hardware, and so it is definitely an actor. It is part of what the
system does. It is a role! While actually printing might be some low
level API calls, we need to prepare what we actually want to print,
eg. the content of each line. The printer can also update the Till's
paperAvailability field, after printing, since there is an API call to
retrieve the amount of remaining paper.

The PAYMENT PARTNER - this is not part of "what the system is". It is
an external system and so it is definitely an actor. The call to this
system is part of "what the system does", for example if we need to
map our data into a web service call. That kind of code needs to be
built by us, so it is a role!

The SALES LOG RECORDS - these are pure data, that we need to create.
Let's call them just part of "what the system is" for now. The next
paragraph will make it clear why.

The SALES LOG - I don't have any objects for this thing at the
moment. It is a container for SALES LOG RECORDS, but that is just
notional. But it is something that has behaviour, such as "create
sales log records". That behaviour is part of "what the system does",
and is something we need to build. It doesn't appear to be an actor,
because it is not an external system or a person, nor is it the
subject of a different use case. But it's behaviour belongs in a
role. You could argue that it *could* be an external system, so let's
call it a role, and not worry too much.

The SALES ORDER - this and its SALES ORDER ITEMs are data. Part of
"what the system is".

The SALES ORDER DATABASE - this is very similar to the SALES LOG in
terms of it having behaviour and not exactly being an actor. For the
same reasons the SALES LOG is a role, this thing is also a role.

TILL - it is already part of "what the system is". Does it need any
extra behaviour within this use case? No. It is not a role.

So, there you have it, I have easily identified the roles, *from the
words in the use case*. Easy huh? This is exactly what I was trying
to do when I first posted to this thread.

Who is assigned the roles?

The BASKET takes these roles:
PAYMENT PARTNER: because we send them the basket's total amount.
The authorization ID is passed from the role back to the context, and
is context state.
SALES LOG: it creates a sales log record per product in the
basket, and additional records if the product is discounted.
SALES ORDER DATABASE: because it creates the sales order and its
sales order items based on what is in the basket.

The TILL takes these roles:
PRINTER: because it reads and updates the TILL's paper
availability. To print, it is passed the basket.

Almost done. The next question I posed myself, was where do I put the
code which I will program, that is, the code which is the use case's
steps? It doesn't go into the roles, that much I know.

This is the bit I am unsure about. I intend to put it into the
context. My context will assign the roles listed above and then call
the roles as the use case's steps require.

Why am I unsure about this last bit? It has always been said that the
context assigns roles and starts the interaction. Just yesterday,
James wrote "The whole point of a Context is to assign objects to
roles and to START the enactment."

In my example, the context is not only starting the enactment, if IS
the enactment (it contains the code which does the enactment). In the
analogy with a shakespearean play, it is the director. It tells the
actors what to do, when.

So shouldn't the statement be more like "the context assigns roles and
implements the use case steps, with the help of the roles to do work
on the system state or call external systems"?

This might explain one reason the bank transfer example is a little
sucky - because the transfer is made by the source account, rather
than by the context.

//this has always hurt my eyes
source.transferTo(amount, destination);

// this reads so much nicer, don't you think?
source.debit(amount);
destination.credit(amount);

Here is my context for the use case at the top of this post. See how
the code maps 1:1 to the use case steps above (see comments in code)?
Please IGNORE the fact I'm using wrappers - that IS NOT part of this
discussion ;-)

What do you think?

------------------------

//sales context's execution method
public void execute() {

// ***********
// ROLE ASSIGNMENT
// ***********
SalesOrderDatabase salesOrderDatabase = new
SalesOrderDatabaseImpl(basket);
SalesLog salesLog = new SalesLogImpl(basket);
Printer printer = new PrinterImpl(till);
PaymentPartner paymentPartner = new PaymentPartnerImpl(basket);

// ***********
// USE CASE STEPS
// ***********
if(till.getBasket().isEmpty()){ // STEP 1
till.getErrorInformation().setError("Nothing to sell!");
return;
}else{
if(!printer.hasEnoughPaper()){ // STEP 2
till.getErrorInformation().setError("Not enough paper!");
return;
}else{
String authID = null;
if(PaymentType.electronic.equals(till.getPaymentType())){ // STEP
3
authID = paymentPartner.getEPaymentAuthID(); // STEP 3.1
if(authID == null){
// STEP 3.2
till.getErrorInformation().setError("E-payment failed. See card
reader.");
return;
}
}

SalesOrder so = salesOrderDatabase.createSalesOrder(authID); //
STEP 4
salesLog.createRecords(authID, so.getSalesRef().toString(),
till.getPaymentType(), so.getTimestamp()); // STEP 5
printer.printReceipt(authID, so.getSalesRef(), basket); // STEP 6
updateTillsBalance(); // STEP 7
till.reset(); // STEP 8

log.info("Sale completed.");
}
}

}

private void updateTillsBalance() {
//till cash balance adjustment
BigDecimal cashBalance = till.getCashBalance();
if(till.getPaymentType().equals(PaymentType.cash)){
cashBalance =
cashBalance.add(basket.getTotalDiscountedPriceIncludingCustomerDiscount());
}
till.setCashBalance(cashBalance);
}

The role code just does what each role needs to do, like create sales
log records, make a call to the partner, etc. If you want this code,
please ask. I am writing this entire example up anyway, and it should
be ready in a few weeks.

Wenig, Stefan

unread,
Aug 29, 2011, 10:45:50 AM8/29/11
to object-co...@googlegroups.com
> From: James O. Coplien
> Sent: Friday, August 26, 2011 8:58 PM

>
> On Aug 23, 2011, at 1:49 , Wenig, Stefan wrote:
>
> > Actors interact with the system, so what is an actor and what is not
> > depends on your system boundaries. A business use case would include
> > the customer, this system use case does not because the customer only
> > interacts with the employee (an actor), not the system (till).
> >
> > At least that's what I always thought.
> > http://practicalanalyst.com/2008/05/21/quick-tip-to-help-identify-use-
> > case-actors/
>
> Use cases are about collections of possible scenarios between end users
> and a system under construction. That is, a use case is an analysis
> entity that drives towards a business goal (what Cockburn calls a
> goal).
>
> The practicalanalyst article suggests that we include customers.
> Customers are one of the actors. It says: "I've found that it's easy to
> identify the actors that are users of the system." I do think the
> practicalanalyst page departs both from Jacobsson and Cockburn when it
> takes design issues into consideration: that's usually viewed as being
> outside the realm of use case expression or consideration.

I googled around a bit, and it seems that Cockburn favors adding a list of stakeholders to the list of actors. The Wikipedia article calls them Off-stage Actors. All good with me. It just never really occurred to me to pack stakeholder requirements into use case descriptions, but I get the idea.

> The distinction between system and business use cases very rarely adds
> value. It usually adds confusion.

Are you saying there's artifacts in UP that are not strictly necessary for success? I'm shocked ;-)

Aren't you ever concerned that the tool Mafia will be coming after you when traceability is built into the code, and no expensive tools are required to keep track? It's similar to what MDSOC + hyperslices/use case slices/FOSD + mixin slices achieve when you suddenly structure your code base along several dimensions, one of them being the structure of your requirements. Putting an end to scattering and tangling.

http://en.wikipedia.org/wiki/Data,_Context_and_Interaction doesn't list this as an explicit goal of DCI (although #2 comes close). I'd consider including it.

> It relates more closely to
> Jacobsson's use case theory than to anything in practice. We've seen it
> useful only once: in a legal registration system, where the process is
> so large and encompasses so many bank contexts that it was useful to
> characterize business use cases for the big picture view, and system
> use cases for each business within the bank where registration was a
> small part of a larger use case. The latter was useful for developing
> the system. The business use cases really weren't useful for what we
> call Contexts in DCI: they were useful for delineating the what-the-
> system-is part of domain analysis. But to call both of these "use
> cases" just added confusion for all but the use case experts, and it
> would have maybe been better just to use the system use cases, because
> they are what drive the functional implementation.

So you'd just go for system use cases with a little stakeholder sugar on top, so it's comprehensible what purpose they are serving? Makes sense, thanks for the comment.

Stefan

James O. Coplien

unread,
Aug 29, 2011, 12:18:29 PM8/29/11
to object-co...@googlegroups.com

On Aug 29, 2011, at 4:45 , Wenig, Stefan wrote:

> Aren't you ever concerned that the tool Mafia will be coming after you when traceability is built into the code,

Yeah, promises, promises. Idiots have been promising traceability, artificial intelligence and world peace for years. You can rarely prove it possible in particular and can always prove it to be impossible in general. I'm not holding my breath.

James O. Coplien

unread,
Aug 29, 2011, 12:19:56 PM8/29/11
to object-co...@googlegroups.com

On Aug 29, 2011, at 4:45 , Wenig, Stefan wrote:

> Putting an end to scattering and tangling.
>
> http://en.wikipedia.org/wiki/Data,_Context_and_Interaction doesn't list this as an explicit goal of DCI (although #2 comes close). I'd consider including it.


Good thought. Please put it in the comments section on Wikipedia so we don't lose it. (Hmmm, that's kind of a recursive application of this notion...)

Ant Kutschera

unread,
Aug 30, 2011, 7:24:50 AM8/30/11
to object-composition
Hi all, I know this post was really long, but I really was hoping
someone would comment on this question:

> So shouldn't the statement be more like "the context assigns roles and
> implements the use case steps, with the help of the roles to do work
> on the system state or call external systems"?

See the code from the posting (also below) which demonstrates
concretely what I mean.

Thanks,
Ant

Ant Kutschera

unread,
Sep 2, 2011, 4:05:10 AM9/2/11
to object-composition
I think James has answered this question in the post about Dijkstra's
algorithm.

http://groups.google.com/group/object-composition/msg/32ab037625b9acb2?

His context contains more code than just assigning roles and starting
interactions (see the execute method). While it doesn't contain a
huge amount more, there is definitely code unrelated to these two
functions.

So I guess a context is also there, to contain use case steps, if
required. The statement ""The whole point of a Context is to ASSIGN
objects to
roles and to START the enactment." is incomplete, and should also
state that the context can contain other code related to the use case.

Ant
> ...
>
> read more »

James O. Coplien

unread,
Sep 2, 2011, 4:24:34 AM9/2/11
to object-co...@googlegroups.com
Maybe. Mea culpa. I was considering moving some of this code into "execute," but it seemed logically better to fit in the constructor. It's a tension around initialization — most of the logic you refer to is the setting of tentative_distance to infinity in all the nodes, setting up the visited bit vector, and taking the origin_node into account as a special case. While end users think of these things as being part of the use case (indeed, you find it there in Wiki) programmers think of them as being part of the constructor. I can't fit both mental models and, since this is code, I let the programmer win. There are good reasons to let the programmer win: in C++, you can't make exceptions (yuk) work right if you put these initializations in member functions: only if they are in the constructor.

But try refactoring it out of the constructor, into execute — it shouldn't be a big problem.

Ant Kutschera

unread,
Sep 2, 2011, 5:11:11 AM9/2/11
to object-composition
My point that it wasn't in any role methods. i.e. the context is
assigning roles, and doing a lot more than just "starting the
interaction".
> ...
>
> read more »

James O. Coplien

unread,
Sep 2, 2011, 6:02:18 AM9/2/11
to object-co...@googlegroups.com

On Sep 2, 2011, at 11:11 , Ant Kutschera wrote:

> My point that it wasn't in any role methods. i.e. the context is
> assigning roles,

that's its job.


> and doing a lot more than just "starting the
> interaction".


Yes, such as the initializations. Anything else?

Ant Kutschera

unread,
Sep 2, 2011, 2:06:58 PM9/2/11
to object-composition
It's calculating tentative distances of unvisited neighbours, and
checking if the calculation is complete:

# Calculate tentative distances of unvisited
neighbors
unvisited_neighbors =
current.unvisited_neighbors
if unvisited_neighbors != nil
unvisited_neighbors.each { |neighbor|
if
neighbor.relable_node_as(current.tentative_distance +
map.distance_between(current, neighbor))
pathTo[neighbor] =
current
end
}
end

unvisited.delete(current)

# Are we done?
if unvisited.size == 0
save_path(@path)
else
# The next current node is the one
with the least distance in the
# unvisited set
selection =
nearest_unvisited_node_to_target

# Recur
CalculateShortestPath.new(selection,
destination, map, path, unvisited, pathTo)
end

That isn't role assignment. And that's not *starting the interaction*
or doing "initialisations*. But it's in the context.

James O. Coplien

unread,
Sep 2, 2011, 5:32:34 PM9/2/11
to object-co...@googlegroups.com
Well, er, yeah, that's the "execute" method, which is where most of the use case logic should end up.

And the question / issue is .... ?

Ant Kutschera

unread,
Sep 2, 2011, 6:41:46 PM9/2/11
to object-composition
On Sep 2, 11:32 pm, "James O. Coplien" <jcopl...@gmail.com> wrote:
> Well, er, yeah, that's the "execute" method, which is where most of the use case logic should end up.
>
> And the question / issue is .... ?

Well, I guess there isn't a question! But you never confirmed or
denied whether the code I supplied in this thread (the till example)
was ok.

And "that's the execute method which is where most of the use case
logic should end up" does not IMHO match very well with "assign roles
and *start the interaction*".

I'm just saying, I think rather than "assign roles and *start the
interaction*", the context should "assign roles, and use those objects
to implement the use case steps".

Maybe only a minor point in the definition of a context, but I feel
it's quite important. If you say the context only "assigns roles and
starts the interaction", then there is an implication that all the use
case logic needs to fit into roles. "starting the interaction" to me
at least, sounds like a simple method call to one of the roles, and no
more.

When you do the full analysis of some requirements, and start off by
writing the use case and then trying to identify roles, and then work
out where each part of the code belongs (in which role, or in the
context), it makes it difficult, if you are restricted to "only
*starting the interaction*" in the context.


So think of the bank transfer example... The transfer of money is
split between two roles, namely the source and destination accounts.
People on this forum always say you'd have this in the context:

BankAccount mine = ...;
BankAccount yours = ...;

//ASSIGN ROLES:
SourceAccount source = mine assign SourceAccount;
DestinationAccount destination = yours assign SourceAccount;

//START INTERACTION:
source.transferTo(amount, destination);

See that last line of code. That is "starting the interaction".

In actual fact, let's start by analysing the use case:

1. transfer money out of source account
1.1 check use has rights
1.2 check account has runds
1.3 reduce the balance
1.4 write accounting records
2. transfer money into destination account
2.1 increase balance of destination account by the amount
2.2 write accounting records

That, in my mental model, leads to different code:

BankAccount mine = ...;
BankAccount yours = ...;

//assign roles:
SourceAccount source = mine assign SourceAccount;
DestinationAccount destination = yours assign SourceAccount;

//do the use case with the help of actors playing roles:
source.transferTo(amount, destination); //step 1
destination.transferFrom(amount, source); //step 2

See there are now two lines of code!

Steps 1 and 2 are in the use case (context).

Steps 1.1-1.4 and 2.1-2.2 are in the roles.

It's about getting the code to read like the use case.

If the context can only "start the interaction", then I can't write
lots of code in the context, for all the steps in the use case.

In the bank transfer example, there might only be two lines of code in
the use case which fit into the context. In my Till/Complete Sale
example, there are 8 steps, and a few if statements, none of which
belong in roles, all of which belong in the context. Or at least
that's what I think.

I just wanted you to look at the code I posted a few days ago, in this
thread, and confirm it was OK to put lots of code in the context.

James O. Coplien

unread,
Sep 3, 2011, 5:17:06 AM9/3/11
to object-co...@googlegroups.com

On Sep 3, 2011, at 12:41 , Ant Kutschera wrote:

> And "that's the execute method which is where most of the use case
> logic should end up" does not IMHO match very well with "assign roles
> and *start the interaction*".


It is a contextual question — literally. From an architectural perspective the Roles are part of the Context, and therefore the use case logic is encapsulated in the Context.

From a low-level coding perspective there is a Context class and there are the roles within it. The Context class itself is mainly boilerplate to just kick off the interaction, while the Roles carry out the work.

So it's purely a question of English semantics as to whether you consider the Context as being the instance doing the work — a matter of scope and perspective of the conversation.

rune funch

unread,
Sep 3, 2011, 5:19:59 AM9/3/11
to object-co...@googlegroups.com
Who said there was such a things as a class Jim? :)

2011/9/3 James O. Coplien <jcop...@gmail.com>

James O. Coplien

unread,
Sep 3, 2011, 5:22:23 AM9/3/11
to object-co...@googlegroups.com

On Sep 3, 2011, at 11:19 , rune funch wrote:

Who said there was such a things as a class Jim? :)


It is the locus of source code for the corresponding object. Nothing profound here. There ARE classes in DCI.

Ant Kutschera

unread,
Sep 4, 2011, 9:48:20 AM9/4/11
to object-composition
OK, sounds good.

Ant Kutschera

unread,
Sep 9, 2011, 4:47:03 AM9/9/11
to object-composition
Hi all,

I wondered what people though of the following statements?

---

Collaborations are generally used to explain how a collection of
cooperating instances achieve a joint task or set of tasks.
Therefore, a collaboration typically incorporates only those aspects
that are necessary for its explanation and suppresses everything else.
Thus, a given object may be simultaneously playing roles in multiple
different collaborations, but each collaboration would only represent
those aspects of that object that are relevant to its purpose.

A collaboration defines a set of cooperating participants that are
needed for a given task. The roles of a collaboration will be played
by instances when interacting with each other. Their relationships
relevant for the given task are shown as connectors between the roles.
Roles of collaborations define a usage of instances, while the
classifiers typing these roles specify all required properties of
these instances. Thus, a collaboration specifies what properties
instances must have to be able to participate in the collaboration. A
role specifies (through its type) the required set of features a
participating instance must have. The connectors between the roles
specify what communication paths must exist between the participating
instances.

Neither all features nor all contents of the participating instances
nor all links between these instances are always required in a
particular collaboration. Therefore, a collaboration is often defined
in terms of roles typed by interfaces. An interface is a description
of a set of properties (externally observable features) required or
provided by an instance. An interface can be viewed as a projection of
the externally observable features of a classifier realizing the
interface. Instances of different classifiers can play a role defined
by a given interface, as long as these classifiers realize the
interface (i.e., have all the required properties). Several interfaces
may be realized by the same classifier, even in the same context, but
their features may be different subsets of the features of the
realizing classifier.

Collaborations may be specialized from other collaborations. If a role
is extended in the specialization, the type of a role in the
specialized collaboration must conform to the type of the role in the
general collaboration. The specialization of the types of the roles
does not imply corresponding specialization of the classifiers that
realize those roles. It is sufficient that they conform to the
constraints defined by those roles.

A collaboration may be attached to an operation or a classifier
through a CollaborationUse. A collaboration used in this way describes
how this operation or this classifier is realized by a set of
cooperating instances. The connectors defined within the collaboration
specify links between the instances when they perform the behavior
specified in the classifier.

The collaboration specifies the context in which behavior is
performed. Such a collaboration may constrain the set of valid
interactions that may occur between the instances that are connected
by a link.

A collaboration is not directly instantiable. Instead, the cooperation
defined by the collaboration comes about as a consequence of the
actual cooperation between the instances that play the roles defined
in the collaboration (the collaboration is a selective view of that
situation).

david Rozenberg

unread,
Sep 9, 2011, 12:01:06 PM9/9/11
to object-co...@googlegroups.com
Not sure there was any need to re-define collaborations. Please check the old (1997) and still great article by 'Uncle Bob': www.objectmentor.com/resources/articles/umlCollaborationDiagrams.pdf
 
Cheers,
David

--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To post to this group, send email to object-co...@googlegroups.com.
To unsubscribe from this group, send email to object-composition+unsub...@googlegroups.com.

Ant Kutschera

unread,
Sep 9, 2011, 4:12:51 PM9/9/11
to object-composition
On Sep 9, 6:01 pm, david Rozenberg <dr_20022...@yahoo.com> wrote:
> Not sure there was any need to re-define collaborations. Please check the old (1997) and still great article by 'Uncle Bob':www.objectmentor.com/resources/articles/umlCollaborationDiagrams.pdf

Ah, but *I* didn't re-define collaborations. Those are not my
statements :-)

Mr. Martin's article doesn't contain the word *role* or *behaviour*,
nor does it so elegantly describe what we do in DCI. For example,
those statements elegantly describe that in a collaboration, we only
look at the details of objects which interest us about the particular
collaboration. In DCI we do this by taking behaviour out of objects
and put it into the context (within roles).

I copied those statements from page 169 of the UML Superstructure
Specification, v2.1.2. They are in the chapter about composite
structures, and are the semantics of a collaboration. A DCI Context
is a composite struture, from the point of view that it and its roles
are a component containing collaborations (interactions), i.e. a
structure composed of roles.

I had difficulty identifying roles from use cases, because the
components internal to my system which were supposed to be roles, were
not drawn on the use case diagrams as actors (because they were not
external systems or people).

But if I look at the collaborations that go on inside a use case, and
draw a collaboration-use diagram, I not only easily extract the roles,
but I also get their interfaces too! The part in those statements
which talks about only viewing the relevant parts of objects using
interfaces, is exactly the "narrowing" which I described in the cheat
sheet I created last year (www.maxant.co.uk/whitepapers.jsp)

Using collaborations from a composite structure / collaboration-use
diagram, is a much easier way to identify roles, than searching for
non-existant or ambiguous actors in use cases diagrams. If I take any
use case, no matter how badly written (within reason), and start
drawing collaboration diagrams and ensure they align with the single
mental model of the system, by showing the diagrams around to all
stakeholders, then everything I need in order to create a DCI design
is jumping off the page at me :-)

This also helps the discussion we had a year ago, as to whether DCI
was relevant for use cases, or also relevant to lower level algorithms
too. If the context is the collaboration, well life is easy! It can
be high level, it can be low level.

The only discrepancy between the UML Super Structure, and DCI, is this
line: "A collaboration is not directly instantiable". If, as I
propose here, a DCI Context is a Collaboration, then this does not fit
100% with UML, because a DCI Context is indeed instantiable. But hey,
we can't expect those UML guys to get it all right ;-)

Cheers,
Ant

Trygve Reenskaug

unread,
Sep 10, 2011, 7:14:53 AM9/10/11
to object-co...@googlegroups.com
A word of warning: Don't read about Collaborations in books and articles that are based on UML 1.x. if you want to understand the DCI Context.  'Uncle Bob':s article is but one example that is less than helpful.

The story is as follows. I was member of the
UML 1.1 core team. My contribution was OOram role modeling and there were two of us that wrote the first draft for the standard. (I regret that I cannot remember the name of my colleague. He was a member of Bran Selic's team at Object Time Ltd., Canada). The powers that be didn't like our draft and we were taken off the project and new authors were selected. The result was a construct called 'CassifierRole'. This was class oriented thinking at its worst because the role was a classifier.  So UML 1.x is OK if you think of a role as an object. It is very misleading if you think of a role as a reference to an object.

In OOram, the role is a description of an object as seen from its collaborators. UML 2.x got it right. Their innovation was to let the role be an instance variable in a Collaboration class. An instance variable isn't a class; it is a reference to an object. (at least in Ruby and Smalltalk).

Look at http://www.omg.org/spec/UML/2.3/Infrastructure/PDF/ page 167 where you will find:
" Collaborations
Objects in a system typically cooperate with each other to produce the behavior of a system. The behavior is the
functionality that the system is required to implement.
A behavior of a collaboration will eventually be exhibited by a set of cooperating instances (specified by classifiers) that
communicate with each other by sending signals or invoking operations. However, to understand the mechanisms used in
a design, it may be important to describe only those aspects of these classifiers and their interactions that are involved in
accomplishing a task or a related set of tasks, projected from these classifiers. Collaborations allow us to describe only
the relevant aspects of the cooperation of a set of instances by identifying the specific roles that the instances will play.
Interfaces allow the externally observable properties of an instance to be specified without determining the classifier that
will eventually be used to specify this instance. Consequentially, the roles in a collaboration will often be typed by
interfaces and will then prescribe properties that the participating instances must exhibit, but will not determine what class
will specify the participating instances."

This has a strong taste of the DCI Context. (Also see the description of the Collaboration metaclass on page 174.)
I hope this can help clarify a wide spread misunderstanding. The UML 1.x Collaboration  is fundamentally different the DCI Context and the UML 2.x  Collaboration.

Cheers
--Trygve

To unsubscribe from this group, send email to object-composit...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/object-composition?hl=en.

--

Trygve Reenskaug       mailto: try...@ifi.uio.no

Morgedalsvn. 5A         http://folk.uio.no/trygver/

N-0378 Oslo               Tel: (+47) 22 49 57 27

Norway

James O. Coplien

unread,
Sep 12, 2011, 9:10:41 PM9/12/11
to object-co...@googlegroups.com

On Sep 9, 2011, at 1:47 , Ant Kutschera wrote:

Neither all features nor all contents of the participating instances
nor all links between these instances are always required in a
particular collaboration. Therefore, a collaboration is often defined
in terms of roles typed by interfaces. An interface is a description
of a set of properties (externally observable features) required or
provided by an instance. An interface can be viewed as a projection of
the externally observable features of a classifier realizing the
interface. Instances of different classifiers can play a role defined
by a given interface, as long as these classifiers realize the
interface (i.e., have all the required properties). Several interfaces
may be realized by the same classifier, even in the same context, but
their features may be different subsets of the features of the
realizing classifier.


I got lost here. There are no classifiers in DCI, and I'm not sure why one would need one. Also, I don't understand the need to introduce a concept called an interface, or of roles typed by interfaces. It seems unnecessarily to introduce a new concept called interface that maps one-to-one onto roles.

Ant Kutschera

unread,
Sep 13, 2011, 9:36:57 AM9/13/11
to object-composition
Maybe. Depends on the implementation. You can do DCI in ruby and you
don't need any of this. You can do it in Java with my
BehaviourInjector, and it uses interfaces.

I guess the important thing for me, is that it is much easier to find
roles on a collaboration diagram, than in a use case diagram. That is
what I was all excited about.

Trygve Reenskaug

unread,
Sep 13, 2011, 10:15:15 AM9/13/11
to object-co...@googlegroups.com


On 2011.09.13 15:36, Ant Kutschera wrote:
Maybe.  Depends on the implementation.  You can do DCI in ruby and you
don't need any of this.  You can do it in Java with my
BehaviourInjector, and it uses interfaces.

I guess the important thing for me, is that it is much easier to find
roles on a collaboration diagram, than in a use case diagram.  That is
what I was all excited about.
I agree. The UML collaboration diagram is best for finding the roles. It is very similar to the BabyIDE Interaction diagram and also the old OOram role modeling diagram. A difference is that my connectors are directed.  I now also consider extending my role symbols with role player interface specification as shown in UML figure 9.12. It might also be useful to pick something from the Composite structure diagram in UML section 9.4.

Perhaps a use case diagram observes a Context from its outside, while an interaction (collaboration) diagram observes the context from its inside.

Food for thought about a DCI language and IDE here.

--Trygve


Ant Kutschera

unread,
Sep 19, 2011, 3:05:03 PM9/19/11
to object-composition
Hi all,

So, I have identified roles. Now I have the problem of identifying
the role players...

I have two objects: a till and a basket.

The till has these attributes:

BigDecimal cashBalance;
ErrorInformation errorInfo = new ErrorInformation();
boolean showHelp = false;
String tillNumber;
List<Product> searchResults;
String status;
double paperAvailability;

The basket has these attributes:

PaymentType paymentType = PaymentType.cash;
List<Product> productsInBasket;
Customer customer;

Now, in a collaboration for a use case named "Complete Sale", I have
identified a roles called Printer.

That role needs access to these attributes (because of the
requirements for a receipt):

Till#tillNumber

Basket#paymentType
Basket#productsInBasket
Basket#customer

It seems almost obvious, that the Printer role should be played by the
basket, because the basket contains the most attributes which the
printer role needs. The Till, or even just the till number can be
passed as a parameter to the role method "printReceipt".

But, what about cases, where it is not so obvious which object should
play the role. For example, imagine a "Screen" role - like an MVC
View - which draws the screen. That might need lots of attributes
from both the basket and the till.

Are there any rules which help one decide which objects play roles in
ambiguous cases? Or is it designers choice? Does the rule "the
object containing the most data which the role needs is the object
which should play the role" make sense, or is it a dumb rule?

Thanks,
Ant

Ant Kutschera

unread,
Sep 19, 2011, 3:10:48 PM9/19/11
to object-composition
Reply all
Reply to author
Forward
0 new messages