The Architect´s Napkin

Software Architecture on the Back of a Napkin
posts - 69 , comments - 229 , trackbacks - 0

My Links

News

Archives

Post Categories

Flows – Visualizing the Messaging Programming Model

Object orientation was ment to be based on messaging – at least if you follow Alan Kay. But that´s not really how it turned out to be, I´d say. Today´s mainstream OO languages are far from being “message-oriented”; they focus on objects as aggregates of data and functionality. Like in the old times of procedural languages it´s all about subprograms calling each other in deep dependency hierarchies. It´s about clients and services, requests and responses.

But messaging is different, as I tried to explain in my previous article. With messaging there is only one-way communication. Messages flow from senders to receivers. Procedures are a better way to express this than functions.

As long as we´re only able to talk about messaging using programming languages, we´ll have a hard time to reap its benefits. We´ll get bogged down by language idiosyncrasies and traditional OO suggestions inherent in OO languages. We won´t see the forest for the trees.

Steve Bate for example talked about his experience with messaging and used a particular implementation. Wouldn´t it be sad if someone got turned off by that, just because he didn´t like Steve´s pipeline implementation?

I guess, it would be beneficial to separate the concept from the languages. Then we could talk about its pros and cons without misunderstanding due to different backgrounds in platform.

That´s why I´d like to suggest a very simple notation to describe messaging solutions. For a start it just consists of just two symbols: boxes and arrows.

image

A functional unit is the receiver and/or sender of messages. And messages flow between functional units in the direction of arrows. (x) and (y) denote messages of different data or even data type.

That´s it, I´d say. We don´t need more. But the devil is in the detail ;-) It´s the limitation to arrows which makes the essential difference between today´s variant of OO and “object orientation as it was ment” based on messaging.

Look at this code from Steve´s article:

var loginPipeline = new PipeLine<LogInMessage>();

loginPipeline.Register(msg => new CheckUserSuppliedCredentials(msg))

             .Register(msg => new CheckApiKeyIsEnabledForClient(msg))

             .Register(msg => new IsUserLoginAllowed(msg))

             .Register(msg => new ValidateAgainstMembershipApi(msg))

             .Register(msg => new GetUserDetails(msg));

Using the above notation it can be expressed independently of any platform like this:

 

image

 

Easy to read, isn´t it? Even easier than the code. And that´s the point: a visual model of what´s supposed to happen in a program is easier to read and easier to communicate and easier to change than our textual program code overloaded with details.

Of course, this notation is no invention of mine. It´s so simple, it´s just natural. Or – if you like – you can find something alike in UML: activity diagrams. But I try to keep things simple for every day use. That´s why I´m not a big fan of UML. Please pardon my non-conformism – as long as what you see is easy to understand.

If Steve would use such a notation before coding, it would be easier for him to talk with his colleagues about his idea of a solution for a particular problem, I guess. And he would not attach himself or his colleagues to a certain way of implementing such a design. He could do it like shown above – or he could do it like this:

var msg = new LogInMessage();

msg = CheckUserSuppliedCredentials(msg);

msg = CheckAPIKeyIsEnabledForClient(msg);

IsUserLoginAllowed(msg,  _ => {

  msg = ValidateAgainstMembershipAPI(_);

  GetUserDetails(msg);

});

As long as there exists a clear and simple translation rule for the notation into code, all´s fine. Bubbles might not crash – but that´s not important. If we are able to translate notational bubbles into code which reflects the original bubbly design, then we can let it crash to give us feedback on our design. It will be easy to carry it back to the drawing board.

And of course we need to distinguish between crashes due to bad design on the level of bubbles and crashes originating from implementation mistakes. I believe the latter are far more common. So if software doesn´t work don´t blame it on the bubbles ;-)

Basing software on messaging creates flows. That´s what I call the arrow-linked sequences of functional units. Messages are flowing through processing steps to be transformed from some input into some output.

And now for the fun part: If we free ourselves from particular programming languages while designing messaging graphs aka flows, then we can come up with patterns like this kind of functional unit:

image

How do you translate multiple inputs/outputs into code? Do messages arrive on multiple inputs at the same time? Do they leave from outputs at the same time? How many output messages are created for each input message? That´s questions arising from such messaging designs – and it´s not important to know the implementation right away. The implementation is not that important. It´s too much detail while pondering a solution structure. It´s enough to know, all answers/patterns can be translated into code in a straightforward manner. For example:

  • Multiple outputs could be implemented as returning a tuple from a function or as continuations passed to a function or as events on an object.
  • Multiple inputs could be implemented as several parameters of a subroutine or as several subroutines on a class.
  • Several outputs for an input could be implemented as lists of data sent on as a single message or as several messages.

Messaging sure is different from how we´re doing OOP today. But being different does not mean worse. Faced with huge brownfield problems this difference could mean better. We just need to try it out. How does testability, evolvability, or production efficiency change, if we adopt a different thinking and implementation style?

Could digging up the roots of OO in messaging help us with today´s software maintenance problems? I think so. But we shouldn´t fall into the language trap again. Programming languages are secondary. Source code is secondary. Before source code in concrete languages come concepts and models. We need to be able to express our solutions in other terms than source code. Only by using visualizing our solutions in language independent ways we can harvest the collective intelligence of teams. That´s why I find it so important to have a visual notation for messaging as a programming model.

Print | posted on Sunday, August 18, 2013 2:35 PM | Filed Under [ OOP as if you meant it ]

Feedback

No comments posted yet.
Post A Comment
Title:
Name:
Email:
Comment:
Verification:
 

Powered by: