Micro SOA

322 views
Skip to first unread message

Matthew Browne

unread,
Jun 6, 2013, 8:11:50 PM6/6/13
to object-co...@googlegroups.com
Hi Ant,
I'd like to follow up on your latest post in the "OO Design" thread where you mention your micro SOA approach. I encountered some of your much older posts about this a few weeks ago and would be curious to learn more.

I understand that micro SOA is different from macro SOA in the way it approaches functional decomposition. As you said in an older thread: "Just as SOA goes further than decomposing into subprocedures, DCI goes further decomposing systems into contexts and the roles relevant to those contexts."

But I think that in order for it to be similar to DCI, micro SOA would need to do functional decomposition according to roles, (and use cases at the more macro level of course) and I'm not understanding how the roles would work. I wrote a quick example in Javascript to illustrate this. In Javascript of course we could easily do real DCI for a real-world project, but it's still a good language for demonstration purposes. In the example I'm assuming that in micro SOA services can be stateful, but I realize I might be incorrect about that.

function TransferMoneyService(sourceAcct, destinationAcct, amount) {
    this.transfer = function() {
        subServices.SourceAccount.transferOut(amount);
    };
   
    var subServices = {
       
        SourceAccount: {
            transferOut: function() {
                this.withdraw(amount);
                subServices.DestinationAccount.deposit(amount);
            }
           
         , withdraw: function(amount) {
                sourceAcct.decreaseBalance(amount);
            }
        }
       
     , DestinationAccount: {
            deposit: function(amount) {
                destinationAcct.increaseBalance(amount);
            }         
        }
    };
}


While this does manage to organize the code according to the role boundaries, it ends up being effectively the same as Marc's non-DCI example of using a naming convention instead of DCI, which has limitations and is arguably more awkward.

My example may be very different from what you had in mind, but hopefully it communicates my doubts that micro SOA achieves a similar result as DCI.

Perhaps you cover this in your book...I glanced at it using Amazon preview but I don't need a book on enterprise Scala right now so I was hoping you could elaborate a bit here.

Ant Kutschera

unread,
Jun 7, 2013, 3:42:23 PM6/7/13
to object-co...@googlegroups.com
Hi Matt,


My services tend to be stateless, perhaps 99% of the time.

SOA doesn't consider roles - you are correct there, although see below.  

According to Wikipedia, DCI has these goals:

  • To improve the readability of object-oriented code by giving system behavior first-class status;

Micro SOA does that by placing behaviour into services, which are first class.  

  • To cleanly separate code for rapidly changing system behavior (what the system does) from code for slowly changing domain knowledge (what the system is), instead of combining both in one class interface;

Ditto.

  • To help software developers reason about system-level state and behavior instead of only object state and behavior;

Micro SOA does this too, in that reading the code in services that are higher up in the hierarchy can be similar to reading use cases or user stories.

  • To support an object style of thinking that is close to peoples' mental models, rather than the class style of thinking that overshadowed object thinking early in the history of object-oriented programming languages.

Micro SOA fails here.  Entirely.  Because of the fourth word "object".  But in my experience business users often fail to think about objects anyway and instead simply refer to "the system".    And when they do that, it isn't hard to introduce them to the idea that components of software have responsibility for data and behaviour, and that the they expose services which can be used to access the behaviour and manipulate the data.  It is certainly no harder than teaching them to think in an object oriented way.

If using roles is a goal of DCI, perhaps the article should state that.  Reading it, roles seem to be part of the implementation details.

An interesting case where I have recently encountered a problem that is best suited to a role based solution is when dealing with customer data.  Consider three parts of a landscape, say a Customer Database System (CDS), an Order System (OS) and a Contract System (CS).  Within a use case you might want to create an order for "Ant", but let "Matt" pay for it on a monthly basis via a contract :-)

While you could simply save both customers in the CDS and let the OS and CS contain ID numbers as references to those customers, your business might be mega complex and cause you to consider the role that the customer plays in order to determine where to save their data.  Maybe data protection laws or multi-client capability [1] force the business to create such requirements.  In such a real-world example, you might end up with some customer data stored in the CDS for marketing reasons; other customer attributes stored in the OS (like a delivery address) and yet other attributes saved only in the CS (billing address).  Micro SOA can solve this because the two customers which are captured in the UI are simply mapped into "transfer objects" that are part of the service interface definitions.  The mapping is where the data is "cast" into the different roles.

In my paper referenced above, I show how the planning service (micro SOA) can be used to plan a recipe.  The data from the recipe is playing a different role that it is when it is mapped and passed to the planning service.

So even when it comes to roles, micro SOA supports them.  The implementation is different to DCI though.

Where micro SOA is *very different* to DCI is that DCI has the goal to stay object oriented (full OO).  It took me a long time to realise that! Indeed I was amazed that people still wanted to have OO in this day and age, after all the hard things we have learned about OO which DCI attempts to solve.  

Saying that, I have come to realise (through writing my book) that I too want certain aspects of OO, and my preferred solution is multi-paradigm.  I claimed to use only SOA, whereas I was really combining OO, SOA and AOP.  Scala let me add FP to the mix and it's awesome!  SOA is used for defining components, responsibilities and interfaces; OO is mostly used for inheritance / polymorphism (e.g. template pattern); AOP for transactions and security; FP for data definition (immutability) and manipulating data (monads) / implementing business logic.

Hope that helps you to understand my point of view.

rune funch

unread,
Jun 8, 2013, 2:41:38 AM6/8/13
to object-co...@googlegroups.com
Den 07/06/2013 kl. 21.42 skrev Ant Kutschera <ant.ku...@gmail.com>:

> after all the hard things we have learned about OO

Would that be all the hard things learned about class orientation? and
what would they be?

> OO is mostly used for inheritance / polymorphism (e.g. template pattern);

Those are trades of a type system not of OO. You can have OO without
them and you can have them without OO

Ant Kutschera

unread,
Jun 8, 2013, 3:17:14 AM6/8/13
to object-co...@googlegroups.com


On Saturday, 8 June 2013 08:41:38 UTC+2, Rune wrote:
Den 07/06/2013 kl. 21.42 skrev Ant Kutschera <ant.ku...@gmail.com>:

> after all the hard things we have learned about OO

Would that be all the hard things learned about class orientation? and
what would they be?


Yes class orientation, things like the need to separate behaviour and data ;-)

Matthew Browne

unread,
Jun 8, 2013, 12:08:14 PM6/8/13
to object-co...@googlegroups.com

Hi all,

On Jun 7, 2013 3:42 PM, "Ant Kutschera" <ant.ku...@gmail.com> wrote:

> If using roles is a goal of DCI, perhaps the article should state that.  Reading it, roles seem to be part of the implementation details.

Would the group agree with the following:

Roles are essential to DCI because without them there would be no way to achieve both full OO and separation of data from behavior. Roles could be implemented in different ways but there would need to be some notion of roles or it would not be DCI. Perhaps roles should be emphasized more in the Wikipedia article.
~~~

Ant, I will probably have a couple more comments once I've had a chance to read your paper. Thank you very much for the explanation. I see the parallels better now.

Jörgen Andersson

unread,
Jun 9, 2013, 6:55:02 AM6/9/13
to object-co...@googlegroups.com
Hi Matthew,

I agree. I would even add that without roles, there wouldn't be any focus on the interactions between objects inside the context, hence no "I" in DCI.

/Jörgen


--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To unsubscribe from this group and stop receiving emails from it, send an email to object-composit...@googlegroups.com.
To post to this group, send email to object-co...@googlegroups.com.
Visit this group at http://groups.google.com/group/object-composition?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

James O Coplien

unread,
Jun 9, 2013, 9:05:35 AM6/9/13
to object-co...@googlegroups.com
I took a look at the Wikipedia article and the word "role" appears more than 80 times. I think that's enough. I tried to capitalize all instances of the word for emphasis.

I also found that someone added three long paragraphs on Role-based programming. I am not sure that they are part of the history or if it's just coincidence of naming. I tentatively left the paragraph there but removed the sentence: "By this judgement every DCI design should be directly implementable using a modern role-oriented programming language." It adds no insight, and it's probably not true.

Matthew Browne

unread,
Jun 9, 2013, 12:20:56 PM6/9/13
to object-co...@googlegroups.com
Good points, Jörgen and Jim. As to the Wikipedia article, I wasn't suggesting that Roles be mentioned more often, just that they be more explicitly mentioned as being essential to DCI. However, reading the article again, I am left wondering how Ant got the impression that roles are only an implementation detail...perhaps it was this sentence:
The interaction is implemented as Roles which are played by objects at run time.
(emphasis mine)

But roles are mentioned so often in the article at the conceptual level (and not just as an implementation detail) that I've changed my mind...I don't think anything needs to be added to the article - but of course, feel free to weigh in Ant.

I do have another comment/question about the article, relating to this line:
There is a special Role called self which binds to the object playing the current Role.
I think it might also be worth mentioning the this keyword, explicitly stating that this and self both point to the same object. The difference as far as I understand it is that this self can only access methods of the data object, whereas this can be used for either the data object methods or the role methods (as long as there are no naming conflicts). I think Rune mentioned somewhere that the way self behaves as a keyword is somewhat similar to super (or parent in some languages), in that it's a way to explicitly refer to a method of the same name that might have been "overridden" (in this case by a role method).

I think the distinction between this and self can be a bit confusing (and I may have it wrong myself), and it may be that mentioning this in the article would confuse more than help, but I will think about the potential wording for a small note about this.
--
You received this message because you are subscribed to a topic in the Google Groups "object-composition" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/object-composition/e6K7KhKkdnM/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to object-composit...@googlegroups.com.

Matthew Browne

unread,
Jun 9, 2013, 12:31:04 PM6/9/13
to object-co...@googlegroups.com
Hi Ant,
Your paper was very interesting and helped me to understand SOA better - thank you for the link.

I do think that it gives a bit of an unfair advantage to SOA simply due to the verbosity of your Java DCI library as opposed to some other DCI implementations (speaking generally, not about Java specifically, as I haven't looked at Qi4J so I don't know how it compares).

Also, you don't mention the benefits of true object-orientation that DCI makes possible. I think one of those benefits is what I mentioned in my original post, namely functional decomposition according to role boundaries rather than by service methods. As you mentioned previously, you can represent roles to some extent in SOA but I would argue that it breaks down with certain roles (as in the Transfer Money example; more on this below).

But it's very insightful article which I found quite convincing about the benefits of micro SOA. I think you made a good point here:
The two solutions differ because of the semantics, and as such, it is not recommended that a service solution be modified to use an identical mental model as the DCI solution.
Having said all that, here's my new attempt at a micro-SOA version of the Transfer Money example I posted previously:

/**
 * SERVICE
 */

var TransferMoneyService = {
   
    transfer: function(sourceAcctDTO, destinationAcctDTO, amount) {
        this._withdraw(sourceAcctDTO, amount);
        this._deposit(destinationAcctDTO, amount);
    },
   
    _withdraw: function(acctDTO, amount) {
        acctDTO.decreaseBalance(amount);
    },
   
    _deposit: function(acctDTO, amount) {
        acctDTO.increaseBalance(amount);
    }
};

/**
 * ENVIRONMENT
 */

/**
 * In SOA I imagine it might be an MVC Controller that initially calls the service,
 * so I've called it a Controller here
 */
var TransferMoneyController = {
    transfer: function(sourceAcct, destinationAcct, amount) {
        //convert the data objects to transfer objects
        var srcAcctDTO = mapper.mapFromAccount(sourceAcct);
        var destAcctDTO = mapper.mapFromAccount(sourceAcct);
       
        TransferMoneyService.transfer(srcAcctDTO, destAcctDTO, amount);
       
        //unmap / merge
        mapper.mergeResults(sourceAcct, srcAcctDTO);
        mapper.mergeResults(destinationAcct, destAcctDTO);
    }
}

var mapper = {
    /**
    * In this example, the DTO interface is the same for both the Source and the Destination roles;
    * in most use cases there would be a different DTO for each role
    */
    mapFromAccount: function(account) {
        var accountDTO = {
            _balance: account._balance,
            //In Javascript we can simply copy methods from the data class to the DTO,
            //so we don't need to define a DTO class
            increaseBalance: account.increaseBalance,
            decreaseBalance: account.decreaseBalance
        };
        return accountDTO;
    },
   
    mergeResults: function(account, accountDTO) {
        account._balance = accountDTO._balance;
    }
}

/**
 * DATA CLASSES (NOT SHOWN): Account
 */



I think the above code would make sense for SOA, but of course the functionality is not organized according to roles. If that were desired, it could perhaps be accomplished as follows (similar to my original example):

var TransferMoneyService = {
   
    transfer: function(sourceAcctDTO, destinationAcctDTO, amount) {
        this.subServices.SourceAccount.withdraw(sourceAcctDTO, amount);
        this.subServices.DestinationAccount.withdraw(destinationAcctDTO, amount);
    },

    subServices: {
        SourceAccount: {
            withdraw: function(acctDTO, amount) {
                acctDTO.decreaseBalance(amount);
            }
        },
       
        DestinationAccount:{
            deposit: function(acctDTO, amount) {
                acctDTO.increaseBalance(amount);
            }
        }
    }
};


In your paper, you describe the services as being analogous to roles rather than contexts, which works for the front-loading example, but if that were true in this case it would look something like this:

var TransferMoneyController = {
    transfer: function(sourceAcct, destinationAcct, amount) {
        ...
        TransferMoney_SourceAccountService.withdraw(srcAcctDTO, amount);
        TransferMoney_DestinationAccountService.deposit(dstActDTO, amount);
        ...
    }
}


