A collection of more than 250 articles about Software Design & Development Best Practices.
With code samples for PHP/Symfony and Fortran applications.
When to add an interface to a class
I’m currently revising my book “Principles of Package Design”. It covers lots of design principles, like the SOLID principles and the lesser known Package (or Component) Design Principles. When discussing these principles in the book, I regularly encourage the reader to add more interfaces to their classes, to make the overall design of the package or application more flexible. However, not every class needs an interface, and not every interface makes sense. I thought it would be useful to enumerate some good reasons for adding an interface to a class. At the end of this post I’ll make sure to mention a few good reasons for not adding an interface too.
Improving your software project by being intolerant
During the holiday I read a book mentioned to me by Pim Elshoff: “Skin in the game”, by Nassim Nicholas Taleb. Discussing this concept of “skin in the game” with Pim had made me curious about the book. It’s not such a fat book as one of Taleb’s other books, which is possibly more famous, called “Antifragile”. “Skin in the game” is a much lighter book, and also quite polemic, making it an often uncomfortable, but fun reading experience. I can easily see how people could get mad about this book or aggressive towards its author (not that I’m encouraging or approving of that aggression!). While reading it, it reminded me of Nietzsche, and his despise of the “common man”, who Taleb calls “the intellectual” - someone who has no “skin in the game”, let alone “soul in the game”. Taleb’s ideas are interesting, just like Nietzsche’s are, but they could easily be abused, and probably so by misinterpreting them.
More code comments
Recently I read a comment on Twitter by Nikola Poša:
I guess the discussion on my thread is going in the wrong direction because I left out a crucial hashtag: #NoCommentsInCode - avoid comments in code, write descriptive classes, methods, variables.https://t.co/MuHoOFXCvV
— Nikola Poša (@nikolaposa) July 13, 2018
He was providing us with a useful suggestion, one that I myself have been following ever since reading “Clean Code” by Robert Martin. The paraphrased suggestion in that book, as well as in the tweet, is to consider a comment to be a naming issue in disguise, and to solve that issue, instead of keeping the comment. By the way, the book has some very nice examples of how comments should and should not be used.
Negative architecture, and assumptions about code
In “Negative Architecture”, Michael Feathers speaks about certain aspects of software architecture leading to some kind of negative architecture. Feathers mentions the IO Monad from Haskell (functional programming) as an example, but there are parallel examples in object-oriented programming. For example, by using layers and the dependency inversion principle you can “guarantee” that a certain class, in a certain layer (e.g. domain, application) won’t do any IO - no talking to a database, no HTTP requests to some remote service, etc.
Objects should be constructed in one go
Consider the following rule:
When you create an object, it should be complete, consistent and valid in one go.
It is derived from the more general principle that it should not be possible for an object to exist in an inconsistent state. I think this is a very important rule, one that will gradually lead everyone from the swamps of those dreaded “anemic” domain models. However, the question still remains: what does all of this mean?
About fixtures
System and integration tests need database fixtures. These fixtures should be representative and diverse enough to “fake” normal usage of the application, so that the tests using them will catch any issues that might occur once you deploy the application to the production environment. There are many different options for dealing with fixtures; let’s explore some of them.
Generate fixtures the natural way
The first option, which I assume not many people are choosing, is to start up the application at the beginning of a test, then navigate to specific pages, submit forms, click buttons, etc. until finally the database has been populated with the right data. At that point, the application is in a useful state and you can continue with the act/when and assert/then phases. (See the recent article “Pickled State” by Robert Martin on the topic of tests as specifications of a finite state machine).
Blogging every week
A very important “trick” in finding the flow in life is: do what you like most. Of course, you have to do things you don’t like (and then you need different life hacks), but when you can do something you like, you’ll find that you’ll be more successful at it.
When it comes to blogging, I find that it helps to follow my instincts, to write about whatever I like to write about at the moment. I can think of a list of things that need blogging about, but I end up not writing about them because they don’t light the fire inside me (anymore).
Testing actual behavior
The downsides of starting with the domain model
All the architectural focus on having a clean and infrastructure-free domain model is great. It’s awesome to be able to develop your domain model in complete isolation; just a bunch of unit tests helping you design the most beautiful objects. And all the “impure” stuff comes later (like the database, UI interactions, etc.).
However, there’s a big downside to starting with the domain model: it leads to inside-out development. The first negative effect of this is that when you start with designing your aggregates (entities and value objects), you will definitely need to revise them when you end up actually using them from the UI. Some aspects may turn out to be not so well-designed at all, and will make no sense from the user’s perspective. Some functionality may have been designed well, but only theoretically, since it will never actually be used by any real client, except for the unit test you wrote for it.
Doctrine ORM and DDD aggregates
I’d like to start this article with a quote from Ross Tuck’s article “Persisting Value Objects in Doctrine”. He describes different ways of persisting value objects when using Doctrine ORM. At the end of the page he gives us the following option - the “nuclear” one:
[…] Doctrine is great for the vast majority of applications but if you’ve got edge cases that are making your entity code messy, don’t be afraid to toss Doctrine out. Setup an interface for your repositories and create an alternate implementation where you do the querying or mapping by hand. It might be a PITA but it might also be less frustration in the long run.
Road to dependency injection
Statically fetching dependencies
I’ve worked with several code bases that were littered with calls to Zend_Registry::get(), sfContext::getInstance(), etc. to fetch a dependency when needed. I’m a little afraid to mention façades here, but they also belong in this list. The point of this article is not to bash a certain framework (they are all lovely), but to show how to get rid of these “centralized dependency managers” when you need to. The characteristics of these things are: