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.