...which means that the use case behavior is now in the controller rather than in a service, which I think you would probably agree should be avoided (especially for use cases that span multiple controller methods).

Overall I think my first example above (in this post) is the best fit for SOA, but it doesn't represent the roles well. It doesn't make much difference in a simple example like this but I think that in more complex cases, roles can help greatly to keep the system behavior logically organized (without a certain discipline, SOA Services can easily end up being Transaction Scripts, which aren't terrible but we can do better).

It's not that you can't represent roles in SOA but rather that it doesn't lend itself to them as well, and in some cases (like this one) I think they're rather awkward. But of course there are trade-offs with both SOA and DCI and you have certainly shown that micro SOA is similar to DCI in many ways, and that it's an equally viable approach to code organization, just with a different mental model. I in fact intend to try it out on a system I'm working on and seeing how it compares.

Matthew Browne

unread,
Jun 9, 2013, 12:41:49 PM6/9/13
to object-co...@googlegroups.com
There's one other alternative I failed to consider:

var TransferMoney_SourceAccountService = {
    transferOut: function(srcAcctDTO, dstAcctDTO, amount) {
        this.withdraw(srcAcctDTO, amount);
        TransferMoney_DestinationAccountService.deposit(dstAcctDTO, amount);
    },
   
    withdraw: function(srcAcctDTO, amount) {
        srcAcctDTO.decreaseBalance(amount);
    }
};

var TransferMoney_DestinationAccountService = {
    transferIn: function(dstAcctDTO, srcAcctDTO, amount) {
        ...
    },

    deposit: function(dstAcctDTO, amount) {
        dstAcctDTO.increaseBalance(amount);
    }
};



var TransferMoneyController = {
    transfer: function(sourceAcct, destinationAcct, amount) {
        ...
        TransferMoney_SourceAccountService.transferOut(srcAcctDTO, dstAcctDTO, amount);
    }
}


This keeps the use case behavior out of the controller while still allowing the TransferMoneyController to be somewhat analogous to a DCI context. But it would break down in the case where there needs to be interaction code that doesn't logically belong to any one role (which in DCI would go in a context method).

Ant Kutschera

unread,
Jun 9, 2013, 1:56:05 PM6/9/13
to object-co...@googlegroups.com

On Sunday, 9 June 2013 18:31:04 UTC+2, Matthew Browne wrote:
 
In your paper, you describe the services as being analogous to roles rather than contexts

Purely because that is where you put the code.
 
...which means that the use case behavior is now in the controller rather than in a service, which I think you would probably agree should be avoided (especially for use cases that span multiple controller methods).


Due to other reasons, like transaction demarcation and deployment, a controller normally just delegates to services, in micro SOA.
 
Overall I think my first example above (in this post) is the best fit for SOA, but it doesn't represent the roles well. It doesn't make much difference in a simple example like this but I think that in more complex cases, roles can help greatly to keep the system behavior logically organized (without a certain discipline, SOA Services can easily end up being Transaction Scripts, which aren't terrible but we can do better).


Another difference between DCI and SOA is that in SOA you don't tend to consider roles.  You look at responsibilities, and they lead to the decision about where data is stored and manipulated.  Common behaviour tends to be grouped into the same component, and that component has 1..n services as interfaces to it.

To orchestrate the various behaviours that belong to a use case, you create high level services which call the low level services.
 
It's not that you can't represent roles in SOA but rather that it doesn't lend itself to them as well,

I agree.

Ant Kutschera

unread,
Jun 9, 2013, 2:02:48 PM6/9/13
to object-co...@googlegroups.com
On Sunday, 9 June 2013 15:05:35 UTC+2, Cope wrote:
I took a look at the Wikipedia article and the word "role" appears more than 80 times. I think that's enough. I tried to capitalize all instances of the word for emphasis.

If you consider the goals to be requirements, like in software engineering as I did, then if I turned up with a solution that didn't contain roles, but did conform to the four goals, would it be a valid DCI implementation?

Of course, it would be interesting to see a DCI solution without roles, that also supported an object style of thinking...

Matthew Browne

unread,
Jun 9, 2013, 3:04:45 PM6/9/13
to object-co...@googlegroups.com
Thanks Ant, that makes sense. I'm just wondering, which of my examples do you think comes closest to micro SOA as you would approach it?

rune funch

unread,
Jun 9, 2013, 3:16:27 PM6/9/13
to object-co...@googlegroups.com
Den 09/06/2013 kl. 18.20 skrev Matthew Browne <mbro...@gmail.com>:

I think the distinction between this and self can be a bit confusing

They are semantically one and the same. The difference comes from languages not semantics. Ie in Ruby it's self but in curly brackets land it's self. 

And btw what you referred to me explaining was not a difference between self and this (since there are none) but how you can explicitly choose a data method over a role method when using Marvin or maroon :)

Matthew Browne

unread,
Jun 9, 2013, 3:20:57 PM6/9/13
to object-co...@googlegroups.com
Ah ok, thanks for the clarification. That's much less confusing...so in a language where this is the keyword that's used by the language itself, would it be ideal then to not have self at all (since there would be no difference between the two anyway)?

BTW I think you meant "in curly brackets land it's this."

rune funch

unread,
Jun 9, 2013, 3:23:58 PM6/9/13
to object-co...@googlegroups.com
Den 09/06/2013 kl. 20.02 skrev Ant Kutschera <ant.ku...@gmail.com>:

> if I turned up with a solution that didn't contain roles, but did conform to the four goals, would it be a valid DCI implementation?

Interesting how are you planing to represent the graph of
interconnected objects without any representation of the nodes in that
graph?

James O Coplien

unread,
Jun 9, 2013, 4:19:09 PM6/9/13
to object-co...@googlegroups.com

On Jun 9, 2013, at 6:20 , Matthew Browne wrote:

I think it might also be worth mentioning the this keyword, explicitly stating that this and self both point to the same object.

Only in some programming languages. DCI is PL-inspecific. We call the role self. There may be other pointers to the same object, including this. And "points to" is funny. There are no pointers in DCI, though there are names of objects and aliases for those names, and in many programming languages they are implemented as pointers. 

There is nothing in C++ that says that this should point to the beginning of the object — in fact, in may MI implementations, it rarely does. So it may not have the same "value" (in terms of its bit representation) as self.

This does lead to some interesting questions on the details of mapping DCI onto C++, but that's a separate issue.

Matthew Browne

unread,
Jun 9, 2013, 7:49:06 PM6/9/13
to object-co...@googlegroups.com
How about this modification:

There is a special Role called self (or this in some implementations, usually depending on which is more idiomatic for a given programming language) which binds to the object playing the current Role.

Or it could be a footnote rather than being in parentheses.

If there are no objections then I can make the edit.



On 6/9/13 4:19 PM, James O Coplien wrote:
On Jun 9, 2013, at 6:20 , Matthew Browne wrote:

I think it might also be worth mentioning the�this�keyword, explicitly stating that�this�and�self�both point to the same object.

Only in some programming languages. DCI is PL-inspecific. We call the role self. There may be other pointers to the same object, including this. And "points to" is funny. There are no pointers in DCI, though there are names of objects and aliases for those names, and in many programming languages they are implemented as pointers.�

There is nothing in C++ that says that this should point to the beginning of the object � in fact, in may MI implementations, it rarely does. So it may not have the same "value" (in terms of its bit representation) as self.

rune funch

unread,
Jun 10, 2013, 1:37:26 AM6/10/13
to object-co...@googlegroups.com
Den 10/06/2013 kl. 01.49 skrev Matthew Browne <mbro...@gmail.com>:

There is a special Role called self (or this in some implementations, usually depending on which is more idiomatic for a given programming language) which binds to the object playing the current Role.

To me the only difference compared to the standard use of the this/self is that in a role method it refers to the role itself. In a context method it does not refer to a RolePlayer. I don't believe there's anything semantically special about this/self contrasted with the use of the term in the language of choice. It's commonly used in behaviors to identify the object the specific behavior is attached to so even the use in role methods can be seen as semantically identical to this common use

-Rune

Ant Kutschera

unread,
Jun 10, 2013, 3:25:02 AM6/10/13
to object-co...@googlegroups.com
I don't know, which is why I added "Of course, it would be interesting to see a DCI solution without roles, that also supported an object style of thinking..."

:-)

Ant Kutschera

unread,
Jun 10, 2013, 3:32:31 AM6/10/13
to object-co...@googlegroups.com
"self" isn't a Role.

AFAIK "self" is simply an implementation detail, dependent on language.

As an experiment try using Java and implementing Roles as wrappers.  "self" will be the data object and "this" will be the role object.  Since roles are stateless, you won't use "this" other than when calling role methods from within the role class.

class SomeRole {

    private Data self;

    SomeRole(Data rolePlayer){
        this.self = rolePlayer;
    }

    void aRoleMethod(){
        System.out.println("role player is " + self);
    }    
}

//test code:
Data data = new Data();
SomeRole rolePlayer = new SomeRole(data); //cast into role
rolePlayer.aRoleMethod();



See how "self" is used in the role method.

DON'T use a solution like this, especially if you are using hashmaps/sets.  In idiomatic DCI, self IS this - they are the same. 

James O Coplien

unread,
Jun 10, 2013, 3:34:34 AM6/10/13
to object-co...@googlegroups.com

On Jun 10, 2013, at 1:49 , Matthew Browne wrote:

If there are no objections then I can make the edit.

I object. In general, this is not self. Build an MI C++ implementation and compare their values in a role method for a role being played by an MI object.

James O Coplien

unread,
Jun 10, 2013, 3:35:27 AM6/10/13
to object-co...@googlegroups.com
On Jun 10, 2013, at 9:32 , Ant Kutschera wrote:

"self" isn't a Role.

You're half right. In DCI, self is a role.

Outside DCI, it's not.

AFAIK "self" is simply an implementation detail, dependent on language.

No.

Trygve Reenskaug

unread,
Jun 10, 2013, 5:34:23 AM6/10/13
to object-co...@googlegroups.com
I suggest that you study the DCI execution model:
    http://folk.uio.no/trygver/2012/DCIExecutionModel-2.1.pdf
rather than the simplified descriptions of DCI in Wikipedia etc.
There are many versions of 'an object style of thinking' that are not DCI.
Why is it so important to call something DCI?
If it's a good idea it is a good idea whatever you call it.
It would be interesting to see a new solution with a new name without roles, that also supported an object style of thinking.
--

Matthew Browne

unread,
Jun 10, 2013, 8:35:41 AM6/10/13
to object-co...@googlegroups.com
I strongly agree with Trygve. If it doesn't have roles, then it's not DCI. However, I think the underlying idea here is to explore alternatives to DCI that are similar in terms of the separation of data from behavior, but don't necessarily use roles.

I don't see how you could achieve both that and an "object style of thinking" without roles, but one area I see for overlap between SOA and DCI is that the idea of services could be part of the mental model for a DCI program, implemented either as a role or a sub-context. As far as I understand it, the goal in DCI is to find a good compromise between the end user's mental model and the programmer's mental model. If that means including the concept of a service as one of the objects involved, I see no reason that the DCI code shouldn't reflect that. As Ant pointed out in his paper, sometimes both the user and the programmer are thinking in terms of services - that seems like a case where services should definitely be represented in DCI.

Matthew Browne

unread,
Jun 10, 2013, 8:52:14 AM6/10/13
to object-co...@googlegroups.com
Jim, in my proposed edit I didn't say they were the same; I was simply pointing out that the "role" of the data object isn't always called "self" (it can be called "this" instead). In my injection-based PHP implementation, there is no self, there's only this. PHP automatically binds this to the current object so I saw no reason to introduce a new property self, not to mention the fact that in PHP you'd have to access it like this:

$this->self

which is just odd. The same would be true in Javascript.

Is there any way of indicating in the article that the DCI implementation can choose either self or this in a way that's both accurate and not confusing? I'm personally used to seeing this in the languages I work with most. If the Wikipedia article were my first introduction to DCI, I think it would probably have helped my understanding to see this mentioned, to emphasize that all the methods are being glued together into one object which in some languages could always be referred to from any of its methods (including role methods) as this.



On 6/10/13 3:34 AM, James O Coplien wrote:
On Jun 10, 2013, at 1:49 , Matthew Browne wrote:

If there are no objections then I can make the edit.

James O Coplien

unread,
Jun 10, 2013, 10:12:15 AM6/10/13
to object-co...@googlegroups.com

On Jun 10, 2013, at 2:35 , Matthew Browne wrote:

I don't see how you could achieve both that and an "object style of thinking" without roles,

Well, the self language has an object style of thinking, and it doesn't have roles. But it doesn't solve the same problems that DCI does, and it's not DCI.

James O Coplien

unread,
Jun 10, 2013, 10:18:16 AM6/10/13
to object-co...@googlegroups.com

On Jun 10, 2013, at 2:52 , Matthew Browne wrote:

Is there any way of indicating in the article that the DCI implementation can choose either self or this in a way that's both accurate and not confusing?

No. First, it is at the wrong level. We also had a language in Bell Labs where the concept "this" was called "me." Should I include that as well?

Second, I think you misunderstand the semantics of this. I suggested that people work up an example in C++ using MI. Do that, and I think you'll understand, and have the answer to your question. In short: within a given object (specifically, within the execution of an instance method of the object), the identifier this can have several different values. That is the semantics of this in C++. The semantics of self in other languages may be the same. But the question of "value of self" never arises in DCI. The identifier self is just the name of an object: an alias for the name of the current Role, both of which are names of the object playing the current Role.

