Journal Articles
Browse in : |
All
> Journals
> CVu
> 175
(15)
All > Journal Columns > Professionalism (40) Any of these categories - All of these categories |
Note: when you create a new publication type, the articles module will automatically use the templates user-display-[publicationtype].xt and user-summary-[publicationtype].xt. If those templates do not exist when you try to preview or display a new article, you'll get this warning :-) Please place your own templates in themes/yourtheme/modules/articles . The templates will get the extension .xt there.
Title: Professionalism in Programming #34
Author: Administrator
Date: 06 October 2005 05:00:00 +01:00 or Thu, 06 October 2005 05:00:00 +01:00
Summary:
The most important single ingredient in the formula of success is knowing how to get along with people. (Theodore Roosevelt)
Body:
The most important single ingredient in the formula of success is knowing how to get along with people. (Theodore Roosevelt)
The gory business of 'paid' professional programming is, depending on how you look at it, either an exhilarating chance to do what you love for a living, or a depressing experience where management incompetence, inept team members, and bad planning conspire to create mediocre software, leaving you no chance to fix the problems. Welcome to life in the software factory. It's a large place, and (however much you'd like to believe it) you don't live there alone.
Being a good software engineer means more than just being a good programmer. You might be able to compute PI to ridiculous accuracy in less than five lines of code. Well done. But there are many other skills required. And one of these is team working
In this series of articles we'll take a long hard look at the Real World scenario of programming in teams. Good teamwork is vital to the survival of a software project. An ineffective team will quickly stifle any software development activity, leaving progress to the heroic efforts of a few dedicated individuals working against huge odds. To work out how write good software we'll examine teamwork as it applies to us, as programmers. We'll look at what constitutes good teamwork, and how we can be more effective in our teams.
In this first instalment we'll investigate what our software writing teams look like, what they do, and how they fit into the software factory. We'll make some observations about what characterizes good and bad software teams and determine what personal skills, tools, and organizational structures will lead to better teamwork.
So what kinds of team do we work in? A typical software engineer participates in various levels of teams, each with different dynamics and requiring different levels of contribution. Consider this scenario:
-
You're creating a distinct software component which is part of a larger project. You may develop it by yourself, or as part of a team of programmers: team one.
-
The component will fit into a wider product. All the people involved with this product (including any hardware designers, software developers, and other non-engineering roles such as marketing) form team two.
-
You are also part of a company that may be working on many different products simultaneously. Team three.
In reality there are more levels of team-manship in any reasonably large software-development company. As programmers, we are most involved in the smaller level of team activity - in our day-to-day development teams. We have the most control and influence over this world. This is the level we are responsible for, where we have authority to make design/implementation decisions and to report on team progress. Programmers are less responsible for the effects of higher level teams, but we are affected by teamwork 'in the large' as much as we are by teamwork 'in the small', even if it's not as immediately obvious.
Development teams sit amidst the many other tribes of software factory inhabitants, and must interact with and work alongside them. This dictates the nature of most of our inter-team interactions. The general shape of corporate team structure is shown in the following diagram:
It is vital to cultivate good relations and foster smooth work flow between these different teams. A problem in the wider software factory structure will really scupper your software development. However, it's outside the scope of this article to investigate company culture and process improvements. In this article we'll focus mainly on development teamwork, under the shadow of this organisational context. That's where most of our time and effort is spent, and consequently where our individual improvement will make the greatest difference. It's the teamwork level that most directly influences the quality of our software
Development team size dictates the dynamic and nature of shared software construction work as much as the team's place in the organisational food chain. A lone engineer is given responsibility for all software architecture, design, and implementation work. In really small outfits they may also have to work on gathering requirements, and create and run a thorough test plan.
As soon as more developers are added to this mix, the nature of the programming task changes. It's no longer just about coding skill, and requires social interaction, coordination and communication skills. This is where your team working skills will affect the software you build -- for good or ill.
There are some factors that clearly characterise good and bad software development teamwork. Cataloguing these will help to set the context for our foray into teamwork improvement. Some can be worked on by individual programmers, but most are things that we have to live with, or try to persuade managers above us to get right.
These are influences that will determine the effectiveness of a software team, and the quality of the work produced. For effective teamwork, all of these factors must be in place:
-
The correct spread of people, with a range of appropriate technical skills.
-
Team members with a range of experience, who are each able to learn from others (a whole team of trainees will clearly be doomed from the start).
-
Complimentary team member personality types -- to succeed the team needs encouragers and motivators not people who will drag morale down.
-
A clear and realistic goal (even better if it's an 'exciting' project that the team members really want to see completed).
-
Motivation (whether financial or emotional).
-
Suitable specifications provided as soon as possible, so each member understands what they have to build, and to ensure that the individual pieces of work fit together.
-
Good management.
-
As small a team as realistically possible, but no smaller. Adding more people makes teamwork harder: there are more lines of communication, more people to coordinate, and more points of failure. We should try not to make things unnecessarily hard.
-
A clear and universally understood software engineering process for the team to follow.
-
Backing from the company, not hindrance and unnecessary beaurocracy.
In contrast, these are sure indicators of a team that is not able to work effectively. Note that this is a mix of internal and external factors.
-
Unrealistic schedules, with deadlines established before the team has scoped their work.
-
Unclear project objectives, and a lack of project requirements.
-
Communication failure.
-
Bad or unqualified team leaders.
-
Badly defined individual roles and responsibilities -- who's responsible for doing what?
-
Individual bad attitudes and personal agendas.
-
Incompetent team members.
-
Management not valuing individual engineers, treating them like minions.
-
Individual appraisals based on criteria that don't match the team objectives.
-
Rapid turnover of team members.
-
No change management procedure.
-
A lack of training, or of mentoring.
Every team is comprised of individuals. A trite maxim splashed across banal motivational posters says: there is no 'I' in Team. If you can avoid vomiting, you'll realise that your software team doesn't exist to serve you. You serve the software team. To start improving your team's performance you can begin close to home - by addressing your attitudes towards the team and your joint development effort. We're not all managers, so this is really the main area that we have any influence over.
Being a high quality programmer requires you to be a high quality team player, so how do you improve? What skills do you need to be an effective team worker? What does it mean to be a 'good' team member?
Teamwork is a skill acquired over time, no one is born with what it takes to be successful in a winning team. However, it is clear that some people are more adept at it than others; it fits their personality and character better.
A different set of technical skills are required from each different development team role. However, presented below are a list of non-technical skills, characteristics, and attitudes that any effective team member really must have before we can even consider program language dexterity or design capability.
Teamwork is dead without communication. Individual parts cannot move as a whole without communication. How can the goal and vision be shared without communication? Projects really do fail because of a lack of good communication.
Intra-team communication occurs in several ways: conversations between individual engineers, phone calls, meetings, written specifications, email correspondence, reports, and instant messaging. Sometimes we even communicate in pictures! Each medium has a particular usage dynamic and is most appropriate for a specific kind of discussion. The most effective communication should involve (or at the very least be visible to) all relevant parties. It should be sufficiently detailed, but not consume too much time or effort. It should be performed in a suitable medium - for example design decisions should be captured in a written specification, not agreed verbally and shared by word of mouth. Code itself is a form of communication. A programmer must be able to communicate well. This requires both good input and good output:
-
to write unambiguous specifications, to describe ideas clearly, and keep things succinct, and also
-
to read and comprehend specifications correctly, to listen carefully, and to understand what they are told.
In addition to intra-team communication we must also consider communication between teams. The classic example of bad communication is seen in most companies, between their marketing department and the engineers. If marketing don't ask the engineers what is possible then they will sell products that the company can't make. This kind of problem is cyclical: once it has occurred once and people have been burnt, the two teams are less likely to talk to each other (due to resentment). It will then happen again and again.
There are many communication methods in our highly connected world, and we must learn to use them effectively, to support and facilitate our team interaction. The key to this lies in understanding their particular dynamics, etiquette, and individual merits.
Best used for communication that requires an urgent response, a phone call interrupts what you are doing. For this reason it's inconvenient to be called for non-urgent matters - use another method instead. With mobile phones we are far more connected than we used to be; this is a blessing and a curse at the same time.
Being audio only, you can't see the other person's face and their subtle body language cues. It's easy to misinterpret someone on the phone, and draw a different conclusion from the other person.
Too many techies are scared of using the phone. Don't be - for urgent communication it's invaluable.
An asynchronous, out-of-band communication medium. You can specify a level of urgency, but email is never immediate - it's not a real-time conversation. It's a rich medium, allowing you to quickly send attachments, and compose replies when it's convenient for you. It is often used for 'memo'-style broadcasts to many recipients. Your email history provides a reasonably permanent record of communications. Email is an immensely powerful communication mechanism.
You must learn to use email as a tool, and to not become a slave to it. Don't open every new mail as it arrives; your coding will get interrupted far to often, with a hit to your productivity. Designate email reading times, and stick to them.
A quick, conversational medium that requires more attention than email, yet one that can be ignored or sidelined easier than the telephone. It is an interesting and useful middle ground.
These are less conversational than email communication, and more permanent. Written reports and specifications are formal documents. They take longer to prepare, and are consequently harder to misinterpret. Written reports are generally reviewed and agreed on, so are more binding.
This is an essential characteristic, and so often lacking in our profession.
The humble programmer wants to make a contribution to serve the team. They don't slack off to let others do all the work. They don't believe that they are the only talented person capable of making a worthwhile contribution.
You can't hoard all the 'good' work for yourself; it's just not possible for one person to do everything. You have to be willing to let another team member contribute - even if it's something you want to do.
You should listen to and value the opinions of other people. Yours is not the only point of view, and not the only solution. You don't necessarily know the only, or the best way to solve every problem. Listen to others, respect them, value their work and learn from them.
We have to be realistic: some people can't help winding each other up. In this situation we must be mature and responsible in our attitudes, and learn to avoid (or learn to resolve) conflict situations. Conflict and animosity breed more and more bad will, and will severely degrade the performance of a team.
However, harnessed and channelled conflict can be a major success factor in your team work. Team mates who stimulate and provoke each other produce the best designs. Disagreement can act as a refining process, ensuring that ideas are valid. Knowing that your work will be cast under a critical eye keeps you focused.
It's important to keep this kind of conflict constructive; on a strictly professional, not personal, level.
This doesn't just mean learning new technical skills, but learning to work as a team. It's not a God given gift. A new team has to learn how to work together, how each member reacts, their strengths and weaknesses, and how to capitalise on individual skills to the group's benefit.
Emerson wrote: "every man I meet is in some way my superior". Look at what you can gain from your peers. Learn from what they know, learn from what they're like, and learn how they react. Learn to communicate with them. Seek criticism from them at all levels, from the formal code review to their passing opinion offered in conversation. Good teamwork builds the project and also builds the team. An important part of 'building the team' is for each member to be learning as they work.
This is tied closely with learning.
If the team has a need that no developer can currently fulfil, and it's not possible to bring in an outside resource, then a solution needs to be found. Adaptable people can learn the new skills quickly to fill the gap and serve the team.
If you are committed to work that you know you can't do, or later find out that you don't have the skills to complete (and you can't realistically learn them in the given time scale) then you should make your manager aware of this as soon as possible.
Otherwise, you will fail to deliver your piece of the project, and the whole team will suffer as a consequence.
Many people believe that admitting they can't do something is a sign of weakness. It's not. It's better to admit your limitations than to be a point of failure in the team. A good manager will provide some extra resource to help you do the work, and along the way you will learn the new skills that you previously lacked.
Having investigated the core personality traits and essential skills of a team-playing software developer, we can now investigate what tools help us to form a functioning software team. There are a few indispensable tools that facilitate collaboration and help to elevate your joint development from chaos to a well-oiled machine. On their own they won't make you a team of commando programmers, but they're the arsenal every crack outfit relies on - the prerequisites for effective software developer interaction.
Even if you're the sole developer on a project, you need a source control system - it's a crucial store of the codebase and its history. When there are multiple programmers it becomes even more critical. Source control helps to marshal who is doing what and when, provides the definitive 'latest code' snapshot, and allows you to manage changes, undo mistakes, and make sure that no one misses source code updates.
Without it you'd need to employ someone to integrate all changes and manage the code. And they'd be more likely to make catastrophic mistakes. Joint development without source control is unthinkable.
We've already looked at what this is, and the specific purpose it serves. However, notice how it facilitates interaction between your development team and the test team. A fault tracking system acts as a pivot between test and development. It helps to organise test and repair work, prioritise faults, assign problems to individuals, and track pending fixes in the software.
The tool can be used to make sure that all issues are addressed and that no work is overlooked. It makes clear which faults are currently development's responsibility and which are tests.
A team needs effective communications support, especially when geographically split. A centralised calendar, address book, and meeting booking system provides a digital administrative backbone.
You also need a mechanism to share documents, both externally supplied documents and your current works-in-progress. A groupware tool facilitates such collaborative work. Without this facility, an inelegant replacement is a well-defined shared network drive.
There are other tools that facilitate group interaction. Consider using wikis (web-based community documentation tools) and internal newgroups (email discussion boards with more permanent storage).
It's important to establish a defined and universally understood development methodology, or work will be chaotic, performed on an ad-hoc basis. One developer will release their code, when another would refuse to let go of it until they've thoroughly tested and debugged it. One developer will halt all coding until they've produced an intricately detailed specification, whilst another rushes straight into prototyping the code. Holy Wars are made of smaller things than this.
A methodology defines the development process details, who is responsible for what work, and how work is handed on. With one, every developer knows how to work as a part of the team, and what's expected of them. You must pick an appropriate methodology, based on the size of the team, the kind of code you are producing, and the talent, experience, and dynamics of people.
To produce any work in a predictable, timely manner you need some semblance of organisation. This is enshrined the project plan, detailing who is doing what over the course of development. To be of any use, the plan must be based on sound estimates, stuck to by developers, and kept up to date with any changes required.
The structure of a software development team is shaped by two main factors:
-
the management approach, and
-
the division of responsibility amongst members.
This will determine the amount of code and the size of the units that you work on. The code produced, in turn, is shaped by the organisation of the team.
A project may be managed on a peer basis, with no coder considered more important than any other, or under the leadership of an über-programmer/manager. The programming team could be considered part of a software production line: fed designs from a team upstream, they produce code to specification[1]. Enlightened software engineers are given more autonomy and responsibility.
Tasks may be allotted months in advance, on long-range plans (which can rapidly become out-of-date and inaccurate), or 'just-in-time' by assigning each work package when a developer finishes their last one. Programmers might work alone on their individual parts of the system, or work collaboratively, pair programming to spread responsibility and knowledge.
The axis of responsibility determines how each line of development is split amongst programmers:
-
With a vertical team organisation you employ a team of generalists, who are skilled in a wide number of roles. They are each given a piece of work and implement it end-to-end, from the architecting and designing, right through implementation and integration, to development testing and documentation.
The main advantage of this approach is that developers gain a wider range of skills, and become more experienced in the whole software system. With one key developer per feature there is cohesion in its design and implementation. However, generalists are expensive and hard to find. They don't have expertise in all areas, and therefore take longer to solve some problems. There is likely to be less cohesion between separate features, as they are implemented by different developers. The customer has to work with more people, since there's no specific liaison point - each developer needs their input to scope the requirements and validate their design.
To make this kind of team work you must define common standards and guidelines for development work. You must have good communication to avoid several people reinventing the same wheel. A common architecture must be agreed early on, or a chaotic and haphazard system will ensue.
-
In contrast, a horizontally organised team is built from a team of specialists, and every development task is split between them, using their respective talents at the appropriate time. Because each aspect of work (requirements gathering, design, etc.) is done by a specialist it should be of a higher quality.
This has many opposite characteristics to the vertical arrangement: we build cohesion between separate work packages, but there's a danger that each slice of work holds together less well because more people have worked on it. Interaction outside the team (with customers or other company factions) is made by a small number of specialists. This is easier to manage, for the team itself and the external contacts.
You must take care to ensure that the specialists are well coordinated, and that they see right through to the end of each work package, or their work will be narrow-sighted. With many people involved in each development procedure, the team is harder to manage; there is more work flow To make this arrangement work requires good communication, defined processes, and smooth handoffs between developers.
There is no 'right' kind of organisation. Which one is most appropriate depends on the team members and the nature of the work produced. The pragmatic arrangement is probably somewhere in the middle.
A team's organisation has an inevitable affect on the code it produces. This is enshrined in software folk law as Conway's Law. Simply stated: "if you have four groups working on a compiler, you'll get a four-pass compiler". Your code inevitably takes on the structure and dynamics of your interacting teams. The major software components lie where teams gather, and their communications follow the team interactions. Where groups work closely, component communication is simple and well defined. When teams separate, the code interacts clumsily.
We naturally aim to create opaque interfaces between each different team's work, to facilitate our interaction with that team. We do so even in cases where reaching into some internal part of another component might be valid and better approach. In this way teams can foster arbitrary divisions; despite our good intentions design decisions are forced by team composition.
Of course, there's nothing wrong with encapsulation and abstraction; however they must be designed in for the right reasons. If anything, organise your team around the code you must build, not vice-versa.
In the next instalment, we'll investigate the death of some failing software teams. Cheery stuff! From this we'll see what we can learn about the characteristics of healthy development teams. Stay tuned.
Notes:
More fields may be available via dynamicdata ..