Just to set the context. I wrote a blog entitled NODB (http://blog.8thlight.com/uncle-bob/2012/05/15/NODB.html)
In that response David complains that FitNesse flunks the first glance test. I quite agree. FitNesse _does_ flunk the first glance test. That's because FitNesse was begun in 2002, during "the lost decade" when we were all trying to figure out what a web application looks like. The reason I referenced FitNesse in my tweet was because it's a very good example of the database independence referenced in the NODB blog.
But let's take a closer look at the architecture of FitNesse. Does it really flunk the first glance test completely? Or is there a hint of a use-case centered architecture lurking in there? Here's the top level of the src folder:
Now, granted, this is not a paragon of information. On the other hand, we do see fit and fitnesse at the top level. That's interesting because FitNesse began as a wrapper around fit. So even at this top level we can begin to see an architecture that communicates intent. In reality this directory should contain only three directories. Fit, FitNesse, and FitNesseMain. That last is important. Those of you who have been following my cleancoders.com
videos know that main is always kept separate from the rest of the application, with all dependencies pointing from Main into the application.
If we open up that FitNesse folder we see a whole bunch of cruft.
That's unfortunate because that cruft hides some very interesting information. That directory should really cleaned up so that you can see the important stuff, and not all the junk that's accumulated over the last decade. What you see below is the physical architecture diagram of FitNesse. If you compare that diagram to the two directories we have seen, you'll note that there's a strong correlation between them. Nearly every box on the architecture diagram has a representative in the directory structures we've seen.
This diagram is not a logical architecture. It doesn't show use cases. But it does show the large physical elements of the system. What's more the top level use cases are implied by this diagram.
Before we can go on, we need to know what FitNesse is. FitNesse is a wiki. But it's a special kind of wiki. FitNesse is a wiki that executes tests that are written on the wiki pages. The tests can be written in a cucumber like style, or a tabular style, or a script style, or any of quite a large variety of different styles.
What are the use cases? Edit page, delete page, rename page, test page, test a suite of pages, etc. etc.
If you look back at that 'fitnesse' directory listing above, you'll see the directories named 'wiki' and 'wikitext'. That's a hint that FitNesse is a wiki. If you were to explore these directories you'd get even more clues about the kinds of things that the wiki does. Also in that 'fitnesse' directory you'll see a directory named 'responders'. Let's look at that one.
OK, a bunch more cruft. And again, that's a shame. Because there's some pretty interesting stuff hidden inside that cruft. But before I can tell you about that I need to explain what the word responder means. Responder means use-case. When we named these objects, we weren't thinking clearly about the architecture. Again, this was part of "the lost decade". But the responder classes in these directories are cousins of the interactor objects that I was talking about in my recent architecture talks. They control the interactions of the individual use cases that drive the system.
Some of the responders you see here are kind of obvious. NotFoundResponder, for example, deals with one of the error recovery scenarios of several other use cases. RssResponder handles the RSS request use case for the wiki. ShutdownResponder shuts the system down when the appropriate command is given. More interesting still are the directories. Let's look at the 'editing' directory:
Now this is starting to look like a bunch of use cases! AddChildPageResponder, EditResponder, MergeResponder, NewPageResponder, SaveResponder. In fact every one of these responders corresponds to a use case.
If you look in the other directories you'll see even more use cases.
Now these responders are not perfect. If I were writing them today, I'd write them very differently. These responders are too coupled to the web. They know they are dealing with HttpRequests, and they know that they are producing HttpResponses. Nowadays I'd decouple them much more. Indeed, it was the act of writing and maintaining FitNesse over the years that re-stimulated the ideas that were lost in the late '90s.
So perhaps FitNesse does not deserve a full out 'F' for the first glance test. The concepts are certainly there, they are just struggling to get out through the cruft. Part of the reason that the structure of FitNesse is somewhat muddled, is because we did not decouple the use cases from the UI. This unfortunately smeared the concept of HTML and HTTP all through those responders. Back then we were struggling with the concept of the web so much that decoupling from it was the last thing on our minds. Nowadays we'd do a lot better. Fortunately, we _did_ decouple from the database very strongly, so FitNesse enjoyed complete database independence. And that's why the tests run so fast.
A much better example of the kind of architecture I like is the Payroll Example in "Agile Software Development: Principles, Patterns, and Practices." Oddly enough, the design of this system is contemporary with the development of FitNesse. But I purposely avoided any mention of the web. I kept the system decoupled from databases and user interfaces, as I had learned to do in the '90s. And the result was quite good. The implementation is C++, but that shouldn't deter you. The directory structure is not shown, but there's a hint of it in the package diagram in Figure 22-11.