When working on an error-driven development project, there is a tendency for the people in the team to focus outwards when trying to finding this sort of problems. This is of course a natural response when a team comes under pressure (aka. “Circling the wagons”), but it’s not really a good response, since it won’t help solve the problems.
In my opinion there are two types of problems which can be related to the people in the team.
1) Qualifications, competences, and inter-personal skills of the team members
2) Roles of the team members
Of course, as always, both sorts of problems might be in play at the same time.
This post will only focus on the first type of problems, while my next post will focus on the roles in the team.
Qualifications, competences, and inter-personal skills of the team members
When a project starts up, a great deal of attention is usually given to the people who become part of the team, since these people will to a large degree create the fundaments of the system, and help shape the future development in the project.
This allows for a false sense of security, since everybody assumes that the people who were picked had the qualifications and competences required to do their job. This is unfortunately not always the case.
An example, which I’m always presented for as a consultant, is the case where there is a key position that’s filled with an external ”expert” (read: consultant with documented experience). Given the fact that this expert obviously have the qualifications (documented experiences in the position), it’s assumed that the expert also has the competences for the position. This is not always the case. Sometimes they have been lucky in the past, and not run into problems; at other times they might have embellished their résumé (putting too much emphasis on one aspect on their work, without making clear that this was only a minor aspect).
Since the external expert was hired exactly because there were no-one available who qualified, there will be no one around to ask questions about problematic decisions.
At some stage, it becomes clear that the decisions might be sub-optimal, to put it mildly, and people will work hard to either compensate for the problems they cause (the typical scenario) or actually have to re-do the work (less typical, but sometimes the better scenario).
I should add that while it might sound like I am trying to insinuate that people like external expert are lying about their qualifications or competences, they might genuinely believe that they are good at what they are doing (see my post on the Dunning-Kruger effect on my other blog for more details on why this could be).
All what I wrote about the hypothetical external expert can go as well for internal team members who misjudge their own qualifications.
Later, when the project has run into problems, more people will be added to the project, without as much focus on their skills, which might cause similar problems.
Here are some steps to avoid these problems.
Peer review
Peer review is of course well-known from scientific publications, but in reality, there is absolutely nothing wrong in doing the same with systems architecture, software architecture, and code. What it simply means, is that something is reviewed, by someone on a similar level (a peer), to find obvious flaws, before it’s accepted. It doesn’t mean that there won’t be any errors, but it means that at least one other person have gone through the product, and tried to understand it, before it’s accepted.
The more fundamental to the project the product is (e.g. the overall layering of the software architecture) the more important it is to get it peer reviewed. Any flaws in the product will cause a lot of grief later and the earlier they are removed, the better.
In case that there is not anyone inside the project who are able to do the peer review, try to look outside the project. Is there anyone else in the same company who can do it? Or can you hire someone for that particular job? The latter option will cost money, but it might save a lot in the long run.
Ensure that the team members have the necessary domain knowledge
Unless you work for a company which only makes a certain type of systems, it will always be necessary to have some kind of domain knowledge when developing a system. It’s not necessary for the developers to know every detail about the domain, but they should understand the fundamentals, and they certainly should understand the details about what they are implementing.
How can you realize that what you’re doing is not making sense, if you understand neither the problem you’re trying to solve, nor the solution to the problem?
In my first blog post in this series, on testing, I made one recommendation on how to ensure that people had the necessary domain knowledge.
With regards to the test cases, my general suggestion is that they are not written by technical people, but rather by people with an understanding of the business domain. Optimally they should be written at the same time as the requirements or at least before the coding really start, and only be in general terms. Before the developer starts developing, he or she should read the relevant test cases, making sure that he or she understands the requirements as stated in general terms. If there are some business concepts that appear unclear, it’s possible for the developer to acquire the necessary domain knowledge before starting on the development.
This is one way, but there are of course others. How you do it, depends on the project and the people in the team. It might require a course, or it might be solved by having one of the end users close at hand, ready to answer any questions which might pop up (something which I would recommend anyway).
Only take on new people if you have time to integrate them into the team
Time after time, projects run into trouble, and management starts throwing more people at the project, in the hope that it will make it possible to finish on time.
That’s not going to work – it just won’t happen.
Adding a new developer to a team is not cost free, and adding several developers at the same time, can be extremely expensive. A team which has worked together for a while, knows each other, and often runs smoothly, even if there are problems with the project as a whole. Adding new team members, without given thought to when and how that’s done, will cause problems.
In 1965, Bruce Tuckman proposed the Forming – Storming – Norming – Performing model for teams, where teams move through different phases (see Wikipedia article). Every time new group members are added, the team will get thrown backwards through the phases, and it will take a time for them to re-group.
Of course, if the team is not running well, adding new team members might be less of a problem, but then, there are probably other issues which should be addressed as well.
Don’t be afraid to get rid of people from the team
This is probably the most controversial of my suggestions, but I know that many people will agree on this.
People in teams depend upon each other, and if a team member can’t get along with the others, or underperforms, it can ruin the entire team. If it appears that’s the case in your project, try to talk with the team member about the problem(s), and see if there is something which can be done, but if there isn’t (or if the problems continue) then don’t be afraid to get rid of the team member.
It might cost you a member of the team, but you’ll find that a good team will perform a lot better than a team which doesn’t work properly. This difference will more than compensate for the loss of man-hours.
Don’t consider mentoring a cost, but an investment
Unless you’re very lucky, not everyone in your team will be experienced and excellent developers when they start on the project. This means that they will have to learn while working on the project.
Learning while working on a project means two things:
1) They will make mistakes
2) They will draw upon the other team members to help them solve problems.
When the going is rough, it’s easy to resent the time the experienced team members have to use to help the less experienced team members. Don’t do that. Consider the time spent on helping the inexperienced team members an investment, helping them reach a level where they can work on equal level with the rest.
If it gets out of hand, boundaries needs to be set, but as long as the experienced team members’ performance doesn’t suffer too much (you’ll have to decide what this constitutes), I recommend letting the other team members draw upon them whenever is necessary.
Create an “ideal” code example
This is something I saw working with success at a customer. They had some general architecture and coding guidelines for the whole company, but realizing that each project would have differences, they also used a concept called “the good code example”. This was a code example in the projects, showing how a typical code implementation would be done correctly in that particular project. The example had to be picked with care, to be representative, and it had to be updated every time changes were made to the coding standards in that particular project, but it served as a great references.
Every time a new member got added to the team, they were given the code example, and told to try to understand it. This worked great for giving people a basic understanding of the software architecture they were going to work in.