Google Groups

FullOO (a.k.a. DCI) Summit in Oslo

Cope Aug 20, 2011 9:21 AM
Posted in group: object-composition
Cope went to visit Trygve for about three days in the beginning of August and, as usual, there was a lot of energetic discussion. In addition to the usual fun smoke and heat, some light also came out. Here are the major upshots of the week.

Abstraction Layers and the difference between Restricted and Full OO

Alan Kay coined the term "object orientation" and likened an object system to a system having thousands and thousands of computers all hooked together by a very fast network. That perspective grounds some of what follows here. Think of computer hardware as a programming API. It provides an abstraction layer. Trygve and Cope define an abstraction layer as a shared understanding of the essential behaviors of an object as seen from a client, while the details of the implementation are hidden. We want to follow the #1 rule of software design: no surprises. That implies that the hardware can't reach up into the software and do unexpected things. If the garbage collector leaks, then the hardware doesn't implement a good abstraction layer. It also implies that the software can't do things to the hardware. You can generalize this concept to layers of software, so the operating system also provides an abstraction layer. 

Trygve is now talking about "Restricted OO" — which is OO-as-we-knew-it-before-DCI with restrictions that makes the code readable. This in contrast to "Full OO" which DCI implements. Maybe there will be other ways to implement it, too. There is a simple but stunningly powerful difference between the two and we spent much collective effort on deepening our understanding of those perspectives. The difference is in the programmer's observation point.

Restricted OO

With Restricted OO, the programmer observes the system from the inside of an object. The class defines what the programmer can and cannot see. A programmer can see:
  • The state of an instance as defined by its class attributes.
  • What messages an instance can receive.
  • The methods that will be triggered by those messages.
  • The attributes that are changed by those methods
  • The messages that are and the types of the objects that will receive those messages.
There are many things the programmer cannot see by reading the class code. Examples:
  • The sender of a received message and the purpose of this message seen within a wider context.
  • The class  of the receiver of a message sent from an observed object. 
The reason for these limitations is that this receiver lives within an abstraction boundary. The programmer cannot know, at compile time, which behavior will be invoked at runtime – by design.  A programmer can understand the program behavior only in general terms.

This is an essential part of the "power" of object orientation.

Unrestricted programming with classes — which is OO-as-we-knew-it-before-DCI – can lead to unreadable spaghetti code. We call it  “Unrestricted OO”.

We spent quite some time discussing the restrictions needed to get readable code. It appeared to have something to do with the abstraction boundary between a client and the inside of an object. Perhaps it would be illegal for an execution to cross back up across the boundary to do unpredictable things to the client. We did not conclude and the work continues. The result shall be a rule that is the “restricted” in Restricted OO. We hope that Unrestricted OO some time in the future will be relegated to history.

Full OO

With Full OO, the programmer observes the system from the space between the objects. Programmers can see several objects at once and observe the interaction messages that flow between them. They can’t see inside the objects because each lives behind its own abstraction layer boundary. They can't even know, at compile time, which behavior would be invoked at run time — by design.

DCI implements system behavior by pulling together the behavior of a system operation into several co-located roles, each representing an object. The programmer can see the roles together and reason about their end-to-end behavior. The system behavior is explicitly given by the RoleMethods that are outside any abstraction boundary. There is still an abstraction barrier: between the roles and the objects that play those roles. This barrier has the usual restriction: The object implementation can't reach up into the Interaction and do unexpected things. However, it is a very narrow abstraction layer whose operations should be viewed as primitive, and which, by design, always return. To be able to reason across a sequence of mutually invoking roles means to be able to reason about several objects at once.

Define a compression as a way to represent that information in fewer bits of data than the amount of information it contains, using contextual knowledge that makes it possible to losslessly expand that representation into the original information. In Restricted OO, a programmer cannot compress the understanding of anything: everything is an abstraction, except the current method. There is a large lack of contextualization. In Full OO, RoleMethods are compressions.

In DCI terms: Data classes are coded with Restricted OO. Interactions are coded with Full OO.

Restricted OO is very much like the Atomic Event Architecture of the Lean Architecture book (e.g., a traditional "shapes" OO program, with very simple operations); Full OO is like DCI.

We spent a lot of energy and time on these concepts and feel they will prove useful when worked out in detail.


We had a few discussions about handoffs. In Lean architecture, you want to avoid handoffs, so there should be no major (human) communication boundary between Context code and Data code. This means that the writer of the code for a Context with its roles and role methods should cooperate closely with the writer of the associated Data classes to adapt the abstractions to the needs of the system as a whole.

On the other hand, there are abstractions within abstractions and the transparency of the abstractions are reduced down the abstraction hierarchy. (There is no hard-and-fast rule; the developers of the first Smalltalk runtime system created private microcode for their Alto computer to optimize their system). Theoreticians will claim that any interface to an object must be supported by precise definitions of its operations with preconditions, postconditions etc.

In some sense, the whole purpose behind the DCI encapsulation of roles is that they are all in one place where they can be considered together without going across an abstraction boundary. But with a role method saying self–>something, we cross an abstraction boundary and must rely on it being implemented correctly. (Otherwise, the code of the RoleMethod would be unreadable).

Abstraction boundaries, therefore, are an agreement based on mutual trust. They are maybe a way of encapsulating change at some level. But that isn't a reason to really "hide" the changes. Everybody, all together, from early on — on everything.

So abstraction boundaries, rather than being viewed as "don't look here" fences, draw attention as key points of agreement around crucial architectural issues that the abstraction boundaries bring into focus.

Context / Role Integration

We agreed it would be a good idea if every Context could play some kind of Context role. That would make it possible to view the Context as a role from inside itself, and as an ordinary object from outside itself, thereby providing a smoother impedance match across the Context abstraction layer boundary. The Context could be a repository for state common to the whole interaction and visible to  RoleMethods through its role name, standardized at e.g., CurrentContext. This idea needs more work. For example an implementation — the true killer of good ideas.

DCI and Systems Complexity

We talked a little about simple, complicated, complex and chaotic systems (Snowden's taxonomy). DCI is interesting because it can implement an adaptive system. It responds to changes in its environment, implementing an open system that has a degree of self-organization. While Restricted OO systems are also open systems, they aren't adaptive.

DCI does this by effectively implementing a weak form of reflection.


Trygve gave Cope comments on his Elephant article, first suggesting that it be re-written from scratch with more precisely defined concepts. He has later withdrawn the suggestion since he realized that the entertainment value of the current form would be lost with very little gain. Cope continues to refine the article, and won't do a major upheaval.

Web Site

We have bought on a Norwegian web hosting site. Cope is supposed to set that up but is a bit lost right now, partly because their setup is a bit mysterious. (They already sold us and after a week of not being able to make it work they admitted a bug in their system that allowed them to sell us a URL that had previously been allocated to someone else.) The main issue seems to be that though he purchased a URL and 8 gigabytes of storage, we still don't appear to have anything with an IP address. There is something wrong with the hosting site. Trygve will  phone them (in Norwegian) and expect they'll fix the problem quickly. Then we can get down to the much wanted Q&A section and collect other material that should go to the site.