Commands and queries in contexts?

16 views
Skip to first unread message

Rickard Öberg

unread,
Oct 7, 2011, 12:22:58 AM10/7/11
to dci-ev...@googlegroups.com
Hi,

I'm writing a sample app in Qi4j using DCI, and the whole thing is to be
exposed as a REST API in the end. Writing commands as interactions is
pretty straightforward, but what I'm wondering now is whether to include
the view methods in the context as well.

The app is a basic webforum-type thing (Forum->Board->Topic->Post domain
model). When I view a Board I should be able to create a topic, for
example. But for viewing it, I need to expose state that can be used to
either just view it, or make a decision to create a new topic.

What is the general feeling for how to do this best? Should methods for
doing that be included in the context, or should that type of code be
put directly into the REST layer on top of it?

My personal take is that if a context is to model a use case, then
queries are a big part of that. A user should always do a view request
first to get the current state, then make a decision on what to do, and
then do it. But I haven't seen any examples thus far (or maybe I just
missed it) where contexts expose methods for doing such queries.

What are your thoughts on it?

/Rickard

ant.ku...@gmail.com

unread,
Oct 7, 2011, 12:41:48 AM10/7/11
to dci-ev...@googlegroups.com
You mean should a context have just one execute method, or is it allowed to have many?  Having many is interesting because individual roles can be used in more than a single event.  If a context just models a simple interaction (collaboration) within a use case, you run into the problem of how to use a specific role in more than one such context.

Rickard Öberg

unread,
Oct 7, 2011, 12:45:57 AM10/7/11
to dci-ev...@googlegroups.com
On 10/7/11 12:41 , ant.ku...@gmail.com wrote:
> You mean should a context have just one execute method, or is it allowed
> to have many? Having many is interesting because individual roles can be
> used in more than a single event. If a context just models a simple
> interaction (collaboration) within a use case, you run into the problem
> of how to use a specific role in more than one such context.

Oh, I definitely have more than just an execute method. I have as many
methods as I have interactions within that context, but up until now
they have mostly been for executing commands that change state. What I'm
wondering now is whether to include view-type methods as well, because
from a use case point of view that is definitely needed. I.e. "given
this selection of objects, show me a view for it so I can make
decisions, and then act on those decisions".

Technically I could have one context for returning the view, and then
another for executing the commands, but it seems unnecessary, and was
wondering how others have solved this, and whether it is fundamentally
right or wrong to do it like this.

/Rickard

ant.ku...@gmail.com

unread,
Oct 7, 2011, 1:27:12 AM10/7/11
to dci-ev...@googlegroups.com
If it returns the name of the view (eg a jsp page) no problem, but it shouldn't return the actual view (html).



----- Reply message -----
From: "Rickard Öberg" <rickar...@gmail.com>
To: <dci-ev...@googlegroups.com>
Subject: Commands and queries in contexts?

Rickard Öberg

unread,
Oct 7, 2011, 1:30:01 AM10/7/11
to dci-ev...@googlegroups.com
On 10/7/11 13:27 , ant.ku...@gmail.com wrote:
> If it returns the name of the view (eg a jsp page) no problem, but it
> shouldn't return the actual view (html).

No no, nothing like that. I'm talking about returning the data needed
for the view. If that is rendered as JSON, XML or HTML is up to the
actual View to decided, in my case the REST API.

/Rickard

ant.ku...@gmail.com

unread,
Oct 7, 2011, 1:40:05 AM10/7/11
to dci-ev...@googlegroups.com
Then I'd say that's ok.  Not 110% sure what you mean.  Got any code?




----- Reply message -----
From: "Rickard Öberg" <rickar...@gmail.com>
To: <dci-ev...@googlegroups.com>
Subject: Commands and queries in contexts?

Rickard Öberg

unread,
Oct 7, 2011, 1:45:53 AM10/7/11
to dci-ev...@googlegroups.com
On 10/7/11 13:40 , ant.ku...@gmail.com wrote:
> Then I'd say that's ok. Not 110% sure what you mean. Got any code?

