The Architect´s Napkin

.NET Software Architecture on the Back of a Napkin

  Home  |   Contact  |   Syndication    |   Login
  9 Posts | 0 Stories | 31 Comments | 0 Trackbacks

News

Archives

Post Categories

Monday, July 07, 2008 #

I´ve talked about what software cells are - asynchronous "islands" of code on several levels of abstraction -, and I showed you how easy they make it for you to place (business) logic where it´s most appropriate. Software cells - to me - are the structural elements for modelling an application in the large. If you´re faced with a modelling problem, don´t fear the blank flipchart! Just start with a single software cell comprising the whole of your application and do a stepwise decomposition. The goal of this first phase is to determine just functional responsibilities that can and should be executed in parallel. Most importantly that´s the processes of any application. But don´t stop there! There´s potential for parallel processing within (!) many processes. You should try to tap into it because that way you can make your application more responsive and scale better.

So far I´ve primarily covered the very nature of software cells and the meaning of their "interior". What´s missing is a discussion of their environment. A software cell is just a piece of code that needs to be triggered and which (mostly) relies on some resources.

image

When you start out modelling an application what you´re most interested in is determining the "parties" relevant to a software cell which you don´t have any control over. You want to know who´s using an application and what kind of resources the application is going to use. The former I call actors, the latter are, well, resources.

Actors are active, they use a software cell, they control its functions. That´s why the arrow is pointing from the actors to the software cell. Although the term "actor" might hint at humans being actors, in fact any "entity" which has the ability to trigger functions in a software cell can be an actor. Of course users (or user roles) are modelled as actors, but also an SAP system or some other application can be an actor. Whenever you do not add any code to a controlling "entity" it´s an actor.

image

On the other hand your application (or any software cell) is not only acted upon but also acts itself upon "entities". Those entities I call resources. They are passive with regard to a software cell. But not only files can be resources. Also other programs - again like an SAP system - can be resources. Whenever you do not add any code to a controlled "entity" it´s a resource.

image

Actors and resources can be introduced on any level of abstraction while modelling the nested software cell hierarchy. However, in the end, they should be visible on all levels. It needs to be clear, which actor uses which software cell, and which software cell uses which resource.

The arrows in the above pictures show control flow. The entity where and arrow starts controls the entity the arrow is pointing to. Data flow, however, is in both directions. An actor triggers some function on a software cell thereby sending it data. Later the software cell returns some result to the actor.

image

In addition to actors and resources software cells can be the entities using other software cells or they can be used by others.

image

The environment of a software cell thus consists of actors, resources, as well as other software cells. Whatever entity the logic core of a software cell is communicating with via an API (e.g. ADO.NET, System.Net, System.IO, System.Windows.Forms) belongs to its environment. Think of the membrane of the software cell as a placeholder for all such APIs. They stand between the logic of one software cell and another. And they decouple a software cell from humans or other software.

image


Sunday, June 22, 2008 #

During the first phase of architecting a software you try to break up the "application blob" in OS processes. They are the corner stones of any application. You can view them as large software components: usually they are binary, they are defined by explicit or visual contracts, they are units of deployment and maybe even re-use.

image 

Because identifying the OS processes in your application is so important, I might have emphazised the notion of a software cell being an OS process a bit too much. You might have gotten the impression, software cells in the end are nothing but OS processes. But that´s not what I mean. Really. It´s just that software cells are most often used to depict an OS process.

So let me try a more formal definition of what I think a software cell is:

A software cell is a unit of code - logically or physicall - which operates asynchronously with regard to other units of code.

This clearly is true for an OS process. It runs on its own thread or even its own machine. And so it is also true for an aggregation of processes, e.g. a whole application or a service. They run on one or more threads dedicated to them.

However, I see a process as a physically separate unit of code, whereas a whole application is more like a logical unit of code, since it´s not one "thing" you can put your finger on. Instead it´s distributed across several physical "things" (OS processes, machines etc.). But you can draw a circle around several processes thereby aggregating several units of code into a higher level unit of code and call them an application.

image

But what about smaller units of code, smaller than an OS process? They can be software cells, too. A single OS process software cell can contain/host/consist of several in-process software cells. I call them active components or worker components or async components. (More of components in future postings.)

The software cell hierarchy thus extends from the very large to the pretty small, from cross-process to in-process.

