A while ago I was asked about my opinion of key factors for successful and quality software development. There are a few lists published from more or less famous programmers, like this excellent collection from Jens Rantil or this from computer game development legend John Romero (scroll down to the bottom of the article).
Both of these lists do not separate more general, organisational topics from detailed, programming design specific guidelines. Both aspects are important, but the latter ones can be implemented within a development team, while the former topics might need to be addressed to a higher organisational level and though might be, depending on your organisation, more difficult to implement.
I won't mention evident best practices, such as "use a version control system", "set up a continuous integration", and so on, I assume nobody will argue about those points.
Organisational key factors
- Code Reviews: As a development team member, review code, as much as possible, not to control your team members, but mainly for knowledge transfer. If several people are working on a system, it will help to prevent re-inventions and will save time on further development if the team members are aware of the changes done to the code they are working with.
- Mentor-ship in heterogeneous teams: Heterogeneous is a complicated word for a simple fact that you will face in most teams: there are developers with more overview able to write better code with less errors in less time than others. One of the reasons is the varying amount of experience, so take measures to keep all developers on (your) track, using e.g. pair programming and code reviews (with at least two developers in front of a screen forcing them to talk directly, unlike above, without code review tools), short training or live coding sessions, ...)
- Be pragmatic: No ideological discussions. Strive for pragmatic solutions. Software development is a business, not an art, you earn (or your company earns) money selling solutions, not the most beautiful piece of code or technology.
- UX: If your software needs an UI, especially a web based UI, try hard to get an UX expert which takes the principle UI decisions, not the so called designers. Most designers (all I met) are perfectionist about their layout and design, but they often don't think beyond it. This means that they don't think about what should actually happen if the user clicks on their so carefully designed button or what should happen if something goes wrong.
Software design best practices
- Unit Tests and Test Driven Development: Unit testable code leads to good software design and allows refactoring
- 'The Run Script': Instead of documenting extensively and describing how to run your project, create a script running your software on a developer's machine (I recommend container or virtualization technologies (Docker, Chef, Ansible, ...) over build systems (Maven, Gradle, ...), if possible, out of two reasons: First, you have a running example of a possible deployment scenario; and second, a virtualized container avoids side effects with your local system.
I ususally set up both.
- Development environment: Make sure your development environment (if the software needs more than the run script), can be set up from scratch automatically.
- Further Automation: automate all tasks you have to do more than once, this includes acceptance tests/web tests. Automating will not only save you time, it will make your environment more maintainable (testable). This implies automation of release todos.
The three bullet points above, unit tests, 'the run script' and setting up the development environment are parts of automation, as well.
- Encourage innovation: With good and motivated developers innovation will happen, if the technological framework and project set up won't stop it. Assure that it is...
- easy to switch development branches (use a clean repository)
- easy to rollback your system
- easy to set up a new environment from scratch (see above)
- possibility to use whatever IDE to develop, do not force your team to use one OS/software/IDE
- Avoid inheritance...: Inheritance causes way more software design issues than you might think. There are lots of articles out there about this issue, consider Robert Martin's Book and Gang of Four's Design Patterns, as well.
- Operation awareness: You may call it DevOps or not, keep your developers aware of or make them take part in the deployment and operations of the software they write, this will help them to keep in mind topics like caching, distribution, synchronization, sessions, monitoring, performance, redundancy, concurrency, ...
- Keep your Code clean: Read, understand and follow Robert Martin's principles in his Books Clean Code and Clean Coder.
As developers spend about 10 times more time reading code than writing code, you can imagine that speeding up the reading process will help your efficiency.
- Frameworks: For the same reason: choose a framework not (only) considering speed of development (unless you are prototyping), but considering the cleanness of it's architecture and it's principles to keep your code clean.
- Be aware of the Pareto principle, which is so true in software development. Keep this in mind when estimating and when communicating that "80% of the task is done".
- Be pragmatic: Again.
- No ideological discussions about technology.
- If the 20% of the work of a certain task which needs 80% of the time is not really necessary, don't do it. Strive for simplicity. Remember: Quality, Tests and clean code is no option!
Thanks to Don Swinscoe (@dswinscoe) for re-reading and correcting this text as a native speaker.
Although code reviews are a development team's topic, the organisational conditions has to be set up. Code reviews need time in which developers are not writing code. ↩︎
Programming has it's own aesthetics, creativity and beauty, but, just as with a carpenter, who's work is often a result of design, beauty, function and form, , so too in Software Development. The money is made with usable products, not (only) with beauty. Although beautiful code is, in most cases, part of a working, maintainable and sustainable solution. ↩︎
I remember my discussion with a (very recognized) designer, clarifying some points regarding the layout for a front end project I was supposed to implement. I was trying to convince him to use as much yet existing layout components as possible (e.g. material design components), "maximizing work not done". His answer: "Well, that is not exactly my goal, from a designer's point of view". This is totally correct, and that is ok, if you are creating a piece of art or similar, where you need something different, for whatever reason. But that's not necessarily the goal for good UX, and in most cases, it will make the implementation more expensive. Eventually it depends on what the customer is asking for (and is willing to pay for). ↩︎
Sorry, designers, this might a bit exaggerated (but only a bit), but that is my experience. ↩︎
There are two excellent articles about this concept from Thoughtworker Pete Hodgson in two parts, called "The praise of the ./go script, part I" and part II. I prefer to call it "run" to avoid confusion with the programming language or the Continuous Delivery Server. ↩︎
My nightmare regarding "dirty" repositories was a web shop project using IBM Websphere Commerce. Based on the sample implementation of IBM, only new and modified resources were checked in (to save repository space). This lead to about 20,000 unversioned files in your project root, there was no .gitignore maintained. There was no way to do a "clean checkout", you had to ask another developer to copy his development workspace, if you needed a new, working one. Estimated about 30% of the developer time was spent only to keep the development instances running, fixing errors, upgrading to new versions of IBM Websphere Commerce... fighting against the system. ↩︎
http://blogs.perl.org/users/sid_burn/2014/03/inheritance-is-bad-code-reuse-part-1.html, ... ↩︎
(Un)fortunately this decision will mostly be taken by other people (product owners, customers, stake holders). This decision has to be accepted. But you can make it transparent to them so that they have better information to decide if they really need this few pixel alignments more, this special animated checkbox, or special features that automatically detect the mood of the users.
But we, as professional software developers have to consider that many of those special features (aside from pixels...) may save time to others using this software, even if they are using it in a way this software was never designed for. But that is seldom their fault. ↩︎