The scoping rules for this and self are substantially different as well. And the concept of self in a role method can't exist outside the semantics of the Context, while self in an instance method is independent of any Context lookup.

This is all DCI 101. I'm a bit surprised at the persistence and insistence of the arguments around this.

James O Coplien

unread,
Jun 10, 2013, 10:19:02 AM6/10/13
to object-co...@googlegroups.com
On Jun 10, 2013, at 2:52 , Matthew Browne wrote:

Jim, in my proposed edit I didn't say they were the same; I was simply pointing out that the "role" of the data object isn't always called "self" (it can be called "this" instead).

It can be called "fred," but in DCI we call it "self." If you call it "this" in your DCI implementation you're likely to confuse people.

Matthew Browne

unread,
Jun 10, 2013, 10:43:31 AM6/10/13
to object-co...@googlegroups.com
I just want to make sure, MI stands for multiple inheritance, right?

I get your point that "self" and "this" are different in C++, but I don't see how creating a property called "self" would be helpful in either PHP or Javascript.

If you call it "this" in your DCI implementation you're likely to confuse people.
In PHP and Javascript I would argue the opposite; consider:

$this->self

I think most programmers would find that more confusing than simply using $this.

Matthew Browne

unread,
Jun 10, 2013, 11:48:49 AM6/10/13
to object-co...@googlegroups.com
Also, I realize that an ideal implementation in PHP might allow something like this:

//in the context
$someObj->addRole('Foo');
$someObj->addRole('Bar');

trait Foo {
    function fooMethod1() {
        //call a method on the data object
        $self->someMethod();
           
        $Bar->someMethodOnRoleBar();   
    }
}


In this case, $self, $Foo, and $Bar and would all be aliases to the same object ($someObj), but which of these identifiers was used would determine where the system would look for the method. I believe that's how Marvin, Maroon, and Trygve's Squeak extensions work.

However, that's not possible to do this in PHP without source transformation and the $self issue by itself is not enough to say that only source transformation is a valid approach to DCI in PHP. I believe the consensus is that while not perfect, method injection is acceptable - it seems to be working well for me thus far.

So given the way the PHP language works (all instance properties must be preceded by $this->), I think using $this instead of $self makes the most sense.

But if you don't like the idea of mentioning $this in the Wikipedia article, that's OK - PHP and Javascript are the only languages I can think of off the top of my where calling it "self" would result in the awkward $this->self or this.self notation.

Matthew Browne

unread,
Jun 10, 2013, 1:58:55 PM6/10/13
to object-co...@googlegroups.com
Just an improvement on my "ideal" example below:

//in the context
$Foo = $someObj
->addRole('Foo');
$Bar = $someObj
->addRole('Bar');

(or role binding could be automatic)

James O Coplien

unread,
Jun 10, 2013, 3:44:37 PM6/10/13
to object-co...@googlegroups.com
On Jun 10, 2013, at 4:43 , Matthew Browne wrote:

I get your point that "self" and "this" are different in C++, but I don't see how creating a property called "self" would be helpful in either PHP or Javascript.

So, do you want to update the WIkipedia article — and the definition of DCI – to reflect what this means in each of the 100 languages out there?

As I said before: This is at best a language mapping issue rather than anything of core importance to DCI. You are welcome to update any documentation of the PHP or Javascript mappings for DCI; that's appropriate. But don't push the bugs from those languages onto DCI.

$this->self

I think most programmers would find that more confusing than simply using $this.

I for one would like $self. I don't see the reason for making this hard.

At worst, this is a slide back into class-oriented thinking. The semantics of the this identifier in many of these languages reflect class semantics: consider an object persisting itself. For example, persisting *this won't persist the object, but a slice of the object related to the class of which the type of this is a derivative type.

I want to keep this as far away from the definition of DCI as possible. By all means put it in your language mapping documentation. But it's not part of DCI.


James O Coplien

unread,
Jun 10, 2013, 3:45:43 PM6/10/13
to object-co...@googlegroups.com

On Jun 10, 2013, at 5:48 , Matthew Browne wrote:

However, that's not possible to do this in PHP without source transformation 

And the problem is... ?

We have several other implementations out there based on source information. You might join the club to get the extra expressive power. If it's between doing that and changing the definition of DCI to fit an impoverished programming language, the choice is obvious.

Matthew Browne

unread,
Jun 10, 2013, 7:49:53 PM6/10/13
to object-co...@googlegroups.com
Hi Jim,
At first I didn't realize that my inclination to use this rather than self was a consequence of the specifics of PHP and Javascript - but I see now that this isn't an issue with other languages in "curly brackets land" as Rune put it, such as C++ and C#.

So I agree now that the Wikipedia article doesn't need to be updated just because of these two languages.
$this->self

I think most programmers would find that more confusing than simply using $this.
I for one would like $self. I don't see the reason for making this hard.
I don't know if you've ever programmed in PHP or Javascript, but if not, I think perhaps you're still not understanding that using self by itself is not possible in native PHP or Javascript. Instance properties must be accessed via this in those languages ($this->foo or this.foo).

My method-injection implementation for PHP is working well for me so far. As long as method injection is considered a valid, albeit imperfect, way to implement DCI, I don't see any reason why I shouldn't use it and stick with $this (since $self by itself isn't possible).

I am by no means against the idea of source transformation, and if I encounter a situation where method injection is problematic and there's no simple workaround, then I will work on a source transformation implementation for PHP. I don't even like PHP that much so I'd prefer to put my efforts into a different language (as long as my method injection approach continues to work well for the PHP systems I'm upgrading).

I didn't realize that calling the data object role "this" instead of "self" had such big consequences in terms of the definition of DCI. So now I will go on my merry way and drop my suggestion about this... :)

I still think that for my current PHP implementation, using $this makes sense.

James O Coplien

unread,
Jun 11, 2013, 5:01:04 AM6/11/13
to object-co...@googlegroups.com
On Jun 11, 2013, at 1:49 , Matthew Browne wrote:

> I don't know if you've ever programmed in PHP or Javascript, but if not, I think perhaps you're still not understanding that using self by itself is not possible in native PHP or Javascript.

I understand that.

I do not see that problem to be a DCI problem. It is a PHP / Javascript problem.

I am glad you recognize the problem.

I don't think we are going to fix it by changing DCI.


Matthew Browne

unread,
Jun 11, 2013, 9:10:24 AM6/11/13
to object-co...@googlegroups.com
On 6/11/13 5:01 AM, James O Coplien wrote:
I don't think we are going to fix it by changing DCI.
And I'm not asking for that. It was a misunderstanding on my part.

My current understanding is that in languages like Marvin or Scala (to set aside PHP/Javascript for a moment), which don't support C++ style multiple inheritance, within a role method, self is almost always interchangeable with this. I believe that's what Rune was saying.

James O Coplien

unread,
Jun 11, 2013, 9:36:11 AM6/11/13
to object-co...@googlegroups.com

On Jun 11, 2013, at 3:10 , Matthew Browne wrote:

My current understanding is that in languages like Marvin or Scala (to set aside PHP/Javascript for a moment), which don't support C++ style multiple inheritance, within a role method, self is almost always interchangeable with this. I believe that's what Rune was saying.

I wouldn't necessarily want that repeated, if for no other reason that this and self have different semantics, that work out to be the same by coincidence in some languages, with one having a class heritage and the other more of an object heritage. It's a small thing, but small things matter.

Ant Kutschera

unread,
Jun 12, 2013, 2:13:49 PM6/12/13
to object-co...@googlegroups.com


On Sunday, 9 June 2013 21:04:45 UTC+2, Matthew Browne wrote:
Thanks Ant, that makes sense. I'm just wondering, which of my examples do you think comes closest to micro SOA as you would approach it?

Hi Matthew,

You asked which of your approaches comes closest to micro SOA.  If I were to program the money transfer example in micro SOA it might look as follows, written in Scala (for no particular reason).

Let's start with a user story: as an accountant I expect a money transfer to decrease the balance of the source account and to increase the balance of the destination account such that their total remains equal before and after the transfer.

//data transfer object (design pattern for a class holding data, see Sun Java EE Patterns / Blue Prints I think)
case class Customer(id: String, name: String)

//data transfer object
case class Money(amount: BigDecimal, currency: Currency)

//data transfer object
case class Account(id: String, var balance: Money, holder: Customer){
    def increaseBalance(amount: Money){
        assert(balance.currency == amount.currency)
        this.balance = new Money(balance.value.add(amount.value), balance.currency)
    }
    def decreaseBalance(amount: Money){
        assert(balance.currency == amount.currency)
        this.balance = new Money(balance.value.subtract(amount.value), balance.currency)
    }
}

//the service
class SimpleAccountingService {
    //transfers amount from source to destination, within a transaction
    def transferMoney(source: Account, destination: Account, amount: Money){
        val totalBefore = source.balance.value.add(destination.balance.value)
        source.decreaseBalance(amount)
        destination.increaseBalance(amount)
        val totalAfter = source.balance.value.add(destination.balance.value)
        assert(totalBefore == totalAfter)
    }
}

//driver code
object Test extends App {

    import CurrencyConstants._
    implicit def int2BigDecimal(i: Int) = new BigDecimal(i)
    
    val matt = Customer("mbr", "Mattthew Browne")
    val ant = Customer("aku", "Ant Kutschera")
    val source = Account("src", Money(100, GBP), matt)
    val destination = Account("dest", Money(100, GBP), ant)

    val accounting = new SimpleAccountingService
    
    accounting.transferMoney(source, destination, new Money(10, GBP))

    assert(source.balance.value == new BigDecimal(90))
    assert(destination.balance.value == new BigDecimal(110))
    
    println("Done: " + destination)
}

So, you can read the user story in the code of the SimpleAccountingService.

But that doesn't really make use of micro SOA because the example is to simple.  There are no dependencies on other stuff for example.

Let's write some other user stories: 

- as a customer I want to be able to hold an account
- as an account holder I want to be able to have an account in a currency of my choice
- as an account holder I want to be able to deposit money into my account, in any currency
- as an accountant I want deposits to be written as credits, in a ledger, always in GBP
- as an accountant I want the deposit to increase the balance of the target by the deposit amount, converted into the accounts currency

To implement this, I functionally decompose so that I end up with an accounting service, a ledger service and a currency service.  Each has a different responsibility:

- Ledger Service is responsible for writing credits to the ledger
- Currency Service is responsible for determining the value of a given amount in a different currency
- Accounting Service is responsible to modifying account balances and has the overall responsibility to orchestrate other services,

The ledger service could look like this (using Java EE annotations to cover cross cutting concerns such as concurrency, scaling and transactions):

//internal to accounting component
@Stateless
@LocalBean
class LedgerService {
    
    @TransactionAttribute(REQUIRED)
    def writeCredit(credit: Option[Credit]){
        //the data in this method is playing a 
        //different role than it is when it is 
        //used in the accounting service

        credit.map{ c =>
            println("deposited " + c.value + " into account " + c.accountReference)
        }
    }
}

A credit is defined as follows:

//data transfer object
case class Credit(accountReference: String, value: BigDecimal)

The currency service could look like this:

//internal to accounting component
@Stateless
@LocalBean
class CurrencyService {
    
    def convert(amount: Money, targetCurrency: Currency) = {
        import CurrencyConstants._
        if(amount.currency == targetCurrency){
            Some(amount)
        }else if(targetCurrency == GBP && amount.currency == EUR){
            Some(Money(amount.value.divide(new BigDecimal(1.25)), targetCurrency))
        }else{
            None
        }
    }
}
object CurrencyConstants {
    val EUR = Currency.getInstance("EUR")
    val GBP = Currency.getInstance("GBP")
}

A new accounting service would look as follows, where the lines starting with @EJB are the dependencies that this service has on other more fine grained services.  In the real world a container which runs this code would be responsible for injecting the relevant instances of the services shortly before making this service available for use.

//interface to a component that is responsible for accounts
@Stateless
@LocalBean
class AccountingService {

    @EJB var currencyService: CurrencyService = _
    @EJB var ledgerService: LedgerService = _
    
    //transfers amount from source to destination, within a transaction
    @TransactionAttribute(REQUIRED)
    def depositMoney(destination: Account, amount: Money){

        //convert into accounts currency
        val amountInAccountsCurrency = currencyService.convert(amount, destination.balance.currency)

        //always written in GBP, because the bank works in that currency
        val amountGBP = currencyService.convert(amount, destination.balance.currency)
        val credit = amountGBP.map(a => Credit(destination.id, a.value))
        ledgerService.writeCredit(credit)

        destination.increaseBalance(amountInAccountsCurrency.get)
    }
}

Finally, some driver code could look like this:

object Test2 extends App {

    import CurrencyConstants._
    implicit def int2BigDecimal(i: Int) = new BigDecimal(i)

    //setup service hierarchy
    val accountingService = new AccountingService
    accountingService.currencyService = new CurrencyService
    accountingService.ledgerService = new LedgerService

    //setup data
    val ant = Customer("aku", "Ant Kutschera")
    val destination = Account("dest", Money(110, GBP), ant)
    
    //do test
    accountingService.depositMoney(destination, Money(10, EUR))

    //assertions
    assert(destination.balance.value == new BigDecimal(118))
    assert(destination.balance.currency == GBP)
}

