Building the Effective Software Team


In today's streamlined development environments, an effective software development team requires engineers who can get the job down with low levels of supervision and who can make efficient use of existing code through reuse techniques. This paper pays specific attention to building a team skilled enough in C++ development to follow a given plan or design with minimal supervision, using the a given set of object libraries, for example those developed as part of a development project.
There are three components necessary to create an effective software team: personnel selection, personnel training, and team stewardship once created. First, people that can learn the desired skills need to be made available. Second, the people must be trained; training is often most effective when it involves actual development work, rather than synthetic classroom-type activities.
Last, once the team is created, there must be leadership that can effectively maintain an environment that is desirable form the team members' perspective and efficient in terms of resources and lack of distractions, such as reassignment to different tasks. Often it is the third component that is the most difficult to provide, but that is not an issue that can be addressed here, for it is dependent upon many outside factors.

Part One: Acquiring a Development Team


When attempting to build upon an existing development team for a given project, there are a number of considerations, both personal and technical, that must be taken into account when attempting to determine if a person is suitable for the team. One thing that must be determined before even the first interview is how short the time line for development is. The shorter the time line, the more technical qualifications that are needed, and it is unfortunate that so many current projects give themselves such a short time line that they must have completely trained and experienced developers to meet their milestones.
On the personal side, the candidate must be a 'self-starter'; this is a reflection of the short time line, rapid-development environment that is often the norm. Team members will often have little patience for people who need constant prodding to move forward. This is reflected in the trade-off between vanishing and hovering. A vanishing team member is given a task and 'vanishes', only to reappear when the task is completed or a complete failure. A hovering team member is given a task but returns for help upon every syntax error or with every design decision.
Pride in one's work is also important. This is more than being defensive about prior work, this is a real desire to see it improved. Often this can be noticed when a person has a realistic opinion of the status of a completed task. A team member who has developed a component of the system should be familiar enough to see the advantages and drawbacks, while being reasonably certain that they have created an adequate solution. Warning signs are attitudes such as 'well, it works, so it must be good enough' or an opinion that a given solution is as good as it will get.
Interpersonal considerations are very important, especially when adding to an existing team, but are often overlooked. To succeed, team members must be somewhat comfortable with each other at a personal level; members who don't fit the team profile will often reduce the efficiency of a team, regardless of their technical ability. Most people will work well together given a referee - a manager skilled at interpersonal facilitation - but the trick is to filter out the people who cannot function in the team environment.
While personal qualifications often cannot be determined until after a team member is part of the development environment, technical qualifications can be determined earlier. An important difference between technical and personal qualifications is that technical skills can be developed, while personal skills are usually relatively set. The qualifications here are listed in order of importance. In general, the skills build upon each other, so as skills are dropped the training time increases. Given with each level of skill is a rough estimate of how long it takes to become workable at this skill, given previous skills. In a nutshell, it will probably take 8 to 10 months to ramp up a developer from scratch, scratch being a year or more of experience in a language other than C.
  • Software development background/UNIX knowledge. Without at least a year of software development background under their belt, new team members will be too far behind the curve to come up to speed in any reasonable time. A UNIX background, on the other hand, is not mandatory, but without UNIX skills, time on the order of a week or so must be spent to become familiar enough with it to go further. Fortunately, the UNIX environment and tools can be reasonably picked up along the way, though this will add 15-25% onto any following times until some level of familiarity is developed; this usually only takes a month or two.
  • C language background. While helpful, a C language background is not mandatory, as many languages (though not all, it must be stressed) are essentially similar. Without any C skills, a basic C capability must be learned, which will take from 8 to upwards of 12 weeks dependent upon existing knowledge and skill level of the developer.
  • C++ background. Development experience with C++ is not necessary, but without existing familiarity there will be a ramp-up time to develop the skills need to perform basic tasks. Assuming an existing C skill, this will be 4 to 8 weeks depending on the level of skill of the developer. An important note here is that this will give the developer 'C++ as a better C' skill, not object-oriented design skill.
  • Knowledge of the object libraries. Without existing knowledge of the project's existing code, the new engineer on a team is handicapped. As an example, it takes approximately 2 to 4 months to become familiar enough with the DMTool object libraries to perform basic tasks. This time period is dependent to a large extent on the size and complexity of the libraries in use.
  • Object-oriented background. This is a quite nebulous buzzword. An object-oriented background is not particularly necessary except for the central members of the design team. With a large enough development team, not all members of the team are involved in the design. However, if a team member is slated to become part of the design team, it will take anywhere from 2 to 6 months to become reasonably proficient in object-oriented design.
    In a nutshell, it will probably take 8 to 10 months to ramp up a developer from scratch (a language other than C ... Maybe copy this up top). More commonly, given a candidate with C skills, it will usually take 3 to 6 months for them to become an effective member of the development team, capable of implementing non-trivial parts of the system.

    Part Two: Training Members of the Team


    Half of the work is choosing the right candidates. Unqualified candidates are frustrating for both the teacher and the new team member. Often the teacher has milestones to meet, and if the person being trained is unqualified for a given schedule then not only will the team member doing the training be pulled away for too long to meet their milestones, the team member in training will not ramp up in time to be useful. This is not good for the morale of either team member. It is essential that the proper time for training be worked into the schedule and that schedules not include unrealistic demands for personnel.
    There several major considerations for training. It is important for the trainer to give ownership of the training tasks to the new team member. Any successes should be for the trainee, not the trainer. The training environment should be goal-oriented; people will come up to speed more rapidly and will be more comfortable if they feel they are contributing. Lastly, the trainers must be willing to spent the time. Training will be a time drain, often major, but it is a necessary facet of team membership, and if existing team members cannot take the time to train new members, the team will stagnate.
    The most important thing to do first is get the new team member comfortable with the team. Exactly what this entails is usually dependent upon the social aspects of the group, but often inviting new members to lunch or to other activities is a good start. They should be encouraged to ask questions, and this should be more than lip service; it is important that questions of new team members, no matter how trivial, be answered on an even level with the design considerations of other developers.
    In giving ownership of tasks to a trainee, the sink-or-swim approach is very poor. A task that is over someone's head rarely leads to a success; more often it leads to frustration. Rather, small tasks should be chosen initially. Optimally little, if any, design work is involved; these tasks are intended to get the new team member familiar with the system. One approach is for the leader to present a partial design to the trainee and to show exactly where the current system must be modified. The new team member should come up with a solution, but not go forward until review by the mentor. Over time, the reviews are less thorough and less often, but initially the mentor should work quite closely with the trainee.
    As mentioned previously, it is important for there to be a specific goal. This should be a piece of the system that can, in effect, be pointed to by the new team member when completed. Giving a team member a task such as 'become familiar with the system' does not accomplish much; most projects have far too much code involved for this to be practical, and there is not a definite completion point. When they are adding a specific feature, it will be reasonably obvious when they have finished.
    Training takes time. This is not just the time for a new team member to come up to speed, but time for the teacher, who should be answering questions, demonstrating tools and features, and reviewing design work. The teacher should initially make sure the new team member is familiar with the development environment. This involves not only initially configuring their environment, but also making sure the new person is aware of all of the tools that are available. For example, sending a new developer off on their own without first making sure they know about use of a debugger can be very unproductive.
    When the person learning has questions, they should always be answered by the mentor. This is important: teaching, when done properly, can be just as instructive for the teacher as the student. If the teacher does not know the answer, they should find out and return with the solution rather than simply shunting off the question to someone more knowledgeable. This does not mean the teacher cannot ask someone; this merely implies they should rarely use the "I don't know, go ask Bob." While convenient, this does not encourage the new team member to ask their teacher questions, it encourages them to ask Bob questions; in addition, the teacher still does not know the answer. Also, it should be important to differentiate between immediate questions and non-immediate questions.
    Immediate questions should always be asked either in person or by phone; they are questions which must be answered before the new team member can continue with their task. Non-immediate questions should be asked via e-mail or over an xrn newsgroup; this will prevent constant interruption of the teacher. It is no less important that these questions be answered, but it is important for the new team member to learn which questions must be answered right now versus which ones can be answered at their teacher's leisure. If the teacher follows these guidelines, initially they will spend a lot of time with the new team member, but the time they must spend will drop off relatively quickly after the initial learning phase.
    Finally, it is important for both the teacher and student to be aware of the materials available. Often a project will have a library of books and reference materials; these can be very helpful. In addition, tools such as answerbook, dbx, dbxtool, Emacs, email, grep, man, nm, Purify, Sentinel, and xrn can be invaluable; the teacher must make sure the new team member is aware of what is available and how to use it. The project may also have internal test utilities beyond the system level utilities mentioned above; these can be just as important to a new team member.

    Part Three: Maintaining the Team


    There are several realities that must be faced when planning a project, especially when specific names are not used in the development plan.
    It is often difficult to retain the people assigned. The more skilled developers are, the more demands there are for their time. Often it is not a matter of them 'going away', but rather the subtle (or not-so-subtle) drains on their time; what would take them 1 week working full-time might take 1 1/2 to 2 weeks of real time. There might even be a week where they work some other task in the middle.
    Qualified people are difficult to find, and will continue to be until more are trained. Part of the reason for this was mentioned previously; too often schedules are written as if the most skilled developer were performing the task, even though it is rarely that person who actually does the work. This leads to frustrating schedules for the people who do have to do the work. It also does not allow sufficient time for training, because the experienced developers end up so overworked that they feel they cannot afford to spend the time helping other, less experienced team members.
    Finally, the tides of funding, especially on IR&D programs, affect people in a big way. Not only is it difficult to retain people when all funding is lost intermittently, but many people who would otherwise consider such work desirable not consider the positions due to the uncertainty involved.

    So What Do We Do?


    There are several things we can do. First, when dealing with relatively new technology such as C++ or object-oriented development, avoid making schedules that require a complete team of experienced developers. Allow space for less experienced candidates; while this may cause longer schedules, it is more realistic in terms of staffing and will pay off better long term
    Be certain to pick the candidates carefully. This depends as much on how much time is available as on the potential team member's qualifications. A C developer, no matter how experienced, is unlikely to be of much use in a schedule that allows a month for anything but a trivial task.
    Encourage questions, and encourage answers. New developers need to feel comfortable that no question will be treated as a stupid question, and more experienced developers will find that they will continue to learn by answering the questions asked of them rather than shunting them off.
    Finally, review of a new team member's work is critical. If they are making mistakes, it is highly unlikely that they are intentional, and the sooner such design practices are corrected, the less likely they are to be ingrained in that person's development style. Tools such as email, xrn, and even the phone are invaluable in this respect, and one-on-one design reviews can go a long way towards correcting incorrect or even difficult to understand design efforts.
    Some trainees respond better to tongue-in-cheek comments on their code, while others may need more subtle suggestion along the lines of "perhaps we could think about doing it this way..." It is important that the teacher realize what technique is better suited to the individual. When conducted properly, this is one of the most effective teaching techniques available.