When I first started to work, I knew I was doing crap. Yep, really. We were using old stuff, copy/pasting heavily, editing config files by hand before deploying in production and so on. However, knowing you do crap doesn’t help you doing right, even if you had the occasion.
As time went by, however, I was lucky enough to work with real Software Developers, craftsmen as we would say today, learning a lot on the way.
Yet, even these bright guys were sometimes uneasy. Not on technical stuff, not on infrastructure, but, well, you know, on the classes and the like you’ve to do for your customer. How shall we split the different parts of the requirements? What should be top level code or just "code that works", intended not to be touched more afterwards. To which extend shall we integrate what’s the business requires, or shall we adapt it a bit to our stuff ?
Yet, these foggy stuff are the value of an application. Customers don’t care too much about how nice your XML described UI is. Nor does he care too much about maven and the like. He cares about these (often messy) code doing what he asked for. The code which enables dealership to get their good in time. The code which triggers automatically some buy on some mutual funds. The code which allows to display the breaking news. The user’s code. And on top of that, whatever the nice technical layers around, if the users’ domain is badly understood and/or translated into code, then it’ll be a mess and massive pain to work with.
Domain Driven Design is all about this code which actually is, or at least should be, the heart of your application. This "domain" code is where the real value is. Ṫhe book makes the obvious visible again: the domain, the users’ stuff, is what matters. Even better, the books describes plenty of means to handle this part of your application, from quite low lever to high ones. How to handle large domain. How to refactor towards greater insight (a chapter title actually). It even has a chapter called Strategic Design, speaking about how to handle these different domains which always coexist, and how to make the best of them. Most important of all, the books is all about the UBIQUITOUS LANGUAGE.
The uppercase is not mistake: the UBIQUITOUS LANGUAGE is what allows users and developers to understand each other effectively and over time. It matters. The UBIQUITOUS LANGUAGE deserves its uppercase. And by doing so constantly in the book, with the core concepts, Eric Evans makes it obvious what matters or not. After reading the book all these big uppercase words will stick to your mind with ease. ANTI CORRUPTION LAYER. REPOSITORIES. BOUNDED CONTEXT. They’re all still there
To tell more about the UBIQUITOUS LANGUAGE, it’s the language used to describe the domain, both by the users and the developers. It is should be reflected in the code. And, of the highest importance, is should evolve with the comprehension of the needs. This is the domain. This is the added value of your work. Eric Evans takes care of showing ways to handle this UBIQUITOUS LANGUAGE and make it pervasive and effective. His examples are clearly first hand ones, which smell and look like what you could expect tomorrow (or on Monday rather lol). No big word on SOA or Agile Manifesto. No, just how to make your users needs properly fulfilled. On top of that, the author speaks of organization at the code level and higher ones (like what to do with big blobs of codes or legacy systems). This uncommon "elevation" is very nice and helpful. Speaking of more than the GOF patterns as a way to make your code base intelligible is very nice. In fact, the book’s title second part "Tackling Complexity in the Heart of Software", is true and right to the topic.
I guess you got it, I liked this book. It makes you think and ponder often, on your current practices and on "industry wide" ones. Like the habit of affecting the best developers to the infrastructure teams. Common isn’t it ? These top notch guys can then develop some stack able to solve both desktops and web needs, transparently and recursively. Sounds all good, but is this what your users want ? They want their needs fulfilled, they want their reality to be tackled. And whatever your bells and whistles, if you can’t move stuff Y to point 1243, it’s no help.
Well, I fear I’m too verbose. By the way, the book is quite verbose as well. More than 500 pages and extensive texts. Reading it took quite some time, even if I liked it. It was just big, both in volume of text and on impact of its content. But it didn’t go in the way, apart that at the end I was wondering about stuff explain at the beginning. But then, no big deal: for sure I’ll read it again.
To kind of conclude, this book is the last bit of theory I was missing towards making great software, in the long run, in a sustainable way, for the users. It has already changed the way I approach design and it looks like my users felt and liked it already.
I already said too much: I’m off !
2 points stroke me when reading this "Pragmatic Unit Testing" book :
- in order to easily test some class, they suggest to open the required methods by making them protected. I had first to check that protected included package readability (it does) but still I think it’s going a bit too far : if the method was supposed to be private, package private is the nearest visibility which would fit. I would only make it protected if I intent to override it. Do I miss something ?
- the last paragraph is called "Testing invalid parameters", and speaks of where to test the validity of the parameters. Their answer is "we find the easiest rule to adopt is the ‘keep the barbarians out at the gate" approach’, meaning internal components can trust the data they get. At work, we do it differently : every non private method has to check for the validity of its input (for which we have a dedicated assertion lib.). Would you suggest otherwise ?
I’m currently reading Refactoring from Martin Fowler. Overall, it’s an interesting book from which much could be said but tonight I would like to speak only of the "introduce Null object" hint provided in it.
The basic idea is pretty simple, instead of checking for null return from various call, just provide a "null object". It means a real object but with no content. The clue is that this object knows how to handle method calls, rendering the right enum/int value/you name it according to its logic.
As such, no need to return null and then check for null everywhere. No result for search of Bla ? Simple, return the missingBla object !
Apparently it helped them quite a lot to skip of these redundant checkings, allowing as well to easily display objects full of others objects instances. Indeed, one instance being null is not an issue any more : calling person.getAdress() and then address.getStreet() providing now a missingAddress then a null street string. Some NPE may still appear, but way less than before apparently.
It’s the first time I see this hint and at first look it seems promising. Does someone have some second thought on it ? I’ll search more on it later on, maybe some caveats are known which would explain its relative anonymity !
NB : instead of using the term Null Object they use "missing object" apparently, which might avoid some confusions… Still on the "note side", please note as well that the "missing objects" are always constant, making their usage pretty easy (and singleton like).
For resources, I found while writing this post that Martin provides a full list of each of the design hints he writes about, and even more (he provides updates and new ones). For the Null Object, it’s there, and probably better than my quick explanation. Great !
see ya !