In Edge Case Bill de hÓra points out, as does Tony Coates, that a DataClass is not always a bad idea. Both are responding to an assertion made by Martin Fowler, that a DataClass is usually a sign of poor design. And both use serialised objects as a counterexample. I guess I’ve never thought of serialised objects as capable of having behaviour (since they generally live in media that don’t support it); and so perhaps I don’t even think of them as being sufficiently objecty to even count in the discussion. So to me it’s a non-disagreement.
More interesting to my eyes is Bill’s use of the term “application edges”:
“But when it comes to working at the application edges – at the network boundary, over HTTP, between applications, intra-app messaging – well, “I have a doubt.” […] There’s a lot of system edges these days, and agreeing where the edges are is hard.”
There are indeed a lot of edges these days. And trying to think about them in the context of a layered model of the application’s architecture is likely to cause brain-ache. Which is why I keep pushing the hexagonal architecture model. It moves the application and domain objects into the centre, and surrounds them with adapters that connect to the rest of the world. In this architecture, the “edges” have a natural symmetry, and their role in the application becomes easier to visualise.
So in the context of hexagonal adapters, some of Bill and Tony’s data classes will likely be GoF Mementos, others are probably Whole Value objects, and the rest probably really are blobs of data. I would expect the Whole Value objects to have behaviour, but not the others. But the real point, for me, is that the hexagonal architecture approach makes the use of these patterns clearer…
During my ‘hexagonal architecture’ session at XPday Benelux, the discussion gave me some clues as to why I feel the “standard” layered architecture model is sub-optimal: I realised that I feel as if I’m looking at a picture of a pile of stuff from the side. Contrast this with a hexagonal model of the same system, in which I feel as though I’m looking down on the picture.
Why is this important? And what relationship does it have to being agile?
The answer, I believe, lies in Lakoff‘s theory that metaphor shapes much of our thinking. When I look at any architecture model I subconsciously impose a point of view on the picture, because my mind relates what I see now to previous experiences. A layered model “looks like” a pile of books or building bricks; a hexagonal model “looks like” an island on a map (another metaphor in itself!) or a table with chairs arranged around it. The choice of metaphor is made deep in my perceptual system, helping me to make sense of anything I see. And once the metaphor has been selected, my mind will then automatically supply it with a whole load of related beliefs, many learned as a baby. Among these are the effects of gravity and mass, together with related implications of downward dependency.
These associations cause me to believe that the things at the bottom of the pile are hard to move or change. Whereas in the hexagonal view I instinctively feel the system’s components are more loosely coupled – perhaps because they are associated only by proximity, and not by gravity.
So because of these deep-seated metaphorical associations, maybe we build less adaptable systems when we think of them in layers…?
Last week I spent an enjoyable day at XPdays Benelux in Rotterdam. I ran a couple of sessions, attended a couple more, and met up with friends old and new. Here are brief recollections of the highlights in my day…
The day began with every presenter offering a 1-minute sales pitch for their session. I got to do two: one for Hexagonal Architecture and one for Jidoka. A minute is longer than you’d think, and I’d guess that most of the pitches were over inside twenty seconds. I decided to be a little different, so I had everyone stand on one leg – hopefully to demonstrate that the standard layered architecture model compromises agility… Continue reading →
In A thought on mocking filesystems Brian Marick provides yet another reason to think in terms of a hexagonal architecture. Discussing the writing of mock objects for huge components such as a filesystem, he writes:
“So it seems to me that a project ought to write to the interface they wish they had (typically narrower than the real interface). They can use mocks that ape their interface, not the giant one. There will be adapters between their just-right interface and the giant interface. Those can be tested separately from the code that uses the interface.”
Mocks/stubs and adapters are natural bedfellows, and definitely help to keep code clean and testable. I once worked on a project in which the “filesystem” was a JNDI directory service. And then later that was scrapped in favour of a plain old filesystem. How I wish I had known about hexagonal architectures then, because it was a real nightmare to disentangle the JNDI dependencies from the rest of the system.
Now I believe that names are immensely important, and so I applaud Alistair’s search for the right name for this concept. But for some reason PortsAndAdapters rings no bells for me. Maybe I’ve simply become used to the old name, or maybe I’m averse to change. (That would be ironic for an agile coach, but I guess we all have comfort zones…) So what is it with this new name – or what does the old name have instead?
Obviously I have no quibble with the ‘Adapters’ part, because I’ve been using that term for long enough myself. But ‘Ports’? From that term I would tend to infer a fixed set of pre-existing conduits, sending and receiving signals from something specific. Whereas I tend to think of a hexagonal architecture as something much more flexible, able to post adapters (more on this soon) to a less prescribed set of real-world entities.
I tend to view the physical world as an amorphous soup to which the software system can connect adapters in fluid ways. I know that’s inherently impractical, but it makes for a great mental model when whiteboarding a system. And I think this gets near to the crux of my unease at the new name. I think of a hexagonal architecture as a whole-system view, whereas PortsAndAdapters seems to look only at the system’s connections with the physical world. The key, for me, is the symmetry, and the consequent removal of the constraints of the layered model. I don’t care about the Ports; I’m interested instead in the central core where the knowledge lives, and the ability to interact with that core in flexible ways. To me, hexagonal architecture is all about inner and outer, core and periphery, business knowledge and interfaces.
Why so much about just a name? After all, it’s clear that neither name comes close to expressing the above…
I like simple rules of thumb that will help developers create better, more adaptable designs. So here’s another: Never throw an exception. And if someone throws one at you, catch it immediately and don’t pass it on.
“…I consider exceptions to be no better than “goto’s”, considered harmful since the 1960s, in that they create an abrupt jump from one point of code to another. In fact they are significantly worse than goto’s…”
But then he goes on to give advice that I consider questionable at best, by suggesting that you catch exceptions quickly and convert them into return codes. I agree that they should be caught at the earliest possible moment, but I disagree with converting them into return codes. Because although that certainly makes the mechanism visible to the reader of the code, it still represents strong coupling where there should be none. The caller – or someone further back along the call stack – has to know about, and take action in response to, someone else’s problem. It seems to me that such coupling violates the pragmatic programmers’ tell don’t ask principle. Continue reading →
In his article Domain-Centric Programming J.B.Rainsberger tells a very nice story about how a project was improved by leaving the database development to the very last.
“The last thing I did was to build a simple, four-table database schema and a small component that read from and wrote to the live database. Since I had practiced test-driven development … I had high confidence that I had implemented everything correctly. Since I had focused on the domain, rather than the database, I was even more confident that I had gotten the database right the first time.”
(Thanks to Brian Marick for bringing the article to light, via the agile-testing group on Yahoo.)
By pure coincidence I’ve been telling very similar stories on a project I’m coaching at the moment. We’re currently investigating approaches for the architecture of a new product line, and the group thinks that we might gain a lot by thinking in terms of a hexagonal architecture. During the last couple of weeks I’ve been thinking a bit more about such models, and I’ve come to a rather remarkable conclusion: the database is not on the outside. I now believe that the database is merely one of the technologies that together create the nutrient environment supporting the objects in the middle hexagon. Continue reading →
In Pseudo-OO Design Dadi Ingolfsson talks about that all-too-common phenomenon – a design in which the code and the data are separate.
“This relates to the Microsoft-style of a DAL (Data Access Layer), a BLL (Business Logic Layer) and a UI, where the data that travels through the layers might be, for instance, dumb Customer objects or DataSet objects. The objects in these different layers are very procedural in nature as they usually only operate on data in objects that are sent to them rather than the data being their own. It´s what Fowler called an Anemic Domain Model. This is not OO design even though many programmers seem to think code is OO if it has classes and objects.”
By coincidence, this week I found myself workshopping agile programming with a team whose legacy C++ system is just like this. My approach to gradually improving the situation is to look for instances of the feature envy smell. Bit by bit, as we find each of these smells, we move the code into the objects where it belongs. Bit by bit, encapsulation improves. Bit by bit, the domain model emerges in the code. And very often, as we introduce abstractions to improve testability, bit by bit a hexagonal architecture emerges too.
Why is this important? Why is it bad to separate the code from the data? Because it stops the code changing at the pace of the business. Distributed behaviour and state mean that each piece of business knowledge is also distributed throughout the system. Which means that any new or changed requirement will cost more to implement.
The standard three- or four-layer models of application architecture seem to dictate the direction of the dependencies between the various “kinds” of object in the system: The UI depends on the application layer, because the UI “drives” what happens “below”. The application layer depends on the business objects, which do all the domain-specific things. The business objects use (and hence depend on) the persistence layer and comms layer, both of which in turn use and depend on external APIs. It is perfectly natural to read a layered model in this way – indeed, that was its purpose.
And it is this very interpretation that has made so many applications difficult or impossible to test. Each of those perceived dependencies ends up enshrined in the code structure, and by stealth the design has cast in concrete the layered model. At which point someone like me comes along an exhorts the developers to improve their test coverage. I’m told: “We tried that, but it takes too long to manage the Oracle testdata we’d need to test the GUI,” or something similar. Or the business decides to switch to a new database or enterprise comms architecture, requiring huge swathes of business logic to be re-engineered.