Below you will find pages that utilize the taxonomy term “Software Development”
Dealing with technical debt during the sprint
It’s quite ironic that my most “popular” tweet has been posted while Twitter itself is in such a chaotic phase. It’s also quite ironic that I try to provide helpful suggestions for doing a better job as a programmer, yet such a bitter tweet ends up to be so popular.
Twitter and Mastodon are micro-blogging platforms. The problem with micro-blogs, and with short interactions in general, is that everybody can proceed to project onto your words whatever they like. So at some point I often feel the need to explain myself with more words, in an “actual” blog like this one.
Commit your code as if it could be accidentally deployed
The one simple trick to do a better job as a programmer is to git commit as if your commit could be accidentally deployed (and it wouldn’t break the production environment…)
Why would this improve your work? Because it pushes for improvements in several areas.
If a commit needs to leave the project in a working state, you need to:
- Be able to prove that after making your changes, the project is in a working state. This forces you to put automated tests in place.
- Be able to make changes that don’t break existing code, or that only add new features. This forces you think about first improving the existing code design to allow for your change to happen.
To practice with the latter, I recommend learning about the Mikado method. It makes it easier to recognize prerequisites for the change you want to make, and then forces you to enable the real goals by implementing the prerequisites first.
Do you have an exit strategy?
It’s an extremely common problem in legacy code bases: a new way of doing things was introduced before the team decided on a way to get the old thing out.
Famous examples are:
- Introducing Doctrine ORM next to Propel
- Introducing Symfony FrameworkBundle while still using Zend controllers
- Introducing Twig for the new templates, while using Smarty for the old ones
- Introducing a Makefile while the rest of the project still uses Phing
And so on… I’m sure you also have plenty examples to add here!
Successful refactoring projects - Set the right goal
Refactoring is often mentioned in the context of working with legacy code. Maybe you like to define legacy code as code without tests, or code you don’t understand, or even as code you didn’t write. Very often, legacy code is code you just don’t like, whether you wrote it, or someone else did. Since the code was written the team has introduced new and better ways of doing things. Unfortunately, half of the code base still uses the old and deprecated way…
Successful refactoring projects - Prepare to stop at any time
Refactoring projects
A common case of refactoring-gone-wrong is when refactoring becomes a large project in a branch that can never be merged because the refactoring project is never completed. The refactoring project is considered a separate project, and soon starts to feel like “The Big Rewrite That Always Fails” from programming literature.
The work happens in a branch because people actually fear the change. They want to see it before they believe it, and review every single part of it before it can be merged. This process may take months. Meanwhile, other developers keep making changes to the main branch, so merging the refactoring branch is going to be a very tedious, if not dangerous thing to do. A task that, on its own, can cause the failure of the refactoring project itself.
Is not writing tests unprofessional?
Triggered by Marco Pivetta who apparently said during his talk at Symfony Live Berlin: “If you still don’t have tests, this is unprofessional”, I thought I’d tweet about that too: “It’s good for someone to point this out from time to time”.
I don’t like it when a blog post is about tweets, just as I don’t like it when a news organization quotes tweets; as if they are some important source of wisdom. But since this kind of tweet tends to invoke many reactions (and often emotionally charged ones too), I thought it would be smart to get the discussion off Twitter and write something more nuanced instead.
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.
Deliberate coding
I wanted to share an important lesson I learned from my colleague Ramon de la Fuente. I was explaining to him how I made a big effort to preserve some existing behavior, when he said something along the lines of: the people who wrote this code, may or may not have known what they were doing. So don’t worry too much about preserving old stuff.
These wise words eventually connected to other things I’ve learned about programming, and I wanted to combine them under the umbrella of a blog post titled “Deliberate coding”. Doing something “deliberately” means to do it consciously and intentionally. It turns out that not everyone writes code deliberately, and at the very least, not everyone does it all the time.
Remote working
Recently I read Ouarzy’s review of Jason Fried and David Heinemeier Hansson’s “Remote - Office Not Required”. I’d read their previous books, “Getting Real” and “Rework”. They’re all a joy to read. Short chapters, nice little cartoons. Just a lot of fun, and inspiring too. Not many authors make as much of an effort as they do to condense their message and reward the reader for taking the time to read an actual book. It’s insulting how much work some authors expect you to put in before they will reveal their secrets!
Combing legacy code string by string
I find it very curious that legacy (PHP) code often has the following characteristics:
- Classes with the name of a central domain concept have grown too large.
- Methods in these classes have become very generic.
Classes grow too large
I think the following happened:
The original developers tried to capture the domain logic in these classes. They implemented it based on what they knew at the time. Other developers, who worked on the code later, had to implement new features, or modify domain logic, because, well, things change. Also, because we need more things.
Convincing developers to write tests
Unbalanced test suites
Having spoken to many developers and development teams so far, I’ve recognized several patterns when it comes to software testing. For example:
- When the developers use a framework that encourages or sometimes even forces them to marry their code to the framework code, they only write functional tests - with a real database, making (pseudo) HTTP requests, etc. using the test tools bundled with the framework (if you’re lucky, anyway). For these teams it’s often too hard to write proper unit tests. It takes too much time, or is too difficult to set up.
- When the developers use a framework that enables or encourages them to write code that is decoupled from the framework, they have all these nice, often pretty abstract, units of code. Those units are easy to test. What often happens is that these teams end up writing only unit tests, and don’t supply any tests or “executable specifications” proving the correctness of the behavior of the application at large.
- Almost nobody writes proper acceptance tests. That is, most tests that use a BDD framework, are still solely focusing on the technical aspects (verifying URLs, HTML elements, rows in a database, etc.), while to be truly beneficial they should be concerned about application behavior, defined in a ubiquitous language that is used by both the technical staff and the project’s stakeholders.
Please note that these are just some very rough conclusions, there’s nothing scientific about them. It would be interesting to do some actual research though. And probably someone has already done this.