What you can see from above is that the AccountingService still implements the user stories but that it delegates to other more fine grained services to get work done (so that it isn't a transaction script for example).  Responsibilities are clearly defined, making services usable by other services (perhaps ones not shown here).

This code now gives behaviour first class status; separates rapidly changing code (behaviour) from slowly changing domain knowledge (data); helps system developers reason about system-level state; supports thinking close to my mental model (and yours if you have seen the light).  It almost fulfils the goals of DCI according to the Wikipedia definition.

This example also shows how micro SOA handles roles.  The ledger service has an interface which only knows about credits, consisting of an account reference and the value to transfer, in the banks own currency.  The data (reference number and value) are playing a different role - they are playing the role of a credit, rather than the roles of an account and some money.  They end up in this role because the accounting service maps this data into the appropriate role (data class) before calling the ledger service.  I have to admit, that it is a bit dodgy requiring the caller of the ledger service to convert the amount into the correct currency - perhaps a more satisfying solution would pass a Money object to the ledger service which would do the conversion itself with the help of the currency service.

In my paper I state that a DCI context is analagous to the code which calls a service in micro SOA - so the accounting service is acting a little like a context when you think about what it is doing here (assigning roles; implementing user stories).  As such, I can attempt to create a DCI solution:

@Stateless
@LocalBean
class DepositContext {
    
    //the definition of a role
    implicit class CurrencyConverter(self: Money){
        import CurrencyConstants._
        def convert(targetCurrency: Currency) = {
            if(self.currency == targetCurrency){
                Some(self)
            }else if(targetCurrency == GBP && self.currency == EUR){
                Some(Money(self.value.divide(new BigDecimal(1.25)), targetCurrency))
            }else{
                None
            }
        }
    }

    //the definition of another role
    implicit class LedgerWriter(self: Account){
        def writeLedgerCredit(value: Option[BigDecimal])={
            value.map{ v =>
                println("deposited " + v + " into account " + self.id)
            }
        }
    }
    
//I believe it is traditional to pass the parameters into the 
//context constructor, but in this case I am experimenting with 
//passing them to the execute method
    @TransactionAttribute(REQUIRED)
    def execute(destination: Account, amount: Money) = {
        //the next line uses a role method called convert!
        val amountInAccountsCurrency = amount.convert(destination.balance.currency)

        //always written in GBP, because the bank works in that currency
        //the next line uses the role method again!
        val amountGBP = amount.convert(destination.balance.currency)

        //call role method on account, in order to write credit into ledger
        destination.writeLedgerCredit(amountGBP.map(_.value))
        
        destination.increaseBalance(amountInAccountsCurrency.get)
    }
}

And here the DCI driver:

object Test3 extends App {

    //setup data
    val ant = Customer("aku", "Ant Kutschera")
    val destination = Account("dest", Money(118, GBP), ant)
    
    //do test
    new DepositContext(destination, Money(10, EUR)).execute
//assertions
    assert(destination.balance.value == new BigDecimal(126))
    assert(destination.balance.currency == GBP)
}

Here it was hard to decide which object should play the role of a LedgerWriter - the account, or the amount?  What do you think?

I guess the main difference between the micro SOA solution and the DCI solution is that while the micro SOA solution uses objects, it isn't object oriented, in that the transfer and deposit methods are not called on the objects containing the data.  But they are contained on objects and as such, this solution is object oriented.  In fact it's multi-paradigm, because it uses object orientation since services are instances of classes; SOA because there is a service hierarchy; aspect oriented programming due to the annotations which can be used to take care of cross cutting concerns; and functional programming, where for example the currency services returns an Option which is a monad, and which is used to map the data into a Credit instance in the accounting service.

Counting lines of code, both solutions come out with around 35 lines of code.  The DCI restricts the use of role code in other contexts, whereas micro SOA does not (in DCI, Roles are part of the inner workings of the context which defines them).

Maybe I should write another paper comparing micro SOA to Scala DCI code, since it looks a lot nicer in Scala.

Cheers,
Ant

 

Matthew Browne

unread,
Jun 13, 2013, 9:47:42 PM6/13/13
to object-co...@googlegroups.com
Hi Ant,
Thanks for the thorough response. This is very helpful to my understanding of micro SOA.

Here it was hard to decide which object should play the role of a LedgerWriter - the account, or the amount?  What do you think?
I would say probably the account, mainly because there could conceivably (perhaps in the future) be other data besides the amount that might need to be involved in writing ledgers, and also because the idea of a "sentient" account that can do things somehow seems more natural to me than a "sentient amount", but that might just be me :) It could probably go either way.

I'm still going through your email but for now I just want to thank you again for the explanation, and for the DCI version too which makes a nice comparison. I agree that the Scala code is better for showcasing DCI especially.

Cheers,
Matt

Jörgen Andersson

unread,
Jun 13, 2013, 11:32:53 PM6/13/13
to object-co...@googlegroups.com

Hi Ant,

Some comments on my part in relation to your reasoning.

> This example also shows how micro SOA handles roles.  The ledger service has an interface which only knows about credits, consisting of an account reference and the value to transfer, in the banks own currency.  The data (reference number and value) are playing a different role - they are playing the role of a credit, rather than the roles of an account and some money.  They end up in this role because the accounting service maps this data into the appropriate role (data class) before calling the ledger service.  
>

I think that conclusion requires a very broad definition of "role", which I don't see align with the definition of role in DCI. In your example the calling service is just packaging up some data into a data structure required by the API it is to call. To me that is not a role, it is a parameter object, or, if the combined value has a greater meaning in the domain it might be a "value object" as defined in DDD.

> I guess the main difference between the micro SOA solution and the DCI solution is that while the micro SOA solution uses objects, it isn't object oriented, in that the transfer and deposit methods are not called on the objects containing the data.  But they are contained on objects and as such, this solution is object oriented.  In fact it's multi-paradigm, because it uses object orientation since services are instances of classes; SOA because there is a service hierarchy; aspect oriented programming due to the annotations which can be used to take care of cross cutting concerns; and functional programming, where for example the currency services returns an Option which is a monad, and which is used to map the data into a Credit instance in the accounting service.
>

I think the micro SOA approach is service oriented, yes. It might also to some extent functional, even though I think there are many criterias to fill before being regarded as "fully functional" by the FP community.
However, to me the solution is only OO and AOP because the technical platform you have chosen requires it from a technical perspective. From a domain point-of-view, stripping of dependency injection, scalability- and transactional concerns (from a technical point-of-view they could be applied only in an outer service, wrapping the whole domain code), the domain logic could just as well have been implemented as static methods. Hence I can't see there being any OO aspect inherent to the micro SOA approach.

Now, wether that is god or bad depends on ones preferences. On my part, I don't like the approach, because I think it subtracts more value, compared to "everyday OO", as e.g. applied in the technical parts of DDD, and OO as applied by DCI, than it adds.
- Compared to "everyday OO" micro SOA adds separation if parts that move at a different rate, which is good, but it does it by scattering the algorithms in different services, related only by the types of parameters they accept.
- Compared to DCI micro SOA allows for reuse of algorithms (services can be reused, whereas roles cannot). However, reusing small parts (services) of an overall algorithm (a use-case) makes maintenance harder since you need to consider (and test) every use-case where that service is used in order to safely make a change. This type of re-use might be to low level to have any relation to the user- or business mental models. In addition, with the over all algorithm broken down into several small services it is hard to see the overall flow, whereas in DCI the whole algorithm of a use-case is contained within the context.

Ultimately it comes down to how you decompose your system. I think both DDD (keeping data and functionality for a given domain concept together) and DCI (keeping algorithm of the whole use-case together) have advantage over the micro SOA approach. I think it makes sense to re-use, either on domain concept level or on use-case level since they are both high enough level to have a notion in the business side of things. Currently I'm leaning more and more towards favoring the use-case level.

BR,
Jörgen

rune funch

unread,
Jun 14, 2013, 2:13:36 AM6/14/13
to object-co...@googlegroups.com
Den 14/06/2013 kl. 03.47 skrev Matthew Browne <mbro...@gmail.com>:

> Here it was hard to decide which object should play the role of a LedgerWriter - the account, or the amount? What do you think?
This is a good example of where micro SOA (the artist formerly known
as procedural programming) makes it harder to understand the code. In
the real world there's no such thing as a 'LedgerWriter' so to be able
to understand the code I first need to learn a new concept even if I'm
an expert in the banking domain. It also means there's a decoupling
between the modeled domain and the modeled or in other words the model
models and different domain than it said out to model. What happens if
the banking domain introduces a LedgerWriter which is a special kind
of tamper proof printer? Or some other change that's consistent with
the domain but not with the pseudo domain being modeled?
It has been shown that users have a higher acceptance of systems with
a 1-1 model (real world-computer model) because they can relate.
Doesn't it almost follow from that, that developers will relate better
to code that models the real thing? And what happens in the
communication between end user and developer if the developers relate
to a pseudo model while the users relate to the actual model? And is
it really true that you can (sensibly) change the users mental model
of his/her domain to fit the pseudo model without impacting his/her
work because the work would then be based on a model that's not real!

-Rune

Jörgen Andersson

unread,
Jun 14, 2013, 2:39:46 AM6/14/13
to object-co...@googlegroups.com

+1

--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To unsubscribe from this group and stop receiving emails from it, send an email to object-composit...@googlegroups.com.

To post to this group, send email to object-co...@googlegroups.com.

Matthew Browne

unread,
Jun 14, 2013, 9:45:05 AM6/14/13
to object-co...@googlegroups.com
Rune,
I agree with your point that it's better to model more closely to the real world, which is one of the arguments in favor of DCI here. However, I think it should be noted that even in DCI you're often dealing with a pseudo-model.

For example, in the real world, an account doesn't withdraw money from itself or deposit money to itself -- a bank employee and/or its computer systems actually do that. If we were to model only real-world roles then almost all roles would be representing people rather than inanimate or virtual objects.

So it's more a question of coming up with a pseudo-model that's close to the real world and can be understood easily (or as easily as possible) by end users and programmers alike.

Ant addressed this in his paper:
Consider [...] a word processor. When the user wants to insert an image from a file, the user selects the file and clicks the OK button to get the system to read the file, place it in the current paragraph and display it on the screen. The author has quizzed a number of people about how they model such things in their minds and has always been told that it is either the user themselves, or “the system” or the word processor (a higher power, a service) which does these tasks. It has never been stated that the document or a paragraph or any other entity which is part of a typical document data model does such things.

Things such as game engines and word processors have state, but this state is the “M” in MVC; it is the data model which SOA or DCI enrich with functionality. Such state does not need to be modelled together with the higher-power behaviour which operates on it, as is suggested by object orientation, i.e. in the same class. Rather the higher-power behaviour can and should be split out into another class. Whatever the situation, in almost all problems solved by software, one can find a higher power responsible for things related to use-cases or algorithms.

I would argue, however, that the "higher-power behavior" should not necessarily be split out into a separate class or object. Often the idea of objects being able to do things to themselves that they wouldn't be able to do in the real world is very helpful to programming, which has been proven many times over the years and is rather fundamental to object orientation to begin with...the "network of communicating objects," where each object is like its own mini-computer taking part in a larger network (if I recall Jim's talk correctly, those ideas are from Alan Kay).

In DCI the behavior is technically being split out into a separate class or trait in order to define the roles separately from the data model, but since it gets glued into one object in the end it's fundamentally different from the service approach.

I'm not arguing for either micro SOA or DCI here, I'm just pointing out that the idea of modeling the real world in a computer system is never one-to-one, and that there are often differing interpretations.

rune funch

unread,
Jun 15, 2013, 4:58:24 AM6/15/13
to object-co...@googlegroups.com
Den 14/06/2013 kl. 15.45 skrev Matthew Browne <mbro...@gmail.com>:

> Rune,
> I agree with your point that it's better to model more closely to the real world, which is one of the arguments in favor of DCI here. However, I think it should be noted that even in DCI you're often dealing with a pseudo-model.
Most models are abstractions so I agree that it's a matter of how
close you get. Inventing something that's not part of the model is no
longer an abstraction upon the real thing but an abstraction of a
different model which was the point I was trying to make

> For example, in the real world, an account doesn't withdraw money from itself or deposit money to itself -- a bank employee and/or its computer systems actually do that.
It's the users mental model we are modeling so ask your self which of
these sentences would you use
1) thanks for the money dad. I'll deposit that to my savings account
2) thanks for the money dad. I'll give them to my PBA so that he can
use a computer to deposit them on my account

-Rune

Ant Kutschera

unread,
Jun 15, 2013, 3:24:58 PM6/15/13
to object-co...@googlegroups.com
On Friday, 14 June 2013 08:13:36 UTC+2, Rune wrote:
In the real world there's no such thing as a 'LedgerWriter' so to be able
to understand the code I first need to learn a new concept even if I'm
an expert in the banking domain.

Clearly, you have not worked at the Bank of Kutschera, based here in Switzerland.  In that bank you will find a little man, who looks much like the bankers in Harry Potter, who writes every transfer and deposit into a little black book, known in the bank as the ledger.  He is referred to as the "ledger writer".  He, like many swiss bankers, will help you avoid your taxes if you live in the US.

In *my* experience, we (the people I work with; my customers) rarely build systems these days which reflect something that currently happens non-electronically, and so we cannot simply look at the real world to determine what happens there, and model that in software.  Even if the processes did exist manually, we would want to improve them (IT is often about making companies more efficient).  That means we (end users, customers, IT, stakeholders) come up with models which don't always make sense, and can't always reflect the real world.

But Rune, instead of us talking philosophically at a high level, why don't you take my user stories and show us your DCI solution?  I would be interested in the roles that you extract from the user stories.
 

Ant Kutschera

unread,
Jun 15, 2013, 3:28:56 PM6/15/13
to object-co...@googlegroups.com
On Friday, 14 June 2013 05:32:53 UTC+2, Jörgen Andersson wrote:

I think that conclusion requires a very broad definition of "role", which I don't see align with the definition of role in DCI.


I agree, there is some artistic licence in there :-)  

In fact in a typical SOA solution you also don't find use case code directly in high level services.  It does belong there, but it isn't an explicit aim of micro SOA to keep use case code readable in high level services, and so it often gets pushed around all over the place and ends up being lost.

I'm not arguing that micro SOA is better than DCI - I was asked about it and have tried to point out some snyergies.  With artistic licence you get close to achiving the goals which DCI sets out to achieve.


- Compared to "everyday OO" micro SOA ... scattering the algorithms in different services, related only by the types of parameters they accept.

That isn't entirely true if you use micro SOA to build components.  The related algorithms are found within single components, implemented as a set of services.  Look hard enough at the details and you will also likely find OO used inside the services, for example in the objects which support the services.


 

Ultimately it comes down to how you decompose your system.

I like this paragraph.  I think you are right that DCI concentrates on use cases; DDD concentrates on domain concepts.  I would say micro SOA concentrates on (technical?) components.

I favour SOA (who would have guessed!).  Where I struggle with DCI is in extracting roles out of the use cases.  Same problem above where I couldn't decide if "amount" or "account" should play the role of a ledger writer.  Maybe we could experiment and get others to list the roles that they can identify out of my user stories?
 

James O Coplien

unread,
Jun 15, 2013, 5:03:35 PM6/15/13
to object-co...@googlegroups.com

On Jun 15, 2013, at 9:24 , Ant Kutschera wrote:

why don't you take my user stories and show us your DCI solution? 

One answer might be that DCI is not a solution to user stories, because user stories are not enabling specifications. They are only cocktail-party conversation starters.

James O Coplien

unread,
Jun 15, 2013, 5:06:35 PM6/15/13
to object-co...@googlegroups.com

On Jun 15, 2013, at 9:28 , Ant Kutschera wrote:

 Where I struggle with DCI is in extracting roles out of the use cases. 

Then maybe your use cases aren't use cases. A role is pretty explicit in a use case; it's usually called an actor. The mapping is often one-to-one. That part isn't rocket science. So if you're running afoul of DCI it's probably more likely because you're running afoul of use cases. That would fit, if you're an advocate of user stories. The two are like oil and water. As Alistair Cockburn said, a user story is to a use case as a gazelle is to a gazebo. They both start with the same three letters.

That is not the level at which design progress unfolds, but it seems to be the level of this discourse.

Matthew Browne

unread,
Jun 15, 2013, 5:16:28 PM6/15/13
to object-co...@googlegroups.com
Ant, did you see Trygve's recent posts about his updated money transfer
examples, particularly this one:

https://groups.google.com/d/msg/object-composition/0S3wTQ10d_8/6r-Ts3oSzDEJ

While it doesn't address all of the potential roles for your user
stories (which as Jim mentioned we would be able to analyze better with
an actual use case), it's certainly relevant to the discussion.

Matthew Browne

unread,
Jun 15, 2013, 6:01:10 PM6/15/13
to object-co...@googlegroups.com
On 6/15/13 5:06 PM, James O Coplien wrote:
> A role is pretty explicit in a use case; it's usually called an actor.
> The mapping is often one-to-one.
This is true, but there are also very often roles in DCI that do not
correspond to UML actors - the Source Account and Destination Account
roles, for example.

This is related to the point I was making earlier - in
object-orientation, the model comes close to the real world, but not
exactly, because in the real world, inanimate or virtual objects don't
do things to themselves (like an account withdrawing money from itself).
So we have both the real-world roles (the UML actors - users of the
system and external systems) and additional roles that are determined in
the process of writing the use case description.

Those additional roles should generally still be part of the end user's
mental model, even if we're giving them "special powers" (as is the case
with the Source Account and Destination Account roles here). It wouldn't
be right to call them "virtual" or "non-real-world" roles - oftentimes
they're just "passive" roles in the real world and we're making them
"active" in our code.

It's these additional roles that I find a bit more difficult to analyze
sometimes, and which are more open to differing interpretations. In the
shopping cart example that Marc and I were discussing (which was based
on a well-defined use case), Marc came up with several different
interpretations of the roles.

It's also worth mentioning that the UML actors aren't always represented
as roles in every DCI context to which they are relevant. Again, the
Money Transfer context is a good example - there's no "Customer" or
"Accountant" role in the code.

I think role analysis is part of the art of DCI programming and is one
of the things that makes it intellectually interesting. But it's very
practical too - it's not a matter of inventing roles, but rather
discovering them in the end user's mental model and the use case.

rune funch

unread,
Jun 16, 2013, 4:18:52 AM6/16/13
to object-co...@googlegroups.com

2013/6/15 Ant Kutschera <ant.ku...@gmail.com>

why don't you take my user stories and show us your DCI solution?  I would be interested in the roles that you extract from the user stories.

I can't. A user story defines an end/a goal but there's no interactions and without interactions no roles. A use case on the other hand focuses on the interactions to reach a certain goal.In the specific case at least 3 out of 5 are stories pertaining details of data and not functionalities. Those are by definition without interactions

These three are all simple data requirements

- as a customer I want to be able to hold an account
- as an account holder I want to be able to have an account in a currency of my choice
- as an accountant I want deposits to be written as credits, in a ledger, always in GBP

The point I was trying to make in my two previous mails, though not clearly expressed I admit, is that we try to model the real world as the user perceives it aka we try to model the user mental model. In that respect systems can roughly be put in three categories. 

1) Those that model the real world as perceived by the user
2) Those that improve it
3) Those that try to change it to fit something the developers find easier to model

The first one is the world that's the easiest to have success with. You can still improve the productivity with out changing the model! I was on a project some years ago where my customer had been ranked second last in the industry world wide when it came their IT offerings to customers. for the next 1 and a half year we didn't do anything but trying to get closer to the users mental model. The application was old and build before any one had actually talked to the real users. We asked questions about have the system was used and found that we we only modeling part of the model (and badly) we included much more of the model and tried to model closer to the user end model. We added _one_ feature and by the next ranking we landed at a second place with 42 points and the leader having 44. The impact was from one single feature that was a true representation of the end users mental model of their domain. 

the 2nd category has the problem that the users won't be able to just start and work with the system that require training. My step dad is an accountant and he could for month type in his pin when the credit card terminals were changed a few years back. He's been using calculates longer than I've be around and uses them at lightning speed without looking. That mental model was a perfect fit for the old terminals, then they went and reversed the order. For good reasons I'm sure but it hampered his productivity for quite some time. In a longer run it might increase it but there's the risk of the system being discarded for the simple reason that though it can be empirically shown to be a better model people are not willing to change. If you don't believe me then look at your keyboard are you using qwerty or dvorak? The former mental model was build to help create type writers that didn't block. letters that usually comes close in words are as far as part as possible. using dvorak it's the reverse increasing productivity. dvorak has been around for quite some time but has gained the needed momentum. The iphone on the other handed changed the mental model of how to interact with a phone and gained the needed momentum and every one else started copying to some extent and the mental model following a multi touch screen has becomed predominant

Then there's the third category, where the model is changed to fit the needs of the developer. It suffers the downside of the 2nd category the users needs to change how they think but it does not reep the potential benefits. These models are usually easy to spot because they introduce elements that are not part of the users mental model and those elements typically doesn't add to the model either, they are mostly glue to keep the "real" model together.

-Rune

James O Coplien

unread,
Jun 16, 2013, 5:58:09 AM6/16/13
to object-co...@googlegroups.com

On Jun 16, 2013, at 12:01 , Matthew Browne wrote:

>> A role is pretty explicit in a use case; it's usually called an actor. The mapping is often one-to-one.
> This is true, but there are also very often roles in DCI that do not correspond to UML actors - the Source Account and Destination Account roles, for example.

I strongly disagree. You can write a business use case and choose to be faithful to that. Or you can first write a business use case and then write what's called an "internal use case" whose actors are internal components (e.g., the artificial accountant role that was recently invoked here). Your DCI implementation can adhere to either, or both.

Lack of a match between your use case and the DCI code says that something is wrong with one of them. Use cases have all the expressive power you need to map one-on-one to DCI thinking.

There's no reason we need to choose to this wrong yet it is sometimes hard to come out of old worldviews that suggest certain limitations in the use of the tools in front of us. The way most agile people regard use cases puzzles me, and when they describe to me what they think a use case is I wonder what dungeons of the 1980s they had to wander to be able to invent such notions.

James O Coplien

unread,
Jun 16, 2013, 5:58:35 AM6/16/13
to object-co...@googlegroups.com

On Jun 16, 2013, at 10:18 , rune funch wrote:

I can't. A user story defines an end/a goal

It does?

Matthew Browne

unread,
Jun 16, 2013, 10:44:27 AM6/16/13
to object-co...@googlegroups.com
Hi Jim,
I am aware of "internal use cases" (or "subfunction" level use cases as Cockburn calls them) but I wasn't aware of their importance in the DCI design process except in the case of re-usable functionality that is included using the "include" statement. I was under the impression that in DCI we are generally translating user-goal level use cases directly to code, without necessarily writing supporting internal use cases first.

The idea of "internal actors" is new to me, although after a quick search I see that the idea has been part of the use case tradition for a long time.

But I haven't seen any examples where the internal actors are spelled out specifically; all the "internal use case" descriptions I've seen just follow the regular use case template; in other words I've never seen something like this:
Primary Actor(s):
Internal Actors:
Precondition:
...
Main Success Scenario:
...
Rather, the internal actors (DCI roles) are usually just part of the use case description.

And I would still say that there can be multiple different interpretations of who/what the internal actors are, and that this is something that emerges in the process of writing use case descriptions. There's no cut-and-dried formula here.

If "internal use cases" are such an integral part of the process, I'm surprised they haven't come up here more often. I suppose that sometimes the roles are obvious and one can go straight from the user goal-level use case to code.

James O Coplien

unread,
Jun 16, 2013, 11:51:13 AM6/16/13
to object-co...@googlegroups.com

On Jun 16, 2013, at 4:44 , Matthew Browne wrote:

But I haven't seen any examples where the internal actors are spelled out specifically; all the "internal use case" descriptions I've seen just follow the regular use case template; in other words I've never seen something like this:

Internal and external are purely in the mind of the beholder and are defined by (ahem) context.

Though Ant maybe doesn't know use cases, let's imagine that he did. Let's go back to his mail:

On Jun 15, 2013, at 9:24 , Ant Kutschera wrote:

Clearly, you have not worked at the Bank of Kutschera, based here in Switzerland.  In that bank you will find a little man, who looks much like the bankers in Harry Potter, who writes every transfer and deposit into a little black book, known in the bank as the ledger. He is referred to as the "ledger writer".  He, like many swiss bankers, will help you avoid your taxes if you live in the US.

Let's say that we wanted a use case for this. Because the use case uses "ledger writer" as an actor, and since they don't exist as business entities, is the scenario described by Ant an internal or external use case? Or are you suggesting that he would be disallowed from using "ledger writer" in a use case at all? Or from using it in DCI at all? Or should he just never have brought it up?

I think that most if not all of Trygve's DCI examples are internal use cases (front loading, for example). Dijkstra's algorithm stands as a good example, and it can be written as a use case (a somewhat messy one). I don't understand why they should all of a sudden have become verboten in DCI.

Matthew Browne

unread,
Jun 16, 2013, 12:50:02 PM6/16/13
to object-co...@googlegroups.com
On 6/16/13 11:51 AM, James O Coplien wrote:
I think that most if not all of Trygve's DCI examples are internal use cases (front loading, for example). Dijkstra's algorithm stands as a good example, and it can be written as a use case (a somewhat messy one). I don't understand why they should all of a sudden have become verboten in DCI.
I wasn't suggesting that they be verboten at all. Let me clarify my earlier statement:
But I haven't seen any [use case] examples where the internal actors are spelled out specifically
My point in mentioning this was that I haven't seen any internal use cases where it was completely straightforward to extract the DCI roles from the use case. Internal actors and use cases should indeed be represented in DCI; I'm just talking about the process of identifying them.

The use case literature that I've seen doesn't emphasize the idea of "object roles" but of course we can improve on that by writing the use case in a specific way, for example by italicizing the roles.

So now that I think about it, I have seen use cases where the internal actors are spelled out specifically -- in the Lean Architecture book, in which all the roles (including internal ones) are italicized.

Writing the use case in this way requires a certain style of thinking, especially when you get into the finer-grained levels; take this example from the book:
1. SourceAccount verifies funds available.
2. SourceAccount and DestinationAccount update their balances.
3. SourceAccount updates the statement info.
I suppose the above list of steps would qualify as an internal use case (or at least part of one).

A alternate version of the above sequence without the focus on roles could be:
1. The system verifies that the source account has sufficient funds available
2. The system updates the balances for the source account and destination account
3. The system updates the statement info for the source account
Obviously, the first version is much more helpful for DCI (and perhaps in general), but we should keep in mind that it's just one interpretation. As discussed earlier, we could have an "accountant" or "ledger writer" role here as well.

I'm just trying to get a better understanding of the DCI design process as it relates to use cases. It seems to be that what you're recommending is the following sequence:

1. Write the "user goal"-level use cases with an emphasis on external actors
2. Write supporting internal use cases with an emphasis on internal actors
3. Translate the use cases to DCI code

It's step 2 that I haven't seen much mention of on this forum and which I think could use more clarification.

Thanks,
Matt
--
You received this message because you are subscribed to a topic in the Google Groups "object-composition" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/object-composition/e6K7KhKkdnM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to object-composit...@googlegroups.com.

Trygve Reenskaug