image

Now, although a service is different from an active component which in turn is not the same as an OS process, they all share one characteristic: the run in parallel with other software cells on the same level. That´s what I find important to express across all levels of abstraction.

Why is that important? Because communication between parallel units of code is so different from synchronous units of code. Synchronous sequential processing within a software cell uses the stack and therefore is secure, fast, reliable etc. Asynchronous units of code on the other hand cannot communicate via a stack. They need some other means which always is an indirection of some kind. That makes async communication much slower than sync communication (up 3 orders of magnitude and more). And often it also makes communication less reliable and less secure etc. With async communication the "Fallacies of Distributed Computing" kick in. It´s because of them that I find it so important to be so conscious about where async units of code are in an architecture. That´s why I devote a whole concept with its own visual notation to this. Software cells are supposed to protect your thinking from slipping into one or more of the fallacies.

Software cells run on their own threads. Software cells thus need to communicate with their environment through some medium. This can be an in-proc queue, or some other form of shared memory, or a database, or a TCP connection, or the Windows message pump. You name it.

image

Whenever you see a relationship between two software cells you immediately know it´s a simplyfication. In reality any communication between the software cells is not direct, but mediated. So medium or even infrastructure necessarily sits between them. Like a stack between two synchronous methods, but much slower.

This has some implications. Whenever you draw a software cell you need to ask yourself a couple of questions. Here are some that come to my mind right away:

  • How is the software cell started and stopped?
  • Can the software cell be paused or interrupted?
  • How are processing failures reported to the environment of the software cell?
  • How should data be passed into and out of the software cell?
  • How is shared data protected from inconsistencies through concurrent access by several software cells?
  • How can I be informed of certain states during a process executed by a software cell?
  • How can I know if a software cell is still alive and progressing?
  • How fast, reliable, secure etc. is a software cell and a connection to it?
  • Does it matter to a client of a software cell, where and if the software cell is running?

Some of these questions relate directly to the above fallacies. But there are more that need to be answered. Especially you need to ponder how the communication between a software cell and its environment should take place.

For in-process software cells (active components) you might just use a Queue<T> - with some synchronization code added. For two OS process software cells, though, you´d need to switch to TCP sockets or MSMQ or WCF. Or you use the file system as a medium: one software cell could create and write a file, the other could react on that and read the file.

And there´s one more twist to active components: they are running inside an OS process and so you should decide if they should be hosted inside a special AppDomain. It´s like deciding whether two OS process software cells should run on the same machine or not.

image

As you can see, co-locating or not is an issue you have to decide on, too, at every level of abstraction in your architecture.

Think of software cells as islands with their own population. The people living on an island happly work on some tasks - at their own speed.

image

You can communicate with them, e.g. by sending a message in a bottle or calling them via sattelite or dropping something from a plane. The islands can be located close to each other in the same sea or exist far apart in different oceans. Most importantly they all work pretty autonomously on their own threads.

image

What´s the benefit of all this?

  1. Thinking in terms of async units of code on several levels of abstraction makes you very conscious with regard to the costs and means of distribution.
  2. As long as you model your applications with software cells you keep it flexible with regard to the topology. Software cells can be moved around between processes and machines etc. comparatively easily. This is due to the explicit medium always used to communicate between them. It naturally decouples them.
  3. Since software cells are basically distributable units of code (remember: always indirect communication through some medium), you get a head start in terms of scalability. A software cell can be "multiplied" pretty easily to compensate higher load. Asynchronous processing is main road to scalability, not faster processors. Software cells make scale-out easier.

Tuesday, June 17, 2008 #

The main concern of software cells is how business logic is distributed. But as I write "business logic" I don´t really feel comfortable. The term sounds as if software cells were just a tool to help modelling business applications - as opposed to games or compilers or infrastructure. But right to the contrary: software cells claim to be a universal meta model for software. You can model any software with them. That´s why I don´t like to use the term "business logic". I prefer the neutral and unqualified term "logic".

So at the core of a software cell is logic code as opposed to technical or infrastructural code. If you like, qualify logic with "business" or "domain" or "application". But in the end it´s only important that the logic code, the core code is not concerned with technical details. It should not directly call, for example, a communication or persistence API. But more of this separation of concerns in another posting.

