DCI (data, context, interaction) is a new programming paradigm developed by Trygve Reenskaug, who two decades earlier first defined the now-ubiquitous model-view-controller paradigm. DCI aims to solve some problems with object-oriented programming by emphasizing the interaction between objects. In an article published on Artima, Reenskaug and James O. Coplien write that,
While objects capture structure well, they fail to capture system action. DCI is a vision to capture the end user cognitive model of roles and interactions between them... [DCI is] an architecture based on the object Data, the Collaborations between objects, and the way that Use Cases scenarios comprise Interactions between roles...
Object-oriented programming languages traditionally afford no way to capture collaborations between objects. They don't capture algorithms that flow over those collaborations. Like the domain structure captured by object instances, these collaborations and interactions also have structure. They form part of the end user mental model, but you can't find a cohesive representation of them in the code...
The fundamental problem solved by DCI is that people have two different models in their heads of a single, unified thing called an object. They have the what-the-system-is data model that supports thinking about a bank with its accounts, and the what-the-system-does algorithm model for transferring funds between accounts. Users recognize individual objects and their domain existence, but each object must also implement behaviors that come from the user's model of the interactions that tie it together with other objects through the roles it plays in a given Use Case...
DCI incisively solves some of the key issues when designing real-world enterprise systems, making such systems more flexible. While Reenskaug describes the key principles of DCI in great detail, he leaves few hints as to how to practically design a system following those principles. In a pair of blog posts, Implementing DCI in Qi4j and Contexts are the new objects, Rickard Öberg writes about his experience of actually implementing a DCI-inspired system.
When we went from procedural programming to object-oriented programming,
by realizing that we could remove the "object pointer" as the first
argument to a function, and instead went to a model where methods are
invoked on objects with identity, it fundamentally transformed our
ability to structure and reason about software. Now, with the
introduction of the DCI paradigm, I think that a similar change is
possible, by realizing that DCI contexts are to stateless services what
objects were to procedures...
One of the core ideas of DCI is that objects are not made up of single classes, i.e. POJO's, but instead use roles to compose functionality. To be specific, when I say "object" here it relates to Entities in DDD terms, rather than Values or anything else. In an enterprise architecture setting, with persistent data, it's mainly the entities that we want to split up into roles, where each role has a distinct purpose. In Qi4j [a framework designed by Öberg], these roles are implemented by Mixins. In Scala they would be termed Traits...
The key thing I want to achieve is readability of code, maintainability of code, and ease of change. If you instead work with a POJO approach, putting all the code for these roles into one class, that complicates all of the above. Once you get to a certain size of your project, having all code in one place will make it less readable, less maintainable, and harder to change. Much harder...
Another key benefit of doing things this way is that it really enables reuse on a whole new level. You can create roles, contexts and interactions that implement a particular usecase, and then reuse that over and over again in various parts of your domain model. Whether this is useful or not depends on the size and complexity of your project.
What do you think of DCI and of Öberg's description of his DCI-inspired design?
The big thing is that you can't possibly argue textual source code representation does a good job showing asynchronous vs. synchronous migrations between roles. The DCI folks encode this logic using actors, instead of a direct visual formalism.
> The big thing is that you can't possibly argue textual > source code representation does a good job showing > asynchronous vs. synchronous migrations between roles.
Can you explain why you say that? I'm not suggesting you are wrong it's just not obvious to me. It could also be that this statement makes me want to try to argue what you say can't be argued and that's distracting me.
IIIIIIIIIIIII don't know. This is April Fool's Day, after all, and the article referenced is more than a year old, with 115 (last count) replies. Totally hashed about back then.
I'll say (likely, repeat; but I'm not going to re-read all the replies) that DCI simply codifies what naive' OO folk have always done: built applications with Action objects and Data objects. Once again, read Holub's series on the Bank of Allen for how to build with real Objects. OO, done intelligently, is a magic bullet. Folks, who generally don't know any better, complain that there is an impedance mismatch between the OO world and the relational world, and so on. And there's always the issue with web frameworks, which were the major impetus for the Data/Action object bifurcation in the first place.
As to the notion that an Object isn't just one Class, well that argument ignores the Inheritance/Composition debate, and the conclusion that Composition is superior.
Ease of change comes from intelligent partitioning of behaviour, and, dare I say it, database design. With an intelligently defined database (BCNF, as a rule of thumb), identifying attributes don't change, so adding attributes is merely (in the SQL database world) adding columns. If you find that inadequate (you're constantly adding and removing columns from your primary key), then you're just not done designing. Man up and do your job and quit complaining that SQL/RM is inadequate.
"Composing" is merely referencing through foreign keys as new entities (tables or rows, depending on how you prefer to phrase it) are defined. Again, so long as you maintain primary identity, composing is easy, as is addition of attributes. We have a perfectly serviceable declarative semantic; it's just not from the hands of coders, but from the brain of a pretty decent mathematician. Use it.
The data drives applications (DCI, Data comes first, Yes???), not code. Coders??? We don't need no stinkin' coders!!!!!!
You're right, and Rickard's strange reply to Raoul Duke on his blog says it all: "@Raoul, DCI focus on getting the code to match the users mental model. If the mental model is a kitchen sink, then you are right. Otherwise, no."
Jim, on the DCI mailing list, has resorted to also explaining people should use "methodful roles" vs. "methodless roles" at times. Stuff that literally makes no sense.
And NONE of this methodology is actually compared systematically to any design methodology. Rickard keeps using the phrase POJOs, as if that means anything. What it appears he is railing against is using objects as components. Then why doesn't he say that? Then his InteractionContext is really about modeling a lambda expression with no free variables. In applicative programming, this is called a "combinator", and is the most mathematically precise definition of "component" you will find.
> > The big thing is that you can't possibly argue textual > > source code representation does a good job showing > > asynchronous vs. synchronous migrations between roles. > > Can you explain why you say that? I'm not suggesting you > are wrong it's just not obvious to me. It could also be > that this statement makes me want to try to argue what you > say can't be argued and that's distracting me.
There is a pretty famous, oft misunderstood, quote in object-oriented literature: "What is object oriented programming? My guess is that object oriented programming will be in the 1980's what structured programming was in the 1970's. Everyone will be in favor of it. Every manufacturer will promote his products as supporting it. Every manager will pay lip service to it. Every programmer will practice it (differently). And no one will know just what it is." Rentsch, the author of that quote, then goes on to say in the next paragraph: "Surely there's a better way. I hope this paper will clarify object oriented programming by characterizing its more important aspects."
Keep in mind Rentsch's original observerations were made in 1982. Coggins wrote about subject-oriented programming in 1992, around the same time as Wegner's original questions about interactive models of computation being of a strictly different computational class than those given by Turing Machines, recusive function theory, and the lambda calculus.
Sorry for being dense but I'm still not getting it. I'm going to rephrase my question in case it wasn't clear. I'm trying to understand why you say that text doesn't do a good job in the context of "asynchronous vs. synchronous migrations between roles". I suppose I assume you are advocating a diagrammatic approach and that could be incorrect.
I'm curious because I tend to prefer diagrams in many contexts but in the case of software, I've never seen a diagrammatic approach to system definition that was adequate on it's own.
Procedural programming never went away and it will never will. Object-oriented programming is the packaging of procedures together with the data they operate upon. Inside each method, the code is still as procedural as ever.
The terms 'procedural', 'object-oriented' and 'functional' do not represent different programming paradigms; they are simply different aspects of programming.
Any type of code written in object-oriented or functional approach is procedural, because tasks are split in steps and these steps are executed one after the other.
Any type of code that is packaged with its data is object-oriented.
Any type of code that can augmented at compile-time or run-time with other code is functional.
A programming language can be procedural, object-oriented and functional at the same time (LISP, C++, Haskell etc).
> Procedural programming never went away and it will never > will. Object-oriented programming is the packaging of > procedures together with the data they operate upon.
That's the theory, and if abided, would yield a different paradigm (and semantics). In practice, it isn't. OO coders more often than not make action objects which process data objects all of which ends up reading like a COBOL or FORTRAN program your grandfather wrote. Again, one can argue that since all of these languages ultimately run on (with a vanishingly small number of exceptions) plain vanilla Von Neumann cpu's, such languages have to conform to that architecture if they're to execute in reasonable time. Now that parallelism is replacing clock as the source of growth, we do need to recast "procedural" problems as concurrent ones. Not much luck with that so far.
> John- > > Sorry for being dense but I'm still not getting it. I'm > 'm going to rephrase my question in case it wasn't clear. > I'm trying to understand why you say that text doesn't do > o a good job in the context of "asynchronous vs. > synchronous migrations between roles". I suppose I assume > you are advocating a diagrammatic approach and that could > be incorrect. > > I'm curious because I tend to prefer diagrams in many > contexts but in the case of software, I've never seen a > diagrammatic approach to system definition that was > adequate on it's own.
I don't think you were being dense. Sometimes it is hard to communicate on a forum, since it is not always the ideal place for teaching broad concepts.
Bottom line: If you look at DCI, it is essentially enforcing temporal consistency through the arrangement of the Data, Context and Interaction. It hardwires sequences of collaborations. From a purely methodological standpoint, this is okay if and only if it is being used in a situation where you need role analysis, e.g. using the GoF State Pattern to represent how an object can migrate between roles. But to divide the problem domain so that each object always has the same order of collaboration with other objects is a reduction down to algorithms (a transformational viewpoint), rather than input/output automata sequences (an interactive viewpoint).
In modern programming languages like Scala, you represent roles using a statically typed language feature called Traits. Now the only remaining question for temporal consistency is whether you need an asynchronous vs. synchronous migration between roles. For traits, the asynchronously transition between roles, you pretty much need to encode that transition using an Actor.
As an aside: In the GoF book, their example is purely synchronous and also does not give a solution for parametric polymorphism, e.g. how a State pattern might interact with a Creational Pattern like one of the GoF factory patterns. A hot button here is that GoF was interviewed for a 15 year anniversary, and was asked what they would do to improve the book, and their feedback was shockingly bad: merely regrouping the patterns, rather than better demonstrating how they interact.
Just to be clear, I am saying that all the encoding you must do textually, as I described in the Scala language, is better communicated in visual chunks. Delimiting creation from behavior is much more obvious graphically, because they literally correspond to two different diagrams. For example, a structure diagram indicates collaboration, but it does not state what sequence that collaboration takes place in.
Rickard appears to be communicating that the overhead textually is the result of cleaner code. I am saying that he is kidding himself, because he is enforcing temporal consistency via guaranteeing sequential coupling.
As I remarked in the previous thread, this appears to be the result of (1) a revolt against inclusion polymorphism (2) a revolt against using objects as components.
From a programming language perspective, this seems to indicate programmers want (1) a degree of freedom between inheritance (code re-use) and OO generalization/specialization modeling (2) something with more degrees of freedom than inheritance for building components, such as Invasive Software Composition (which subsumes aspect-oriented programming).
> Procedural programming never went away and it will never > will. Object-oriented programming is the packaging of > procedures together with the data they operate upon. > Inside each method, the code is still as procedural as > ever.
Inside each sequential interface, the internal representation is manipulated by primitive operations known only to that representation.
Flat View: This topic has 27 replies
on 2 pages