This is actually probably gonna be the first of several blog posts on this topic. Turns out I got a lot to say. Also I decided to do lots of shorter blog posts instead of one giant one. I sincerely hope this is useful and someone, anyone, actually reads it. Anyway, momentary self-doubt aside, let’s get to it…
This article is just a starting point, based on just a very small amount of real world experience. Treat it with suspicion. On the other hand, we’re just gonna touch on basics here so it’s not like anything in here is gonna be very controversial. Incidentally if you’re not into the project management side of software development that’s fine but… you should still try to get a basic understanding of it. It can only add to your skills 🙂
Two simple rules
When you create software there are several aspects to pay attention to.
- Requirements gathering – to understand what needs to be built.
- Design – to meet the requirements.
- Code – to implement the design.
- Test – to validate that the requirements are met.
- Maintenance – fix bugs once the software has been released. personas con diabetes pueden tomar ivermectina
Viewing this as a one way process results in waterfall development and viewing it as a cyclic process results in agile development.
A rule, an absolute law of software development, is that it’s easier to change things at earlier stages.
- It’s easier to add a requirement than it is to change a design.
- It’s easier to change a design than to change code that already exists.
- It’s easier to fix bugs at the time of coding than to track them down and fix them after time has passed.
From this rule flow two more rules, I’m gonna go ahead and grandly assert that they’re pretty much fundamental to all successful software development:
- One should put a lot of effort into requirements gathering and careful design up front, since getting these as right as possible from the start will save much time and effort later, and the cost (in both time and money) of investing in these is tiny relative to the cost of redesign to match a previously ignored requirement or recoding to match an updated design. If you do have to redesign and recode and the cost of these things is too prohibitive then you end up with an ugly, bolted together product that, like the oboe, is an ill wind that nobody blows good.
- Feedback loops must be as tight as possible. This means:
- Code must be tested as close as possible to the time it was written.
- Software must be put into the hands of end users as soon as possible, to identify missing requirements, incorrect design choices and bugs. Ideally you catch bugs in the testing phase but a design bug or a missing requirement can only be found in production, so you have to get the software to end users ASAP so that you can quickly provide that feedback to the development team. Once that feedback is received it must also be acted on quickly, so that the virtuous cycle can repeat.
A lot of people get the memo for either the first of these rules or the second. Both are important. Ignoring the first rule wastes time and resources, but ignoring the second rule is worse since even if you’ve carefully designed and gathered requirements, if your users don’t see software quickly then you still don’t know for certain whether the stuff you’ve sunk six months of development time into is fit for purpose or whether you’ll have to redesign it.
These rules might seem super basic but in fact it’s amazing how often they’re actually ignored completely. Software projects are commissioned where the requirements are dictated by some upper level manager who knows the problem domain well but last worked in an operational role 20 years ago. A delivery date and budget is assigned and the software is not sent to end users until that date is near. It’s a crazy way to risk project failure but it happens all the time. My belief is that software development is a bit alien to most upper management and they don’t realise that the process is fundamentally different from e.g. commissioning a bridge to be built. That’s why we present these rules as these mystic sayings handed down from the Gods, instead of what they really are, just trivially true things – because teams have to understand their importance and to push for them to be practiced – they won’t just happen by themselves.
People and Workflows
Teams are made of people. Here’s a simplistic look at the roles in a development team. Developers write code. Testers test that the program works. Business Analysts (BAs) are in charge of knowing software requirements. They need to chat to stakeholders to make sure that the software is fit for purpose.
A typical workflow would go like this:
- BA gathers requirements and creates a specification.
- Developer writes code to the spec.
- Tester uses the spec to develop test cases and checks that the software performs according to the spec.
Although I’ve just presented you with a separation of roles I personally believe that everyone on the development team should be capable of and expected to fulfill all these roles. I think that much misery, pain and sadness in software development can be traced to these roles being separate. A developer who codes to a spec without understanding the problem they’re solving is gonna be far less effective than one who does understand. A tester who tests to a spec without knowing why the spec is the way it is, is going to be similarly less effective. A BA who makes a spec without regard to the technical implementation details… you get the picture.
It’s far better (IMHO) if the dev team is just one or two managers and those kinda people, and the rest are all developers who can test or write specs as required. Just one rule, developers shouldn’t test their own work. When you’ve developed a feature you often can’t see the flaws and hidden assumptions in your implementation.
We have good tool chains that support software project management. All software projects nowadays will use a similar basic setup.
- You need a git repo. Keep your code base in there. Also keep documentation that changes with the software there. This would be user documentation as well as things like build instructions.
- You need some kind of project documentation store where requirements, specs and so forth can live. Everyone on the team should have access to this. para que se toma ivermectina A lot of Atlassian projects use confluence, but any project wiki will do just fine. Even just markdown in the git repo will work, as long as everyone understands it, has access to it and can edit it.
- You need an issue tracker. The tracker should support a Kanban board, milestones, assignment of issues and classification and prioritization of issues into bugs, features, tasks and so forth.
- You need a build agent. Something like bamboo or Jenkins. This is something that kicks in very time you push to master and builds the code or runs tests. The idea is that your code must always be in a state that it’s building. That way if you need to suddenly deploy you don’t have to fix bugs before doing so.
The entire team needs to use these tools and they shouldn’t be circumvented. For example developers should not work on anything that’s not tracked on the issue tracker. If there’s a bug, there must be a ticket and it must be tracked. There must be no sneaky untracked development of someone’s pet feature. There mustn’t be a situation where half the dev team uses the issue tracker and the other half don’t. Again, this is trivially true but humans are dodgy and we take shortcuts where we can, so much like keeping vigilant watch over the institutions of democracy, if you don’t want your software development to resemble the dying days of a banana republic you must maintain the Rule of Law.
Us developers, we love us some buzzwords. DevOps is one such word. It’s pretty straightforward. The central idea is to get software from the development team to end users as fast as possible, and to send feedback the other way also as fast as possible. You do this mainly by automating your build process and implementing continuous deployment, which basically means deploying new features and bug fixes as soon as they’re ready and not waiting for some predetermined release date or some other such madness.
- At all stages of development you must always be able to build a production-ready release in a short space of time.
- You achieve this by cutting release branches off master periodically and maintaining them as separate branches. Fixes on these released branches are then merged back into master and the fixed release branch is deployed to production.
- In the meantime new features are merged with master without affecting the readiness of the release branches to be built and deployed to production.
- When the new feature is ready a new release branch is cut.
- Releases should be numbered using semantic versioning.
- Try to get all the end users onto the latest release branch if possible. That way you don’t have a tangled mess of deployments to deal with when you discover some mission critical bug and have to figure out which customers are affected.
Ja, that’s it for this post. I’ll follow up with a more detailed look at some of the stages of the SDLC (Software Development Lifecycle). That’s the current plan anyway.