When thinking of logic, think of all that which is not dependent on a certain way of accessing this code or storing data or comunication with other software. Think of the invariant code that is independent of such "interface details" - whereas "interface" means interfacing with other software cells or infrastructure or resources or humans.

image 

If you think of a prime calculation application, what would such invariant code be? Well, for example the prime calculation algorithm. You need it regardless of whether the primes are displayed on a web page or in a desktop client; you need it regardless of whether the primes are send to another program via TCP or stored in a flat file for later import into Excel.

Ok, so at the heart of the software cell concept is application logic. At the core of any software cell is logic code. It´s the code that solves the problem the whole application is about in the first place.

Now you might say, that´s not much different from what you have thought of N-tier business logic all along - and I can´t but agree.

However - and this to me is an important however -, the N-tier architectural model pretty much confines the logic to one OS process. If you´re talking about a 3-tier application you mean 3 OS processes with (all) the colorful (business) logic residing in the middle tier process:

 image

That might have been ok in the mid 1990s. Back then distribution of code was not that easy with either socket or DCOM communication. And it seemed less often necessary than today. Client/Server architectures were the norm, N-tier architectures seemed to solve the scalability problem of internet applications, and that was pretty much it.

But today... today communication is much, much easier. Web services, .NET Remoting and Enterprise Services are simple to use RPC technologies. Even socket programming is no longer a black art with the System.IO and System.Net namespaces. And WCF is here to change the very paradigm of distributed communication by providing a neat unified message oriented API.

This in turn makes distribution easier. Setting up an application to consist of several very different "presentation tiers" and several "middle tiers" and several "backend tiers" all serving different purposes and maybe communicating in a P2P manner with other similar "tiers" is becoming the norm. That´s why I don´t see the term "tier" for an application´s OS process to fit anymore. For certain architectures it´s ok to use - but to let your modelling process be guided by it, seems limiting. Take off the "N-tier glasses"! And in terms of the pre-trans-fallacy enter the trans level: go beyond the slavish adherence to the N-tier "rule"! Set yourself free to think in different, more flexible terms. That´s what software cells are all about. Think cells instead of tiers.

What does that mean for your logic code? Well, it means, it should be able to move freely among the topology of an application. The meta model of software should allow logic to exist at any place an architect sees fit. That´s what software cells are about. They allow you to model OS process topologies and more to fit a problem and not a pattern. And they allow you to put logic in any place you like.

When you start a project, though, all application logic sits in one place: in the one and only all encompassing single software cell representing your entire solution:

 image

imageThis single logic core contains all the logic code your application needs - despite you not knowing what this code will look like in detail. You just take it as a black box, or a black box made up of several parts or aspects. Each being a different, (sooner or later) clearly distinguishable responsibility.

But that´s just the start. Sooner or later you´ll want to decompose the initial single software cell into 2 or 3 software cells. That means - to come back to the biological cell analogy - you cause a cell division. Whereas biological mitosis creates two clones, though, software cell division creates two or more software cells that look different. And that´s the whole point when distributing logic in this manner: the logic in the original cell should be split up. Parts of it go into one of the "child cells", other parts go into other "child cells".

image

image image  image image

image

The reverse is also possible: you might look at a software cell diagram and decide to merge software cells into one. Either physically, i.e. reduce the number of OS processes by aggregating logic from two or more processes in just one. Or logically by wrapping software cells in a software cell on a higher level of abstraction. This happens most often when you try to depict legacy systems with software cell diagrams. There already exist several OS processes and you need to describe the status-quo in a more coarse grained way to management.

Decomposition and aggregation might be the most common operations on software cells and their logic cores. But there´s yet another transformation you can apply: you can of course move logic from one software cell to another.

image

Although this might sound and look a bit abstract to you right now, I assure you, it has great practical value. This value lies in eliminating any cognitive dissonance stemming from conflicts when trying to find the right place for business logic according to the canonical N-tier architecture pattern. This value lies in freeing your thinking about architecture. The pain when trying to fit your solution to the N-tier model might seem weak - but I argue, it´s there and it´s not weak, but only subdued or even denied. So once you look for it in yourself or your peers, you´ll realize its prevalence.

I´m not against layers as a pattern. They have their place and I´ll talk about them in due course. But layers and tiers as other patterns should not be the starting point of your thinking. Or at least, don´t believe them to be the ultimative truth.