unread,
Jun 17, 2013, 4:55:38 AM6/17/13
to object-co...@googlegroups.com
I don't see DCI as a method for realizing any odd domain model that initially may be in the user's mind. The lean principle "everybody, all together, all the time" says that user and programmer together shall collaborate to construct a new mental model that extends the initial domain model with an explanation of how the new system works. The user is an active member of the development team and the programmer creates a system that will feel like an extension of the user's mind - no surprises.

James O Coplien

unread,
Jun 17, 2013, 12:00:41 PM6/17/13
to object-co...@googlegroups.com
On Jun 16, 2013, at 6:50 , Matthew Browne wrote:

My point in mentioning this was that I haven't seen any internal use cases where it was completely straightforward to extract the DCI roles from the use case.

Maybe we need more example use cases to accompany the internal use case examples. Is your observation any more than the lack of such examples?

I have always looked down on internal use cases as I've too often found them to be the nerds' revenge: pseudo-code with overkill. Too often they are done by programmers without much connection to any end user, and too often they seem to be a pro-forma methodological chit instead of a foundation for the kind of dialog Trygve mentioned in his mail ("everybody, all together, from early on"). But they probably do have a place.

Ant Kutschera

unread,
Jun 17, 2013, 3:44:19 PM6/17/13
to object-co...@googlegroups.com
On Sunday, 16 June 2013 17:51:13 UTC+2, Cope wrote:
Though Ant maybe doesn't know use cases, let's imagine that he did.

I'm still a little timid of presenting any here, after the last time I tried, some 18 months ago with my Till example.  Hopefully I'm a little better at it now.

So here are my user stories written as a use case in the style used in Cope's book, so hopefully it is good.  Can someone please help me to identify the actors and roles?

Use Case: Deposit Money
========================

Business Goal: Account holders can put (foreign) cash into an envelope at an ATM and deposit the cash filled envelope which results in an immediate increase to their funds, enabling them to say pay a bill or use the money in their currency.  

Preconditions: The account holder has a good credit rating and history (see business rule 453).

Step 1.
Actor Intention: The account holder selects an account for which they wish to deposit money.  

System Responsibility: The bank displays the account information. The bank displays a field to enter the amount and a combo to select the currency.

Comments: Assume there are enough envelopes! 
                            
Step 2.

Actor Intention: The account holder enters the amount and selects a currency.

System Responsibility: The bank displays the converted amount by which the account balance will be credited.

Comments: -
                                       
Step 3.

Actor Intention: The account holder confirms that they wish to make the deposit.

System Responsibility: The bank opens the envelope drawer.

Comments: -
                                               
Step 4.

Actor Intention: The account holder puts their money into an evelope and posts the envelope into the tray.

System Responsibility: The bank closes the drawer and displays a new (tentative) balance, and issues a receipt. 

Comments: Habit: "deposit money and do accounting". The bank updates the account balance and writes a credit in the ledger.

James O Coplien

unread,
Jun 17, 2013, 5:02:17 PM6/17/13
to object-co...@googlegroups.com
Love it. Looks like a use case to me.


--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To unsubscribe from this group and stop receiving emails from it, send an email to object-composit...@googlegroups.com.

Matthew Browne

unread,
Jun 18, 2013, 1:00:49 AM6/18/13
to object-co...@googlegroups.com
Hi Ant, Jim, et al.,


On 6/17/13 12:00 PM, James O Coplien wrote:
Maybe we need more example use cases to accompany the internal use case examples. Is your observation any more than the lack of such examples?
I suppose I am mostly desiring more examples...I was also wanting to understand the role of internal use cases in the DCI design process in general. It seems we've now agreed that they're optional, especially given your comment:
I have always looked down on internal use cases as I've too often found them to be the nerds' revenge: pseudo-code with overkill. [...]
But they probably do have a place.
Perhaps an internal use case would be useful at least for the sake of discussion in this thread. Fortunately, Ant has provided us with a good "user goal"-level use case to serve as an example.

By the way, are "user goal"-level use cases the same thing as "business" use cases in the way you were using the term? I know that use cases can be used for other business processes besides software development so that's why I keep using the term "user goal"-level.

I drafted an internal use case for Ant's below use case. I'm not sure it's too low-level.... I'm also not sure if I've got the role behavior right, but that's the whole point of use cases, right? ...that you don't have to think through all the details in advance. Use cases are mainly for specifying requirements, and can always be revised later. So here goes:
~~~

Internal use case for "Deposit Money"

Primary external actor: Account Holder
The "internal actors" (AKA object roles) are italicized.

Main Success Scenario:
  1. The Account Holder selects an account for which they wish to deposit money.
  2. DestinationAccount returns the data necessary to display an account summary
  3. The Account Holder enters the amount and selects a currency.
  4. Cash returns the value of itself in the selected Currency
  5. The Account Holder confirms that they wish to make the deposit
  6. EnvelopeDrawer opens itself
  7. The Account Holder puts their money into an envelope and posts the envelope into the tray.
  8. EnvelopeDrawer closes itself
  9. DestinationAccount deposits Cash into itself -- Include "Deposit cash and do accounting"
  10. DestinationAccount returns the data necessary to display a receipt in the Account Holder's selected Currency

Habit: Deposit cash and do accounting
  1. DestinationAccount adds Cash's amount to its balance
  2. Because DestinationAccount is a cache over a collection of Ledger transactions, step 1 also causes a new entry to be added to the Ledgers collection.
~~~
What do you all think?

rune funch

unread,
Jun 18, 2013, 3:55:49 AM6/18/13
to object-co...@googlegroups.com
I personally see two roles or perhaps three roles
 
an account (plyed by a collection of ledger entries)
An amount (played by a Currency object)
 
or
 
an account
an amount (played by a decimal number)
a currency (played by a synbol)
 
I view the drawer to be external to the context since the amount of cash you deposit doesn't affect the flow. If we removed the user interaction of typing in the amount and assumed that the ATM counted the cash itself then the drawer is simply an input device.
 
That's how I see it when reading the use case.
 
-Rune
 
 


2013/6/18 Matthew Browne <mbro...@gmail.com>

Cevat Serkan Balek

unread,
Jun 18, 2013, 4:07:28 AM6/18/13
to Object Composition
Hello,

This is the excellent summary of the lateral paradigm shift in general and DCI in particular.

This will not be as clear as what Trygve said, but I feel that it will be better to cite the sentence below now:

To me, lateral means the ability to put or to bring forward the things (idea, code, design, etc.) at any levels without compromising the whole which will emerge stage by stage so that anyone who is interested will feel easy to enter into the feedback loop as early as possible: everybody, all together, all the time.   

Thanks Trygve...

Cheers,

Cevat




--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To unsubscribe from this group and stop receiving emails from it, send an email to object-composit...@googlegroups.com.

James O Coplien

unread,
Jun 18, 2013, 5:01:52 AM6/18/13
to object-co...@googlegroups.com
First of all: What Cevat said. Good insight.

Second: I think you might be looking for something that isn't there, something that provides a formal or traceable basis in use cases for DCI. Use cases are not a formal notation. Their purpose is to elicit dialog.

It is like we teach in Scrum: a Product Backlog Item isn't itself the requirement. It stands for the requirement. Its presence is a provocation to dialog.

Now, beyond that, use cases can be used to structure requirements. They can designate dependencies between them (build the basement before the walls) or refinement relationships (three-way-calling refines, and should be packaged together with, a plain line-to-line call). Use case is not Swedish for "scenario" (the word is "användarfall" ...) A use case like "phone call" might wrap all the scenarios for basic line-to-line call, for three-way-calling, for call forwarding, and so forth. The "Phone Call" use case comprises all of those together. Each one individually is a scenario (and each one individually could be a PBI in Scrum).

One can incrementally introduce scenarios to a use case, over time.

I typically use DCI Contexts to represent use cases: i.e., they are one closed copy of code that captures all scenarios. You will not anywhere find any mapping between the code and the structure of any one of the scenarios in a use case. In some sense, you need to do manual weaving of the scenarios into the code that implements the use case, much as you need to weave aspects into join points in AOP. The DCI approach is much more general and powerful than AOP in part because it lacks the very kind of formal mappings that you may be seeking.

The only reasons I distinguish between internal and external use cases is on the principle that Kay's objects represent mental models. I have a prejudice that the best use cases represent the prejudiced mental models of end users, in part because I've seen far too many computer scientists force their will and their mental models on end users. It shows through all the way to the user interface, and that's why so many interfaces are hard to use. (Just try putting a picture in the middle of a paragraph in Word, positioned right where you want it.) I used to fight Trygve on this, with me more advocating the end user and Trygve advocating the programmer, but Trygve used my own words against me, invoking the agile need for team dialog and thinking. These problems can be solved with dialog as one finds in the agile world: hence, the "everybody, all together, from early on" as a central tenet of DCI. As long as the programmers and the end users are in dialog and genuinely seek consensus (how Nordic...), I don't care about the difference between internal and external use cases. I want a single shared mental model wherein both the programmer and end user develop an appreciation for each other.

That can only happen if the Team is organized right, to facilitate the dialog. If use cases are thrown over an organizational wall with external use cases on one side and internal use cases on another, all is lost. That's why the two first patterns of the MVC architecture relate to domain analysis and to the organizational structure (http://heim.ifi.uio.no/trygver/2003/javazone-jaoo/MVC_pattern.pdf). It should be no different in DCI. DCI is the use case side of the coin; MVC is the domain visualization side of the same coin.

There is a point at which programmers have to reason about technical implementation stuff that is rarely of concern to the business, and which is common reusable logic, such as logging in. That's what habits are. Because they lack real context, they're not use cases. People use DCI for such things anyhow, but it's a bit dodgy to write general code for something intrinsically so uncontextualized.

Does that drive to the point you are wondering about?

(Writing this has been useful for organizing my thoughts and firming up my own thinking. Thanks.)



Ant Kutschera

unread,
Jun 18, 2013, 2:24:23 PM6/18/13
to object-co...@googlegroups.com
Kinda cool how we have three people (Rune, Matt and myself) making 4 suggestions :-)

I guess the phrase "everybody, all together, from early on" really is the solution to turning the ideas into one mental model.  It isn't the user's mental model, rather that of the stake holders (users, business people with money, analysts, architects, programmers, testers, etc.).

Also interesting (maybe): the roles which Rune identified are interesting, but I need to know which behaviours they would contain in order for my mental model to match his.  Can you provide that info Rune?

rune funch

unread,
Jun 18, 2013, 2:45:00 PM6/18/13
to object-co...@googlegroups.com
It would be something like this:

context :CashDeposit  do
  
 def initialize(account,amount,currency)
    @account = account
    @amount = amount
    @currency = currency
  end

  def converted_amount
    amount.to_GBP
  end

  def deposit
    account.deposit
  end

  role :amount do
    def to_GBP
      (currency.exchange_rate :GBP) * amount
    end
  end
 
 role :currency 
  role :account do
    def deposit
      amount_GBP = amount.to_GBP
      message = "Deposited #{amount} in #{currency} equalling #{amount_GBP} GBP"
      self.add message, amount_GBP
    end
  end
end


2013/6/18 Ant Kutschera <ant.ku...@gmail.com>
--

Matthew Browne

unread,
Jun 18, 2013, 10:20:02 PM6/18/13
to object-co...@googlegroups.com
Hi Trygve and Cevat,
Thanks for the excellent points.

Cevat, what are you citing exactly? Is "lateral paradigm" an existing term or did you just invent it to summarize some of Trygve's ideas?
You received this message because you are subscribed to a topic in the Google Groups "object-composition" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/object-composition/e6K7KhKkdnM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to object-composit...@googlegroups.com.

Matthew Browne

unread,
Jun 18, 2013, 10:21:14 PM6/18/13
to object-co...@googlegroups.com
Hi Jim,
Thanks for the very helpful explanation.

On 6/18/13 5:01 AM, James O Coplien wrote:
> I typically use DCI Contexts to represent use cases: i.e., they are
> one closed copy of code that captures all scenarios. You will not
> anywhere find any mapping between the code and the structure of any
> one of the scenarios in a use case. In some sense, you need to do
> manual weaving of the scenarios into the code that implements the use
> case, much as you need to weave aspects into join points in AOP.
I understand the need for this manual weaving of scenarios to support
logical branching. The only mapping I was seeking was for the roles, not
the exact sequence of a particular scenario.
> The DCI approach is much more general and powerful than AOP in part
> because it lacks the very kind of formal mappings that you may be seeking.
Originally I had said that analyzing roles is part of the art of DCI
programming and that some roles (the internal ones) aren't necessarily
going to be present in the use case description. Your earlier response
made me think I was missing an important part of the process:
> I strongly disagree. You can write a business use case and choose to be faithful to that. Or you can first write a business use case and then write what's called an "internal use case" whose actors are internal components (e.g., the artificial accountant role that was recently invoked here). Your DCI implementation can adhere to either, or both.
It was at this point that I started looking for a formal mapping for the
roles, because I thought that's what you were saying.

If the internal use cases are actually written down (in a role-oriented
way), then I agree that determining object roles from use cases is
straightforward. If, however, the use cases are only in the developers'
minds (not written down), as you seem to have suggested in your
subsequent posts, then it very well might not be straightforward - it
depends on the developers, the complexity of the use case, and the
number of possible interpretations of the roles.

James O Coplien

unread,
Jun 19, 2013, 4:55:53 AM6/19/13
to object-co...@googlegroups.com

On Jun 19, 2013, at 4:21 , Matthew Browne wrote:

> If the internal use cases are actually written down (in a role-oriented way), then I agree that determining object roles from use cases is straightforward. If, however, the use cases are only in the developers' minds (not written down), as you seem to have suggested in your subsequent posts, then it very well might not be straightforward - it depends on the developers, the complexity of the use case, and the number of possible interpretations of the roles.

Oh, use cases are written down. It's just that they are written (mostly) after the many-to-many discussions have taken place.

The written word has two roles in written endeavor: one, to communicate; the other, to remember. In agile development, we use the written word to remember — never to communicate. We distill the important decisions and agreements from the conversation: the things that are too detailed, or too numerous, to remember. The Agile Manifesto doesn't say to avoid documentation, but infers rather that we leave to human memory what should be left to human memory, and to write down what should be written down.

I can envision a style of development, supported by an appropriately expressive programming language, that uses the programming languages the way people use Use Cases today. The reason that won't work is because of the weaving. We still need use cases to highlight the individual scenarios, preconditions, postconditions, and other use case features.

Trygve Reenskaug

unread,
Jun 19, 2013, 5:40:47 AM6/19/13
to object-co...@googlegroups.com
Great input to help me clarify my own thoughts. Thank you, Jim. Comments inline.


On 2013.06.18 11:01, James O Coplien wrote:
First of all: What Cevat said. Good insight.

Second: I think you might be looking for something that isn't there, something that provides a formal or traceable basis in use cases for DCI. Use cases are not a formal notation. Their purpose is to elicit dialog.

It is like we teach in Scrum: a Product Backlog Item isn't itself the requirement. It stands for the requirement. Its presence is a provocation to dialog.

Now, beyond that, use cases can be used to structure requirements. They can designate dependencies between them (build the basement before the walls) or refinement relationships (three-way-calling refines, and should be packaged together with, a plain line-to-line call). Use case is not Swedish for "scenario" (the word is "användarfall" ...) A use case like "phone call" might wrap all the scenarios for basic line-to-line call, for three-way-calling, for call forwarding, and so forth. The "Phone Call" use case comprises all of those together. Each one individually is a scenario (and each one individually could be a PBI in Scrum).
A backlog item can ultimately become a history item.
A use case can be part of the resolution of a PBI?


One can incrementally introduce scenarios to a use case, over time.
Yes. One of the great advantages of the DCI programming paradigm.


I typically use DCI Contexts to represent use cases: i.e., they are one closed copy of code that captures all scenarios. You will not anywhere find any mapping between the code and the structure of any one of the scenarios in a use case. In some sense, you need to do manual weaving of the scenarios into the code that implements the use case, much as you need to weave aspects into join points in AOP. The DCI approach is much more general and powerful than AOP in part because it lacks the very kind of formal mappings that you may be seeking.
Represent use cases, not implement use cases?

one use case => one context? Is this an expression of a dogma? The roles of such a context would be the union of all the roles needed by all the system operations needed by all the scenarios. Do you rule out that a separation into several contexts could lead to more readable code?

In the DCI glossary, I say
"The terms related to the system’s handling of a Use Case are of special interest:
- Use Case 
- - Scenario 
- - - Command 
- - - - System Operation 
- - - - - Context
- - - - - -Role
- - - - - - - RoleMethod
"
I now read you to say that this is an over-simplification, there are no such simple relationships.
If that is so, I'm completely confused about how to go from use case to code and back to user mental model. I clearly need to re-read your book.


The only reasons I distinguish between internal and external use cases is on the principle that Kay's objects represent mental models. I have a prejudice that the best use cases represent the prejudiced mental models of end users, in part because I've seen far too many computer scientists force their will and their mental models on end users. It shows through all the way to the user interface, and that's why so many interfaces are hard to use. (Just try putting a picture in the middle of a paragraph in Word, positioned right where you want it.) I used to fight Trygve on this, with me more advocating the end user and Trygve advocating the programmer, but Trygve used my own words against me, invoking the agile need for team dialog and thinking. These problems can be solved with dialog as one finds in the agile world: hence, the "everybody, all together, from early on" as a central tenet of DCI. As long as the programmers and the end users are in dialog and genuinely seek consensus (how Nordic...), I don't care about the difference between internal and external use cases.
I fully agree that DCI is a good foundation for the end user's mental model and for the discussions in "everybody, all together, from early on"..
But IMO, DCI is more:
I see DCI as a paradigm for computing and insist that I shall be allowed to use it as such even if there are no end users in sight.
I have a vision of DCI becoming a lingua franca of computing, spanning any number of programming and modeling  languages.
A great advantage of DCI is that it is has been demonstrated to be a natural metamodel of  human mental models. This applies to end users, other stakeholders, programmers, game developers, composers, schoolchildren, etc.etc.

I want a single shared mental model wherein both the programmer and end user develop an appreciation for each other.
Agreed.

That can only happen if the Team is organized right, to facilitate the dialog. If use cases are thrown over an organizational wall with external use cases on one side and internal use cases on another, all is lost. That's why the two first patterns of the MVC architecture relate to domain analysis and to the organizational structure (http://heim.ifi.uio.no/trygver/2003/javazone-jaoo/MVC_pattern.pdf). It should be no different in DCI. DCI is the use case side of the coin; MVC is the domain visualization side of the same coin.

There is a point at which programmers have to reason about technical implementation stuff that is rarely of concern to the business, and which is common reusable logic, such as logging in. That's what habits are. Because they lack real context, they're not use cases. People use DCI for such things anyhow, but it's a bit dodgy to write general code for something intrinsically so uncontextualized.
Logging in with its authentication can be a very complex process involving the services of trusted sites etc. End users shall not and should not know this process, but somebody need to design and implement them  They too need  computer augmentation. Perhaps more than most because evil doers frequently seem to find holes in their protective walls.

Matthew Browne

unread,
Jun 19, 2013, 8:50:44 AM6/19/13
to object-co...@googlegroups.com
On 6/19/13 4:55 AM, James O Coplien wrote:
On Jun 19, 2013, at 4:21 , Matthew Browne wrote:

If the internal use cases are actually written down (in a role-oriented way), then I agree that determining object roles from use cases is straightforward. If, however, the use cases are only in the developers' minds (not written down), as you seem to have suggested in your subsequent posts, then it very well might not be straightforward - it depends on the developers, the complexity of the use case, and the number of possible interpretations of the roles.
Oh, use cases are written down. It's just that they are written (mostly) after the many-to-many discussions have taken place.
Even the internal use cases? When you said you generally avoid internal use cases, I thought that meant that they don't get written down, not even after those many discussions have taken place. I was only talking about whether or not internal use cases are written down- I accidentally omitted that word from my second sentence above; what I should have said was:
If, however, the internal use cases are only in the developers' minds (not written down)...

James O Coplien

unread,
Jun 19, 2013, 2:59:22 PM6/19/13
to object-co...@googlegroups.com, Alistair Cockburn, Bran Selic
On Jun 19, 2013, at 11:40 , Trygve Reenskaug wrote:

Now, beyond that, use cases can be used to structure requirements. They can designate dependencies between them (build the basement before the walls) or refinement relationships (three-way-calling refines, and should be packaged together with, a plain line-to-line call). Use case is not Swedish for "scenario" (the word is "användarfall" ...) A use case like "phone call" might wrap all the scenarios for basic line-to-line call, for three-way-calling, for call forwarding, and so forth. The "Phone Call" use case comprises all of those together. Each one individually is a scenario (and each one individually could be a PBI in Scrum).
A backlog item can ultimately become a history item.
A use case can be part of the resolution of a PBI?

What do you mean by: "history item"? I used to be big on keeping use cases around, and I've always advised people to do that. Gertrud used to do that, too, but found that people never really went back to the information they stashed away. I started noticing the same thing. So I don't admonish people to keep the stuff around. It's quite un-lean.

Formally, a use case is a way of organizing multiple scenarios (one scenario in the degenerate case) along with their "non-functional requirements" (NFRs). I usually think of an NFR or a scenario as being the thing that goes into a PBI, whereas a use case is the formalism used to manage, organize, or group scenarios. Use cases are still essentially scenario-based, so we could informally say that "a use case can be part of the resolution of a PBI."


One can incrementally introduce scenarios to a use case, over time.
Yes. One of the great advantages of the DCI programming paradigm.

This is a two-edged sword. I can't find a scenario in a Context: I can only find the current state of the use case, which may represent several scenarios and NFRs woven together.


I typically use DCI Contexts to represent use cases: i.e., they are one closed copy of code that captures all scenarios. You will not anywhere find any mapping between the code and the structure of any one of the scenarios in a use case. In some sense, you need to do manual weaving of the scenarios into the code that implements the use case, much as you need to weave aspects into join points in AOP. The DCI approach is much more general and powerful than AOP in part because it lacks the very kind of formal mappings that you may be seeking.
Represent use cases, not implement use cases?

Yes, that is much better said.


one use case => one context? Is this an expression of a dogma?

I hate dogmatæ in general, but this could be a useful dogma if dogmatæ exist... Read on.


The roles of such a context would be the union of all the roles needed by all the system operations needed by all the scenarios.

IN THAT CONTEXT. For example, if "Phone Call" is a use case — including party-to-party call, call forwarding, call waiting, and three-way calling — and if I use the above Dogma, then, yes: The Phone Call use case would have all roles for all three scenarios. That means that the Context would comprise roles including perhaps "Three-Way Conferencing Circuit." Perhaps that is unnatural. Then I would break it into three use cases, each with one scenario — IF one wanted to stand on formality and dogmatæ.

But, again, I want to emphasize: The input to a use case is understanding, and the output of a use case discussion is understanding. The output of understanding is code. The output of a use case is not a DCI Context — though the two are close enough to be both interesting and instructive. To violate the dogma would be an exception (as above), but the exception proves the rule.


Do you rule out that a separation into several contexts could lead to more readable code?

That is a delicious question and it depends heavily on the technology being used. Let's say that you had Magic AOP, which is unlikely, because not even Everyday AOP comes close to working. The AOP pundits would say that you could have one *scenario* per Context and then use cutpoints and joinpoints to manage the interference between them. That makes each scenario more readable in the context (sic.) of understanding the individual scenario, but it ALSO makes the system behavior (shades of the term "system operation") more opaque. That's where Aspects tend to fail. Remember that Adele said that in object orientation, "it" always happens somewhere else? In AOP it not only happens somewhere else, but you never quite know when that somewhere-else will hijack the program counter from you. With the current status of AOP technology, the single-scenario-per-Context dream is, I think, a dream.

There may be hope in more modern OO technology like multiple dispatch. There is something pattern-ish and regularizable about drawing a Shape on a Window, but the combinatorics get interesting when you have four kinds of shapes (nicely arranged in an inheritance hierarchy) drawing on multiple kinds of windows (ditto). I have a vague glimmer of hope that it's possible to separate scenarios into their own code modules in CLOS and manage the interaction between them with wrappers, whoppers and multi-methods, but I suspect it doesn't look very DCI-like any more. A good research topic.

In the DCI glossary, I say
"The terms related to the system’s handling of a Use Case are of special interest:
- Use Case 
- - Scenario 
- - - Command 
- - - - System Operation 
- - - - - Context
- - - - - -Role
- - - - - - - RoleMethod
"
I now read you to say that this is an over-simplification, there are no such simple relationships.
If that is so, I'm completely confused about how to go from use case to code and back to user mental model. I clearly need to re-read your book.

Maybe. I think we're about due for another tête-à-tête.


... I don't care about the difference between internal and external use cases.
I fully agree that DCI is a good foundation for the end user's mental model and for the discussions in "everybody, all together, from early on"..
But IMO, DCI is more:
I see DCI as a paradigm for computing and insist that I shall be allowed to use it as such even if there are no end users in sight.

No argument. And it is *a* paradigm for computing rather than *the* paradigm for computing. In fact, I'd say that procedural programming is the paradigm for computing. Ted Calhoun used to point out that computing is little of what we use computers for. I hate the old term "data processing" but I think it strikes somewhat closer to the mark than "computing."

I have a vision of DCI becoming a lingua franca of computing, spanning any number of programming and modeling  languages.

I'm skeptical. It is powerful and maybe even the dominant paradigm, but there are other paradigms. The very nature of a paradigm is that it denies the ability to be united with other paradigms by any lingua franca.


A great advantage of DCI is that it is has been demonstrated to be a natural metamodel of  human mental models. This applies to end users, other stakeholders, programmers, game developers, composers, schoolchildren, etc.etc.

Probably of most common human mental models related to objects. But there are others more related to values and functions that I wouldn't do this way. Use DCI to solve the quadratic formula.


There is a point at which programmers have to reason about technical implementation stuff that is rarely of concern to the business, and which is common reusable logic, such as logging in. That's what habits are. Because they lack real context, they're not use cases. People use DCI for such things anyhow, but it's a bit dodgy to write general code for something intrinsically so uncontextualized.
Logging in with its authentication can be a very complex process involving the services of trusted sites etc. End users shall not and should not know this process, but somebody need to design and implement them  They too need  computer augmentation. Perhaps more than most because evil doers frequently seem to find holes in their protective walls. 

No disagreement, and perhaps I should have chosen my words more carefully. First, I'm saying there are probably things that the programmers know that the Business Analyst doesn't need to know. However, there is something more sinister going on here as well. I am sure you log in to your bank via the web. I dare you to write a general login use case. When I log in to my bank, the login process is incremental and asks for additional information at different points in different transactions (different scenarios). Logging in has to be contextualized to the kind of transaction: it is different for deposits than for transfers than for balance inquiries. And the simplistic "logging in" authentication at the beginning is not reusable across different kinds of transactions, except as a non-value-added (more or less) preamble to lots of other authentication stuff. In most business contexts it wouldn't be a use case; its steps form a preamble to many other (contextualized) use cases. That reusable fragment, Gertrud and I call a "Habit."