Sure, here's an example. When viewing a Post on a Board in the Forum, it
must be possible to reply() to it. But first step is to view the post:
public class ViewPostContext
implements IndexContext<Post>
{
ViewPost viewPost = new ViewPost();
ReplyTopic replyTopic = new ReplyTopic();
Poster poster = new Poster();

public ViewPostContext bind( @Uses Topic topic, @Uses Post post,
@Uses User user )
{
viewPost.bind( post );
replyTopic.bind( topic );
poster.bind( user );
return this;
}

@Override
public Post index()
{
return viewPost.self();
}

public Post reply( String message )
{
return replyTopic.reply( message, viewPost );
}

class ReplyTopic
extends Role<Topic>
{
@Structure
Module module;

public Post reply( String message, ViewPost viewPost )
{
Post post = module.currentUnitOfWork().newEntity( Post.class );
post.message().set( message );
post.createdBy().set( poster.self() );
post.createdOn().set( new Date(
module.currentUnitOfWork().currentTime() ) );
post.replyTo().set( viewPost.self() );

self().lastPost().set( post );
Numbers.add( self().postCount(), 1);

return post;
}
}

class ViewPost
extends Role<Post>
{
}

class Poster
extends Role<User>
{
}
}
---
I'm using the wrapper approach, as a test of what happens, but the main
question right now is whether the index() method should be included or
not. I *could* put this straight into the REST API on top of this
context, but that makes it harder to reuse this context in testing,
where the test would call index() to get the Post, make some decision,
and then reply() to the Post.

/Rickard

ant.ku...@gmail.com

unread,
Oct 7, 2011, 3:02:39 AM10/7/11
to dci-ev...@googlegroups.com
Why is view post a role?  It has no methods.

Other question: is the context instantiated one time for each call to index() and reply()?

And "index" is a weird name to give a method which shows a post.




----- Reply message -----
From: "Rickard Öberg" <rickar...@gmail.com>
To: <dci-ev...@googlegroups.com>
Subject: Commands and queries in contexts?

Rickard Öberg

unread,
Oct 7, 2011, 3:38:24 AM10/7/11
to dci-ev...@googlegroups.com
On 10/7/11 15:02 , ant.ku...@gmail.com wrote:
> Why is view post a role? It has no methods.

I did it that way so that after bind() there are no other references to
the original data objects. There might be methods added later also,
depending on what interactions I add.

> Other question: is the context instantiated one time for each call to
> index() and reply()?

Since it's a REST API, for each request.

> And "index" is a weird name to give a method which shows a post.

That comes from this being used mainly to back a REST API, i.e. it maps
to "index.html" or "index.json".

/Rickard

ant.ku...@gmail.com

unread,
Oct 7, 2011, 3:46:42 AM10/7/11
to dci-ev...@googlegroups.com
I think I can live with index in the context.  Sighing the use case, you view (index) and reply to posts.

I don't think every object has to be forced to play a role, if the role has no extra behaviour.  Give the identifier a suitable name and pretend its in a role.  No need to make the programmer write more code.

Ant




----- Reply message -----
From: "Rickard Öberg" <rickar...@gmail.com>
To: <dci-ev...@googlegroups.com>
Subject: Commands and queries in contexts?

Marc Grue

unread,
Oct 7, 2011, 4:20:32 AM10/7/11
to dci-ev...@googlegroups.com
On 2011-10-07, at 06.22, Rickard Öberg wrote:
I'm writing a sample app in Qi4j using DCI, and the whole thing is to be exposed as a REST API in the end. Writing commands as interactions is pretty straightforward, but what I'm wondering now is whether to include the view methods in the context as well.

Since the query in itself doesn't include any logic I found that it was natural to have a query package within what I call a "Communication" layer - the layer that communicates with the user (probably similar to your REST API or a "Controller" layer) where I would have "Query objects" that retrive whatever data the view wants. Queries can change with the needs of the views and shouldn't have an impact on the Context layer (and thus not used for testing the Contexts either).

I found it interesting to see that queries mapped to steps in "User-Goal" use cases (see Cockburn pp 61) and commands to steps in "Subfunction" use cases! So we end up having two levels:

1. User-Goal use cases -> View/Controller/Communication/REST layer -> Queries
2. Subfunction use case -> Context layer -> Commands

Let's how a user-goal use case could look like:

===========================================================================
USE CASE: Participate in discussion [user-goal]

Forum Participant participates in a forum discussion.

Primary actor.. Participant
Scope.......... Forum
Preconditions.. Board has Topics
Trigger........ Participant enters Board on Forum.

Main Success Scenario
---------------------------------------------------------------------------
1. Board presents list of Topics to Participant.
2. Participant selects a Topics.
3. Board presents Topic Posts to Participant.
4. Participant chooses to reply to Post.
5. Board offers Participant to write a Reply.
6. Participant write and submits Reply.
7. Board asks Post to <registers Reply>.
===========================================================================

Then we could see three categories of actions:
- Communication/View/REST-API layer action (query): step 1, 3, 5
- User action: step 2, 4, 6
- Context layer action (command): step 7

Step 1-6 takes place in the communication layer with queries and doesn't involve state change. Step 7 activates the Context layer with a command that will change state. The command is represented by a subfunction use case that could serve as a template for the interactions in the context: 

===========================================================================
USE CASE: Register reply [subfunction]

Board registers a Reply to a Post.

Primary actor.. Post ?
Scope.......... Topic ?
Preconditions.. ?
Trigger........ Participant submits Reply to a Post.

Main Success Scenario
---------------------------------------------------------------------------
1. Post receives Reply.
2. Post verifies that Participant is authorized to reply.
3. Post verifies that ... etc ...
4. Post saves reply data in system.
===========================================================================

Does this make sense? (see also http://marcgrue.com/dci/dci-sample/use-cases where I talk about this too).

The names (beginning with capital letter) in the use cases gives clues to the Role names ;-)

Cheers,
Marc

James O. Coplien

unread,
Oct 7, 2011, 4:27:03 AM10/7/11
to dci-ev...@googlegroups.com
I view a Context as a use case. A use case is a collection of related scenarios. I can see having an execute method for each scenario (i.e., for each use case deviation).

There is likely some good research to be done here that ties together MVC and DCI in a way that maps Controller gestures onto Context scenarios. The Controller's job is to identify (parse) the gesture; the Context's job is to orchestrate its execution.

James O. Coplien

unread,
Oct 7, 2011, 4:39:44 AM10/7/11
to dci-ev...@googlegroups.com

On Oct 7, 2011, at 10:20 , Marc Grue wrote:

Since the query in itself doesn't include any logic I found that it was natural to have a query package within what I call a "Communication" layer - the layer that communicates with the user (probably similar to your REST API or a "Controller" layer) where I would have "Query objects" that retrive whatever data the view wants. Queries can change with the needs of the views and shouldn't have an impact on the Context layer (and thus not used for testing the Contexts either).


I am scratching my head.

In an OO world, the Controller and View *together* "talk" to the user. These environments are not layered per se: they are flat from one perspective and fractal from another. Controllers are not a layer.

Query objects don't seem to be part of any user mental model, and that to me suggests that they should be relegated to more detailed implementation than bears discussion at the same level as Controllers or DCI building blocks.

I had the same discomfort about the DDD Sample application. It looks like DDD but I'm still struggling to see the DCI in it.

Marc Grue

unread,
Oct 7, 2011, 4:45:53 AM10/7/11
to dci-ev...@googlegroups.com
A lot to catch up on, but I'm busy the rest of the day :-( 

Sent from my iPhone

Rickard Öberg

unread,
Oct 7, 2011, 4:52:14 AM10/7/11
to dci-ev...@googlegroups.com
On 10/7/11 16:20 , Marc Grue wrote:
> Since the query in itself doesn't include any logic I found that it was
> natural to have a query package within what I call a "Communication"
> layer - the layer that communicates with the user (probably similar to
> your REST API or a "Controller" layer) where I would have "Query
> objects" that retrive whatever data the view wants. Queries can change
> with the needs of the views and shouldn't have an impact on the Context
> layer (and thus not used for testing the Contexts either).

Right, so in my case I would just have the REST resource classes get
whatever they need, without having to go through a context. Sometimes
that makes sense, especially with the simple cases. Sometimes the query
*does* involve quite a bit of domain-related logic however, and for
those cases I suppose it would make sense to put it in the context, as
the context bindings are actually required to make a decision on what to
return.

> I found it interesting to see that queries mapped to steps in
> "User-Goal" use cases (see Cockburn pp 61) and commands to steps in
> "Subfunction" use cases! So we end up having two levels:

<snip>


> Does this make sense? (see also
> http://marcgrue.com/dci/dci-sample/use-cases where I talk about this too).

I think it makes sense... still struggling with all this, trying to
figure out what it turns out to in actual code.

/Rickard

Risto Välimäki

unread,
Oct 7, 2011, 4:59:33 AM10/7/11
to dci-ev...@googlegroups.com


2011/10/7 James O. Coplien <jcop...@gmail.com>


On Oct 7, 2011, at 10:20 , Marc Grue wrote:

Since the query in itself doesn't include any logic I found that it was natural to have a query package within what I call a "Communication" layer - the layer that communicates with the user (probably similar to your REST API or a "Controller" layer) where I would have "Query objects" that retrive whatever data the view wants. Queries can change with the needs of the views and shouldn't have an impact on the Context layer (and thus not used for testing the Contexts either).


I am scratching my head.

In an OO world, the Controller and View *together* "talk" to the user. These environments are not layered per se: they are flat from one perspective and fractal from another. Controllers are not a layer.

To clarify (I hope), I think Marc meant "Controller" as in typical web application. That "web-MVC Controller" has only subtle relation to typical OO MVC Controller. Also it's actually "a layer" that's between user commands (http requests) and the "real thing" (Model or DCI), and Controllers is usually responsive for creating the View back to the user.

-Risto

Risto Välimäki

unread,
Oct 7, 2011, 5:18:00 AM10/7/11
to dci-ev...@googlegroups.com
+1,

Just want to add that I use one execute method for each interactive Use Case step (for the web of course). For example the Money Transfer use case could need following interactive (== requiring new or updated View) steps (and therefore an execute method (for the web)):

1. User selects source, destination & amount and sends confirmation
2. System verifies and executes the transfer and displays result to user

there might also be extension steps (different scenarios) that need their own execute method and View:

2a. insufficient funds, display error

We can see from above, that those steps had many substeps, and UC definition would have been:

1. User selects source account
2. User selects destination account and amount to transfer
3. User confirms
4. System verifies and executes the transfer
5. System displays result to user

For heuristics, I suggest (for web apps) one execution method for every request that is in practise, one execution method for every View.

-Risto

2011/10/7 James O. Coplien <jcop...@gmail.com>
I view a Context as a use case. A use case is a collection of related scenarios. I can see having an execute method for each scenario (i.e., for each use case deviation).

James O. Coplien

unread,
Oct 7, 2011, 5:21:43 AM10/7/11
to dci-ev...@googlegroups.com
Here on the DCI-evolution group, I want to stick to sound concepts and how to evolve them into something powerful. I hope we will not limit them with the poorly conceived architectures of current frameworks.

AFAIK, this post is inspired by the DDD port. The more I look at the DDD port the more I see considerable compromises to DCI principles. I am concerned that people will take that port as being what DCI is. It is not. DCI is not layered. DCI is an architecture in itself rather than a gloss on another architecture. The DDD architecture reflects pretty static thinking; it says a lot about static things but little about objects. The concepts fit the technology rather than mental models, and makes artificial distinctions (e.g. between scope and Context) that seem strange to me. This Controller anomaly is another one of the head-scratchers in that set.

Here, I would rather that we looked at what is lacking in DCI to be able to replace the DDD architecture, rather than how to compromise it to fit the DDD architecture. The latter could be a good topic for object-composition IF the DCI compromises are made explicit.

Let's raise the bar.

Marc Grue

unread,
Oct 7, 2011, 10:43:24 AM10/7/11
to dci-evolution
Reply all
Reply to author
Forward
0 new messages