If you want to use layers, use them as a structuring pattern for something. Don´t just draw layered boxes. Rather plan a structure and then (!) arrange it in layers. See layers/tiers as superimpositions over an architecture, but not as the architecture itself or its goal:

image 

The stuff to arrange, the structural elements , that´s software cells with their logic. They are the material to build architectures from in the large. Why? Because they give you maximum freedom in arranging the most important part of any software: the logic.


Saturday, June 14, 2008 #

You know how that is when you start to immerse yourself into some new subject and all around you related stuff suddenly seems to sprout and blossom. Stuff you had never seen before and you doubt, existed before.

This is happening to me right now. Until a couple of days ago, I was not much concerned with napkins. Pretty much they were below my concious radar. I used them when appropriate, but otherwise gave them not much thought. Except maybe for not liking napkins out of real fabric much. They are stiff and lack absorptive capacity.

image Anyway, now that I´ve read Dan Roams book and started this blog, napkins seem to be all over. Not only have star architects been asked to confine themselves to sketches just on napkins. Napkins since have transcended their typical use at tables and become veritable creativity tools:

image

source: http://www.tranism.com/weblog/2007/11/napkin_notebook.html

Cool, isn´t it. I´d love to order a couple of these notebooks, which surely are excellent software architecture tools. Who would still want to use Rational Rose or Visual Studio Team System Architect Edition, if one has such a powerful and flexible tool at one´s disposal?

Unfortunately, as it seems, I´d need to travel to New York to buy such notebooks. They are on sale only at the MoMa.

Until then, though, I can use the only version of this tool:

image

source: http://www.napkinnotebook.com/

And it´s for free!

IBM and Microsoft: when will you bring software architectural drawing at our finger tips like this?


Friday, June 13, 2008 #

Software cells to me are the basic building blocks of software in the large. Don´t think in smaller terms as a software architect - at least at first. Keep your planning on the process level or above, e.g. on the service level. Services - as in SOA - can be depicted as software cells, too. You can think of a service as a composite consisting of several smaller software cells.

As peel away the layers of your software system, your application starting from the top, i.e the whole application...

image

...you get to the layer of services...

image

...which you can drill down into to get to the actual OS processes constituting these services:

image

(Please notice, how a service from the previous/higher level has become an OS process on this level. That´s because the service just needs one OS process. No further refinement was needed.)

Software cells thus lend themselves not only to planning a single application, but also to think in SOA terms. Which brings me to the question: what is it, that makes a software cell a software cell? Why the similarity to biological cells? Why didn´t I choose another analogy?

At the core of the cell analogy is, well, the core. A core of something sitting in the middle of an area surrounded by a wall.

Let me explain the genesis of this analogy: It was in 2005, I guess, during a vacation in beautiful Ireland, when I toyed around with software architecture depictions. I was pretty much in a trance the whole time - much to the grief of my girlfriend. The driving force behind my thinking was distress with the architectural layer pattern. Layered architectures or N-tier architectures seemed inflexible and misleading to me.

First of all, they suggest a certain direction of development. You´re either a person who likes to start with the tangible and visual, so you emphasize the presentation layer. That where you feel comfortable. So you work yourself from there down to the invisible parts you might be so sure about anymore. Or you´re a person who likes to lay a solid foundation. So you start at the backend, the data access layer and work your way up to the frontend.

image

Either way what´s kind of left out by these "processes" is the most important part of any application: its busines logic. Although the literature always underlines its importances, this message often does not materialize in project reality which is driven by one of the personality types just described. This is because the layer pattern does not favor any layer. All layers are created equal, so to speak.

So my first approach to improving the architectural pattern/symbol situation was to morph the layer pattern into a "burger pattern":

image

It changes the importance and the priority in favor of the business logic. That´s where the meat (!) is of an application. That´s the area you should flesh (!) out first. Business logic should be developed in a way as to be pretty invariant with regard to how it is access from any frontend or what kind of backend it uses to retrieve/store data. Frontend technologies change all the time, so do backends. Yesterday we used ADO.NET, today it´s some O/R Mapper, tomorrow it might be an only storage service like Amazon´s S3 or SimpleDB. Would you want to modify the business logic along with those changes? No, I don´t think so. That´s why it´s more important to think about it first, to put it in the center of your planning.

