Below are my guiding principles, that are the basis of what, how and why am I doing with regards to software development.
Long term development speed
First and foremost I understand my main responsibility as delivering value as fast as possible in the long term.
By delivering value I mean adding, changing or removing features, that "business" requested, but also things like:
- improving processes around me, both technical, like application deployment, and business, like simplifying stock management,
- proposing and introducing new techniques and technologies whenever I feel that they will improve things,
- sharing knowledge within and outside of the team (blog, mentoring, pair/crowd programming, etc.).
"As fast as possible" is self explanatory, I want to deliver as much as possible using as little time as possible.
"Long term" part needs a bit of clarification, because it might seem like contradicting with previous part. As studies show (see below), when it comes to TCO for software, most of the money is spent on maintenance, not on development. That means, that thinking in "short term" and "long term" might be different. Sometimes a "quick and dirty hack" today, just to have something done faster in short term, would mean, that in long term we would be slower. We would either have to anyway solve the problem correctly or be constantly hit by our bad solution. That's why I take as my obligation to think long term, and to try to find solutions better in long term, even at a cost of spending more time in short term.
One of the main factors, if not THE factor, leading to increased long term development speed is understanding.
Understanding and readability
You can only do things, do them right and do them fast if you understand your environment, for example code. Readability, not only of the code, but also things like test scenarios, greatly eases reasoning about what the application is doing, so it's far easier to add or change functionality or do an investigation "why the thing that happened happened". Readability cannot be replaced by anything, especially not by TDD/BDD techniques or any other kinds of tests. Those are only safety nets and can only protect against issues in currently implemented features, they're providing no help whatsoever to changing the code. You need to know for sure how the things you're doing now to the code, documentation, test scenarios or whatever else will affect the system. But even more importantly you need to make sure, that your changes don't hurt understanding of everybody else who will be reading or changing it. As every line of code (and not only code) is written once but read multiple times it's worth spending more time on writing it in such a way, that it's easier to read later on.
How to achieve code readability has a short answer: code quality.
Although quality code is much more pleasant to work with than all those "big balls of mud", it's not a goal on its own, it's a way of reaching goals mentioned above. Luckily enough there are already standards or rules for code quality.
Some time ago our industry finally started creating standards. Those standards are all those rules like SOLID, DRY, KISS or YAGNI, techniques like TDD or BDD or "templates" like design patterns or hexagonal architecture / clean architecture. I believe, that although nobody proved them to be correct (yet), they're being referred to by many developers as something that enables them to develop faster and with better quality. Also, up until now, I haven't found any other set of rules or guides, that would be as complete as the things mentioned before. People are reporting, that other approaches or principles are working for them, but usually no one else is supporting such claims, or is supporting them partially, they're more of exceptions than rules. They also doesn't form a system, that is they can't be put together and applied all at once, they will probably contradict one another in a few places.
I admit, it's a homework for me to try to find out how good those standards are, do they really provide what they promise and are they really the only way. For now they work for me, but I might be a subject to confirmation bias and be missing other, important points ov view or approaches. But do expect more detailed, in-depth, filled with hard data and less beliefs posts soon.
The right mindset is required to have code of good quality. But code quality is not something that can be achieved, it can only be asymptotically approached. What can be achieved is code of good enough quality. Moreover, as ideas, languages and tools evolve, untouched code, even if of good quality yesterday, will be of worse quality tomorrow.
Quality degradation starts always the same way, explained by broken windows theory. In short: once someone consciously ignores or violates quality, an exception is created, that others are likely to follow. Eventually exceptions become regular behaviour, because they're "easier".
All this makes code quality a thing, that we need to fight for all the time, every single time we touch the code. By separating the tasks related to improving quality we risk, that we will not get the time for them. There is actually a place for those tasks in a regular development process: refactoring step in TDD/BDD cycle. It is as important as the other two, but quite often forgotten. One can also apply boy scout rule and always commit code with even only a bit better quality that was checked out, even when this particular piece of code wasn't touched during feature implementation.
The ideas mentioned here are also mentioned in Software Craftsmanship Manifesto. They're also part of a forming software professionalism movement or definition.
It's nothing new
All or most of the things mentioned above are not new, most of them can be found in agile principles that were formulated in 2001. Even ideas expressed in Agile Manifesto are not new, see for example below for NATO report. A. J. Perlis in 1968 said “A software system can best be designed if the testing is interlaced with the design instead of being used after the design”, so TDD wasn't discovered in 2003 by Kent Beck, it was more "rediscovered", see discussion here.
Unfortunately, the World is not perfect and from time to time we're asked to do something fast in short term. There are cases, where such requests are valid, for example the law has changed and we need to adapt our systems before an externally set deadline, or a problem occurred, that we couldn't foresee, the company is loosing money and we need to react immediately. In such cases we should be cutting some corners to deal with the situation, but we should also take care to bring the quality back after the issue has been dealt with.
A few additional notes from me
As mentioned above I'm not fighting for clean code just for its own sake, for me it's a way of ultimately being able to deliver fast consistently. It's one of Agile Manifesto's principles: "Agile processes promote sustainable development. The sponsors, developers, and users should be able to maintain a constant pace indefinitely.". Out of all rules of clean code, currently mostly discussed and stressed, in my humble opinion, are separation of concerns (a.k.a. single responsibility principle) and simplicity.
This post is far from being complete, I tried to focus on the most basic problems. But remember this: always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
Software engineering / professionalism
NATO Software Engineering Conference report - although the conference was held in 1968, it contains things like:
- description of iterative process of writing software,
- statement, that best systems are written by small groups,
- staring development from a skeleton, which is used to explore problem domain and technical solutions,
Total cost of ownership
- Out of the tar pit - scientific paper focused on complexity and how to handle accidental one
Videos / presentations to watch
- Engineering You by Martin Thompson - mostly about mindset, but also mentions other things like readability
- Simple made easy by Rich Hickey - mostly about simplicity
- TDD, where did it all go wrong? - how very wrong we're sometimes thinking about TDD