Does that drive to the point you are wondering about?

We're certainly dancing around the right Maypole.


You received this message because you are subscribed to the Google Groups "object-composition" group.
To unsubscribe from this group and stop receiving emails from it, send an email to object-composit...@googlegroups.com.
To post to this group, send email to object-co...@googlegroups.com.
Visit this group at http://groups.google.com/group/object-composition.
For more options, visit https://groups.google.com/groups/opt_out.

(Bran, Alistair — I know you're not in this group but I'm happy to forward any of your response mails to the group, if you're interested. Or, of course, you can join the group.)

Trygve Reenskaug

unread,
Jun 27, 2013, 12:51:21 PM6/27/13
to object-co...@googlegroups.com, Alistair Cockburn, Bran Selic
Jim's original message in bold. Comments inline.


On 2013.06.19 20:59, James O Coplien wrote:
On Jun 19, 2013, at 11:40 , Trygve Reenskaug wrote:

Now, beyond that, use cases can be used to structure requirements. They can designate dependencies between them (build the basement before the walls) or refinement relationships (three-way-calling refines, and should be packaged together with, a plain line-to-line call). Use case is not Swedish for "scenario" (the word is "användarfall" ...) A use case like "phone call" might wrap all the scenarios for basic line-to-line call, for three-way-calling, for call forwarding, and so forth. The "Phone Call" use case comprises all of those together. Each one individually is a scenario (and each one individually could be a PBI in Scrum).
A backlog item can ultimately become a history item.
A use case can be part of the resolution of a PBI?

What do you mean by: "history item"? I used to be big on keeping use cases around, and I've always advised people to do that. Gertrud used to do that, too, but found that people never really went back to the information they stashed away. I started noticing the same thing. So I don't admonish people to keep the stuff around. It's quite un-lean.
future -> now -> past history
It's immaterial if you record the history or not - it always exists
"Those Who Fail to Learn from History Are Doomed to Repeat It" (Edmund Burke)

Formally, a use case is a way of organizing multiple scenarios (one scenario in the degenerate case) along with their "non-functional requirements" (NFRs). I usually think of an NFR or a scenario as being the thing that goes into a PBI, whereas a use case is the formalism used to manage, organize, or group scenarios. Use cases are still essentially scenario-based, so we could informally say that "a use case can be part of the resolution of a PBI."


One can incrementally introduce scenarios to a use case, over time.
Yes. One of the great advantages of the DCI programming paradigm.

This is a two-edged sword. I can't find a scenario in a Context: I can only find the current state of the use case, which may represent several scenarios and NFRs woven together.
Doesn't sound very simple. Is it explained in your book?



I typically use DCI Contexts to represent use cases: i.e., they are one closed copy of code that captures all scenarios. You will not anywhere find any mapping between the code and the structure of any one of the scenarios in a use case. In some sense, you need to do manual weaving of the scenarios into the code that implements the use case, much as you need to weave aspects into join points in AOP. The DCI approach is much more general and powerful than AOP in part because it lacks the very kind of formal mappings that you may be seeking.
Represent use cases, not implement use cases?

Yes, that is much better said.

one use case => one context? Is this an expression of a dogma?

I hate dogmatæ in general, but this could be a useful dogma if dogmatæ exist... Read on.

The roles of such a context would be the union of all the roles needed by all the system operations needed by all the scenarios.
IN THAT CONTEXT. For example, if "Phone Call" is a use case — including party-to-party call, call forwarding, call waiting, and three-way calling — and if I use the above Dogma, then, yes: The Phone Call use case would have all roles for all three scenarios. That means that the Context would comprise roles including perhaps "Three-Way Conferencing Circuit." Perhaps that is unnatural. Then I would break it into three use cases, each with one scenario — IF one wanted to stand on formality and dogmatæ.

But, again, I want to emphasize: The input to a use case is understanding, and the output of a use case discussion is understanding. The output of understanding is code. The output of a use case is not a DCI Context — though the two are close enough to be both interesting and instructive. To violate the dogma would be an exception (as above), but the exception proves the rule.
Do you rule out that a separation into several contexts could lead to more readable code?

That is a delicious question and it depends heavily on the technology being used. Let's say that you had Magic AOP, which is unlikely, because not even Everyday AOP comes close to working. The AOP pundits would say that you could have one *scenario* per Context and then use cutpoints and joinpoints to manage the interference between them. That makes each scenario more readable in the context (sic.) of understanding the individual scenario, but it ALSO makes the system behavior (shades of the term "system operation") more opaque. That's where Aspects tend to fail. Remember that Adele said that in object orientation, "it" always happens somewhere else? In AOP it not only happens somewhere else, but you never quite know when that somewhere-else will hijack the program counter from you. With the current status of AOP technology, the single-scenario-per-Context dream is, I think, a dream.

There may be hope in more modern OO technology like multiple dispatch. There is something pattern-ish and regularizable about drawing a Shape on a Window, but the combinatorics get interesting when you have four kinds of shapes (nicely arranged in an inheritance hierarchy) drawing on multiple kinds of windows (ditto). I have a vague glimmer of hope that it's possible to separate scenarios into their own code modules in CLOS and manage the interaction between them with wrappers, whoppers and multi-methods, but I suspect it doesn't look very DCI-like any more. A good research topic.
Do you rule out that a separation into several DCI contexts could lead to more readable code?

In the DCI glossary, I say
"The terms related to the system’s handling of a Use Case are of special interest:
- Use Case 
- - Scenario 
- - - Command 
- - - - System Operation 
- - - - - Context
- - - - - -Role
- - - - - - - RoleMethod
"
I now read you to say that this is an over-simplification, there are no such simple relationships.
If that is so, I'm completely confused about how to go from use case to code and back to user mental model. I clearly need to re-read your book.

Maybe. I think we're about due for another tête-à-tête.
Yes. Very much so. We need to discuss the relationships from use case to role method.  (After I have re-read the appropriate chapters in your book.)
Possibly also the consistency of the concepts described in my article (When the next draft is ready.)
There appears to be a many-to-many relationship between scenario and system operation, all within the single use case context? Sounds manageable.


... I don't care about the difference between internal and external use cases.
I fully agree that DCI is a good foundation for the end user's mental model and for the discussions in "everybody, all together, from early on"..
But IMO, DCI is more:
I see DCI as a paradigm for computing and insist that I shall be allowed to use it as such even if there are no end users in sight.

No argument. And it is *a* paradigm for computing rather than *the* paradigm for computing. In fact, I'd say that procedural programming is the paradigm for computing. Ted Calhoun used to point out that computing is little of what we use computers for. I hate the old term "data processing" but I think it strikes somewhat closer to the mark than "computing."
Webster: COMPUTE ()
intransitive verb
(1: to make calculation : reckon )
2: to use a computer


Wikipedia: Computing is any goal-oriented activity requiring, benefiting from, or creating computers
  1. My article is currently named : "DCI - The Metamodel of a Lingua Franca of Computing"
  2. I don't like 'Data processing'. It's too close to sorting cards and spinning tape reels IMO.
  3. ICT (Information and Communications Technology) is a popular term here. But I won't use it for two reasons: First, I deal with Data; the representation of information. Second, I don't like to single out communication  as being special; it is merely one of the three basic capabilities of computing: transforming, storing, and communicating data
People need to understand the nature of data as a representation of something. Also how computing capabilities are independent of what the data happens to represent.

I have a vision of DCI becoming a lingua franca of computing, spanning any number of programming and modeling  languages.

I'm skeptical. It is powerful and maybe even the dominant paradigm, but there are other paradigms. The very nature of a paradigm is that it denies the ability to be united with other paradigms by any lingua franca.
The lingua franca I'm thinking about is based on true object orientation. A true object is encapsulated. The inside is invisible from the outside and can be anything, including all the other paradigms you may be thinking about.  (The language for the methods of a particular class in Smalltalk-80 was SQL and the database could be considered within the instance encapsulation) All I need is that the top level is object oriented. You appear to be thinking of 'unified with' another paradigm? I'm thinking of subordination, 'containing'.


A great advantage of DCI is that it is has been demonstrated to be a natural metamodel of  human mental models. This applies to end users, other stakeholders, programmers, game developers, composers, schoolchildren, etc.etc.

Probably of most common human mental models related to objects. But there are others more related to values and functions that I wouldn't do this way. Use DCI to solve the quadratic formula.
It can be done in a method in the object that needs it. A simple example of data transformation.

There is a point at which programmers have to reason about technical implementation stuff that is rarely of concern to the business, and which is common reusable logic, such as logging in. That's what habits are. Because they lack real context, they're not use cases. People use DCI for such things anyhow, but it's a bit dodgy to write general code for something intrinsically so uncontextualized.
Logging in with its authentication can be a very complex process involving the services of trusted sites etc. End users shall not and should not know this process, but somebody need to design and implement them  They too need  computer augmentation. Perhaps more than most because evil doers frequently seem to find holes in their protective walls. 

No disagreement, and perhaps I should have chosen my words more carefully. First, I'm saying there are probably things that the programmers know that the Business Analyst doesn't need to know. However, there is something more sinister going on here as well. I am sure you log in to your bank via the web. I dare you to write a general login use case. When I log in to my bank, the login process is incremental and asks for additional information at different points in different transactions (different scenarios). Logging in has to be contextualized to the kind of transaction: it is different for deposits than for transfers than for balance inquiries. And the simplistic "logging in" authentication at the beginning is not reusable across different kinds of transactions, except as a non-value-added (more or less) preamble to lots of other authentication stuff. In most business contexts it wouldn't be a use case; its steps form a preamble to many other (contextualized) use cases. That reusable fragment, Gertrud and I call a "Habit."

We are here talking about the programmer's mental model, must I write a use case?

It seems that Danish netbanks are different from the Norwegian ones; the Norwegian authentication is always the same. There seems to be a state machine deeper down here. An item on my TO DO-list is to add an alternative way of implementing the DCI interaction algorithm using a state machine rather than the current sequential role methods. The context object is encapsulated, so I can't see why a state machine should pose a hard problem. (That may be because I haven't really looked into it). I could start with looking at Kent Beck and Ward Cunningham's  HotDraw to see how they did state machines in Smalltalk.


Does that drive to the point you are wondering about?

We're certainly dancing around the right Maypole.
Who's wandering about what? Jim, is it time to re-write the original mail so that we could see if we have made any progress?

James O Coplien

unread,
Jun 27, 2013, 4:18:50 PM6/27/13
to object-co...@googlegroups.com, Alistair Cockburn, Bran Selic

On Jun 27, 2013, at 6:51 , Trygve Reenskaug wrote:

Do you rule out that a separation into several DCI contexts could lead to more readable code?

Yes. This is the AOP problem or the Feature Interaction Problem.

Good use cases are relatively separable (a variation on the theme of coupling and cohesion). By their nature, scenarios within a use case rarely are separable. If you separate one scenario into each DCI Context, then you have the problem of how to make the Contexts interwork (in one execution thread!) AOP claims to be chasing this problem but in 18 years they haven't even established the premise that AOP could solve these problems, let alone show that they have solved these problems.

This problem also goes by the name: "The feature interaction problem." It's a wicked problem and is largely unsolved, in part because it is so hard to contextualize individual cases against a common formalism. See "A Version Model for Aspect Dependency Management" by Elke Pulvermüller, Andreas Speck and Jim Coplien, at https://3aec1b23-a-eadc3f87-s-sites.googlegroups.com/a/gertrudandcope.com/info/Publications/pulvermCACM01.pdf. (This is kind of interesting because of the ostensible relationship between DCI and SOP.)

James O Coplien

unread,
Jun 27, 2013, 4:24:03 PM6/27/13
to object-co...@googlegroups.com
I agree on learning from history, but we live in an oral culture. Very little of the true learning is transmitted in written form, and very little corporate memory is written. We don't have a tradition of using written history.

On Jun 27, 2013, at 6:51 , Trygve Reenskaug wrote:

future -> now -> past history
It's immaterial if you record the history or not - it always exists
"Those Who Fail to Learn from History Are Doomed to Repeat It" (Edmund Burke) 

Next time I come to your house and you tell one of the stories of something you learned along the way, then, I want you also to find it in a notebook or book on your bookshelf.

Even if it was there, finding it would be another matter....

:-)

Trygve Reenskaug

unread,
Jun 28, 2013, 3:18:37 AM6/28/13
to object-co...@googlegroups.com, Alistair Cockburn, Bran Selic
Thanks for the reference. It reminds me of Egil Andersen's doctoral thesis "Conceptual Modeling of Objects.  A Role Modeling Approach". He used state machines to model the behavior of role models. He then 'synthesized' two source models into one merged model where a role in the merged model played two source roles. (I'm just leaving for yet another week's holiday, so I haven't time to make this sentence readable). Anyway, the general conclusion was that knowing that the source models behaved properly didn't guarantee that the merged model behaved properly. My engineer's conclusion was that there were two safe ways of merging role models: Either do one of them at the time. Or do one as a subroutine in the other. Any other way of merging roles was highly dangerous and should be avoided. This may apply to DCI too. Any fancy way of mixing roles from two contexts is dangerous and should be avoided. May be this constraint can protect us against feature interaction, may be not. In my simple mind, I hope functional decomposition can help us avoid some dangerous pitfalls.
(http://folk.uio.no/trygver/1997/EgilAndersen/ConceptualModelingOO.pdf)
Reply all
Reply to author
Forward
0 new messages