Then I played around with those "burgers" (even though my mother used to tell me, "Don´t play with your food!").  Here´s what a multi-layer application looks like:

image

And here´s an N-tier application:

image

But wait, isn´t that the same picture as for a multi-layer software? Yes. The reason is, that N-tier diagrams, which are just multi-layer diagrams, usually don´t graphically distinguish between a layer and a tier. They assume you know, that in an N-tier diagram a layer is at least an OS process.

I think, that´s bad, because it leads to falling prey to one or more of the "fallacies of distributed computing." So at least, when you know you´re dealing with different OS processes, pull apart the layers/tiers and connect them with arrows like this:

image

Unfortunately that raises some questions: Is all the code in a tier of the same color? If so, where do you put validation code, for example? Validation sure is a business logic responsibility. But you don´t want to be forced to do all validation in the green OS process. Some validation should already be done right after data entry in the frontend. But that would mix blue code with green code. Or you might want to validate data right before storing it, just to be sure. That would mix red code with green code. Not a beautiful sight, or is it?

image

But the shudder that ran through me when I saw this "distributed burger" led me to an insight: business logic is not limited to the "middle tier", but can appear in all tears. That´s not even an exception, but the norm. You should not avoid it, because it´s so natural.

Unfortunately the N-tier architectural pattern does not account for such naturalness.

So, what to do? Avoid putting business logic in the frontend or backend (e.g. as a stored procedure) and thus not be able to model what´s coded? Or spit into the holy grail of distributed systems modelling, the N-tier pattern? Tertium non datur?

After having a Guinness or two I chose a third way: I did away with layers and tiers.

Instead I made what seemed awkward in the N-tier model the center of a new model: If we business logic is so important and we can´t avoid putting business logic in all tiers, why not put business logic at the heard of everything - plus give a tier a distinct shape?

image

Isn´t that straightforward? Each circle represents a tier (and thus readily distinguishes itself from a layer), each tier/circle contains business logic.

Thinking further along this line then led me to the visual unification of "all tiers are created equal". From a structural or syntactic point of view there is no difference between a presentation tier, a business logic tier, and a data access tier. So why not represent them using the same symbol?

image

This was the birth of the software cell. The dot in the middle signifying the ubiquitous business logic.

Syntactically it is on par with the simple box of a tier. But semantically is has more to offer:

  • A software cell makes clear, at least an OS process is meant when it´s drawn.
  • A software cell makes clear, at the core of every OS process is the business logic.
  • A software cell makes clear, business logic can be present in any OS process.
  • A software cell makes clear, there is a gap between them that needs to be explicitly bridged. (Tier boxes on the other hand could be just stacked, not leaving a gap, and thus glossing over the fact, that communication between tiers has different characteristics than communication between in-proc layers.)

In addition the circle of a software cell allows for more flexible connections with other software cells. Drawing distributed systems - which are increasingly becoming the norm - thus has become much easier with software cells instead of tier boxes.

And think of it: What a great analogy to think of software systems consisting of many processes as "tissues" made up of software cells. Why not seeing such service tissues as "organs" of an even larger software system or "software organism"?

image

By making business logic core and making OS processes as well as OS process aggregates clearly visible in an architecture, it´s easier for autonomy - one of the fundamental values of SOA - to enter the picture. Software cells are code units running all by themselves in a separate physical or logical address or data space. They share, so to speak, the same "milieu" (alluded to by the colors of the "tissues" in the above drawing).

You decide, how much business logic to "lump together in a software cell organ" until autonomy "sets in". Physically a single software cell representing an OS process is already autonomous in so far as it´s running on its own thread in its own address space. But logically, with regard to the problem domain, though, it might not be able to truely act autonomous. Nevertheless it´s on a good way, because it´s naturally decoupled from other software cells. But that´s a topic for another posting.

Let me close by making again clear, how software cells lend themselves to describing software systems on different levels of abstraction by adding levels above the previous drawing:

image image

On which level does the software system or its parts become autonomous with regard to the respective environments? It´s up to you - as it always has been. But with software cells it´s easier to "visually think" autonomy, because the very concept of (semantic) and symbol (syntax) for software cells carry autonomy at the core.

Take a software cell, connect it to another, connect both to yet another... there is no limit to the connectability of a software cell. Model strictly hierarchical software or P2P software in the same easy manner:

image image

Software cells don´t restrict you syntactically. You´re free to shape the topology of your distributed system as you like. That´s freedom the N-tier paradigm does not offer. That´s why I saw the need for a new, more flexibel meta-model for larger scale software structures.

Let me close for today by saying, that it´s of course ok to use boxes in software cell diagrams, too. If you like, group software cells on any level by surrounding them with a box or any other shape of your liking. That way you can add dimensions for e.g. platform, machine, or some logical context:

 image

Just be sure not to overburden the napkin with details!


Thursday, June 12, 2008 #

The basic building blocks of software when you start architecting it are... well, not classes, and no UML packets either. I believe it should be something more high level and general.

Classes are too fine grained to be used as architectural modelling elements. No chip architect would start planning a new processor by arranging single transistors, and no building architect would plan a house by thinking about where to place each brick:

image

Such a detailed view of a house might be nice for home owners to give them an impression of how their house will look. So it´s about the look and feel and has always been an art of its own:

image

source: http://upload.wikimedia.org/wikipedia/commons/c/ca/Erlach_4.jpg

Using the almost lowest level structural elements for planning how something is built, though, works only for very, very simple things. Think of a flip-flop circuit or a shepard´s hut:

image image

sources: http://pics.computerbase.de/lexikon/121846/180px-Flipflop_by_trexer.png, http://www.planetfear.com/includes/images/uploaded/24200746122613JP-stone-hut.jpg

As a software architect you need more coarse grained material to form an application out of. At least to start with. Do rough sketches first, then refine them. Start in the large, then drill down into the small.

But what is a structural element of software in the large? A UML package? I don´t find that very useful out of two reasons: On one hand an UML package has close ties with a particular programming language (Java), and why should I as an architect be concerned with that (at the outset)? On the other hand an UML package is something very generic, too generic, I´d even say (think UML stereotypes), and why should I as an architect be not more specific?

Hence I feel there´s a lack of an appropriate structural element for modelling software in the large. Services, too, do not help. They are an application of structural elements. So what I came up with are software cells. To me they are the basic, rough, and coarse grained modelling elements for architecture in the large. Their depiction is simple as I showed in my previous posting:

image

Now, what is a software cell? Well, a software cell is a larger unit of code. It can be just C# code or it can be the sum of C# plus T-SQL plus IronPython plus Java plus VBA. The only criteria to call something a software cell is: you develop the code. So basically the "membrane" separates your code from the rest of the world, from some environment.

image

You could also think of a software cell as an island of your code that´s separated from other code islands or some mainland by large stretches of water:

image

How much of your code goes into a software cell? At the beginning, it´s all the code you´re going to develop for an application. From 30,000 ft your application always looks like one large softwar cell:

image

But then, when you sink lower, zoom in during your planning, when you refine your picture of the application, then you come to see more details. The one island of code in fact is several islands:

image

This way you build your software in the large on an arbitrary number of levels of abstraction. Here´s a more handy tree view of such nesting of software cells. It´s the stepwise structural decomposition of the root software cell, which - in the beginning - was the sole representation of the application to plan:

image

Each level of this tree contains as many software cell as you see fit. All together they describe your application on different levels of abstraction/detail. But they are just "blobs of your code" representing some kind of task or responsibility on a high level. Except for the leaves of such a tree of nested software cells they are all virtual or logical. They exist only on your napkin and in your head. Their purpose is to keep complexity at bay.

The leaves, though, are real. They are operating system (OS) processes (or .NET AppDomains if you need more than one in an OS process). So the goal of the initial architectural phase is to determine which OS processes your application should consist of.

Since all applications require at least one OS process to run their code in it´s always right to fill the first blank napkin with a software cell. You could even draw it before your boss has started to explain what kind of application he envisions. With a software cell on your napkin you´re never wrong. Be it a "Hello, world!" program or an ERP system.

This might sound trivial to you, but my experience with lots of software teams tells me, it´s far from it. Many, many developers have difficulties to find an entry point into a software architecture. What they fall back on in such a situation are... more or less formal UML class diagrams. That´s like starting to plan the Empire State Building with some door or corner stone. Or it´s like planning a painted portrait by drawing an ear lobe. Maybe some master artist can start like this, but not us mere mortals. For us it´s much easier not to start with a detail, but with a big picture right in front of us - on the back of a napkin. That´s what software cells are about.

Software cells are the large scale building blocks for our applications. With them you can quickly refine your picture of a software from initial code blob containing everything you need to develop to a number of OS processes among which you distribute the code. Here´s a series of napkins as a testimonial to this approach:

image image image image

I began the architecture with just a single software cell to represent all of the application to develop. As I said, that´s never wrong.

Then I decomposed the software cell into two very different ones, e.g. a software cell for frontend stuff and one for business logic stuff. Maybe I first thought a client/server architecture would fit the problem best.

But then I realized it would be better to distribute the business logic stuff across at least two software cells, both being candidate OS processes.

Finally I devided the frontend stuff into two software cells (or candidate OS processes), because I learned from my boss, he would like a web frontend as well as a desktop frontend.

And, upps, before I forget, there is another concern coming up: What about reports? If the application needs to print long running reports they could be produced by yet another software cell (aka service) instead of one of the business logic software cells. So I spawn another software cell from the code I imagined to go into the blue software cells:

image

This is the lowes level of abstraction at the end of the first architecturing phase. These software cells are now to become the OS processes of the application. And depending on who you´re talking to you can pull out an appropriate napkin on a level of abstraction right for your audience.

Here´s the decomposition for you as an overview of all levels:

image

With your senior developers you talk on level 4, the OS process level. The newly hired junior dev might need a more gentle introduction to the application starting on level 2, and your boss or his customer just wants to see the big, big picture on level 0.

In any case: If a napkin gets crowded by symbols and lines, take a new one from the pile. Insert a level of abstraction and drill down using a couple of napkins for the details.

Ok, where are we now? I showed you how to start architecting you next application not by trying to dream up some class it might contain, but rather by determining the OS processes it will be distributed across. That´s maybe just one or it´s a dozen on several machines and different platforms. Start by assuming there is at least one, depict it as a software cell, then refine each software cell in a recursive process into "smaller", more focused software cells until you´re confident you´ve reached the leafs of the software cell tree. That´s the OS processes.


Wednesday, June 11, 2008 #

Before I bore you with some theory let me quickly show you, how I think you can fill any (!) empty napkin in a minute with a meaningful sketch of a software system, be it completely new or already 30 years old, whether it´s object oriented or all assembler code, and regardless of its size.

Imagine your boss calling you in to talk to you about a new software project. He explains to you his grand vision of a one-size-fits-all "Hello, world!" program. And you can´t hold back your excitement. What a great opportunity for you to show off your skills as a software architect! You go through the requirements with him and make sure you understand every detail. Then you impress your boss with your first architectural sketch. It´s rough, yes, but at least you can show him something right away. You don´t fear an empty sheet of paper (or Visio drawing canvas). Right to the contrary! You love napkins when they are empty!

Here´s what you draw for your boss on the back of a napkin you happen to have brought with you:

image

That´s it. Plain simple, and enough to convey your understanding of his amazing idea.

And what is it you depicted? It´s the whole application, all that you have to develop and don´t know yet how to implement. All the intricacies and complexities of the application are represented by, well, just one "software cell" - the circle with the dot in the middle:

image

I call it a software cell, because it looks like a biological cell with a membrane and a core:

image

source: http://www.schule.at/index.php?url=kategorien&kthid=6191

And like a biological cell a software cell encapsulates complex processes and shields them from the outside world. By drawing a software cell you thus distinguish an inside from an outside, a system from its environment.

image

That´s not difficult, isn´t it? But it´s an important first step, since it draws a line in the sand separating what you have to implement from what you don´t have to implement. And it´s important because it starts software development on a level of abstraction your boss is still comfortable with. He´s an important stakeholder of the whole effort, so you want him to feel comfortable and confident and understanding as long as possible. How better to do that than by drawing pictures even he understands?


The Back of the NapkinWhy did I choose the napkin to promote as a canvas for software architectural drawings? To be honest, except for my general belief in the virtues of simplicity it´s also somewhat a hommage to a book I recently read: The Back of the Napkin: Solving Problems and Selling Ideas with Pictures.

A traditional blueprintDan Roam impressed me with his creativity and his ability to depict the essence of all sorts of stuff in clear and simple pictures - all fitting on the back of a napkin. Before I´ve read his book I either did not give size of architectural images much thought or I complained about the limited size of displays compared to the huge blueprint tables for building architects.

I always envied them for their large sheets of paper filled with all those symbols describing a whole world to be built and lived in. The overview such blueprints provide seemed important to me. In comparison to that, looking at an UML diagram on a 1280x800 screen felt awkward.

That has changed, though, thanks to Dan Roam! I no longer feel hindered in my creativity and expression by a small display. Right to the contrary! I think limited display size or a consciously chosen small canvas help architecting software. Why? Because a small canvas naturally limits the number of "things" you can depict at the same time. A small canvas thus constrains the complexity of the design you can draw. And that´s a good thing!

Traditional building architecture might not need such constraints, since it´s dealing with static objects. But software is a different beast. It´s not static at all, it´s highly volatile, constantly evolving, never finished. That´s why I recommend, to keep depictions of it small.

You probably think drawings like this

Some complicated class diagram

source: http://openalchemy.org/index.php/OpenAlchemy_Wizard_Tour

or this

Another complicated class diagram

source: http://www.roxsoftware.com/ug/

Do you now understand how a fuel injection pump is meant to work?are the norm and why should it be different. But from the point of view of someone trying to understand (!) what they show they are, well, hard to grasp. Whoever draws a diagram does not have much of a problem with its size. He understands the content perfectly well - otherwise he wouldn´t be drawing it. But once you switch sides and need to understand such depictions, the situation changes. Hours upon hours of valuable time are invested into understanding such drawings - whereas much effort could have been saved, if the drawings were kept smaller and simpler.

If you´re an expert in fuel injection pumps the drawing on the right might be easy to read. But there are always less experts than novices, people who first need to learn about a technical system. They are easily (and unnecessarily) overwhelmed by such images.

That´s why I´m saying: Don´t try to impress anybody by putting everything you know about a software system into just one big picture. Try to walk in the shoes of the many (occaissonal) viewers of it who don´t have much time make sense of a ton of boxes and arrows.

Electronic light table Of course the capacity of the human visual system is mind boggling. We can spot a familiar face in a crowd and scan thousands of images in a folder or on a light table. But that´s "simple" pattern recognition.

Understanding (!) a software architecture on any level of abstraction is different. There might be patterns to recognize, but before that the meaning of the structural elements and their relationships needs to be clarified. And that´s what costs so much time. And that´s what benefits from consciously limiting the size of software architectural drawings.

At times larger drawings for overview might be ok. But mostly you should think "small is beautiful" ;-) Focus yourself on whatever fits on the back of a napkin. You can use more than one. Help yourself...

image


Tuesday, June 10, 2008 #

Welcome to my new blog on .NET software architecture.

I set it up as a journal for my work on a book I plan on making architecting or modelling .NET software easier. For the past 2-3 years I developed a small system or method or view on how I think developers should approach planning and implementing the structure of a software. Sure, there are already many guidelines as to how one should design software - but still developers feel uneasy when standing in front of a blank flipchart. At least that´s what I experience again and again when consulting with clients.

How should they start with an architecture? How to map an architecture to tangible artifacts? How can they keep an architecture in sync with the code? These and many more questions make it difficult for them to feel comfortable with the task of architecting a software.

Unfortunately OOA/D, OOP, UML, DDD, architectural patterns like N-Tier Applications, or SOA don´t help much. Although they are all valuable, something is missing. Some glue, some big picture within which all this makes sense. That´s what I want to provide. A big picture of software and a clear roadmap for how to get from a bunch of requirements to deployable code.

I´ve blogged about my ideas before in my other English blog and in my German blog. But for a book I need to pull all this material together and add some new stuff. That´s what this blog is for. Plus, I want to give the whole story a provocative twist by claiming: software architecture needs to fit on the back of a napkin in order to stay understandable. As soon as architectural drawings can´t be sketched on a napkin anymore, they are too complex and will hamper discussion and implementation.

My credo thus is: As a .NET software architect strive for visualizing your ideas on the back of a napkin! Management as well as developers will love you for this.

If you like, stay tuned. I´d love to discuss my ideas with you.

image

Ralf Westphal, www.ralfw.de