I've come to the conclusion that the single most important attribute of an
effective software team is simply the will to be good. Talent can be
developed and knowledge gained, but not without the will to get there. I'm
obviously a big proponent of Agile practices, but these practices are useless
unless the team is disciplined and intelligent in their approach. If you
want to be good, you have to be reflective about your approach every day and
constantly make little improvements.
Don't Live with Broken Windows yes, but you've got to be observant in the first place to spot those Broken Windows.
Complacency is the enemy.
I don't think a team is going to be good by simply working harder.
Ironically, my most important lessons for software development came from working
on my father's construction crew in school — "always think about what
you're doing" and the paternal classic "work smart, not hard."
He was worried about things like walls getting out of square or hurting your
back lifting, but those little homilies certainly apply to our profession.
Effort
alone will not lead to good results. Some of the worst systems I've
ever seen resulted from taking a bad direction and following that same bad
direction for the duration of the project, often with a great deal of team
effort.
Don't tolerate bad code. If you see your code starting to get wild and
wooly, refactor! Little refactorings are the ounce of prevention that
prevent the painful rewrite cure later. Pay attention to your code so you know when to refactor.
That "pay attention" could be code reviews, code metrics, pair programming, or
simply reading the code you just wrote. Bad code will increase the
cost of debugging, testing, and modifying the code later.
Don't write code on top of bad code. I failed to make this point
adequately
yesterday. My current team is effectively evaporating and we're passing
our upcoming project onto a different team. The new project is going to
require modifying some existing classes that can only be described as pure excrement.
There's far, far too much duplicated code in a very long method and class (Cyclomatic
Complexity = 50+).
The new team wants to make the simplest change they can to just add in some more
if/then logic and walk away. That's a dangerous attitude that will hurt
the team over time. I know that attitude has hurt my company. Arguably, that code is in the shape it's in because of exactly that attitude of "I just have to get this done." On one hand, I think the new code would go
smoother if you cleaned up the old code first. On the other hand, doing no
cleanup is going to increase the chances of a full blown rewrite the next time
that code changes because it's already at the verge of being unusable. The
key point is that the
new changes would be relatively simple if the original code had simply been
built cleaner. I really do think that some minor refactorings early on
could have prevented the poor quality code with much less effort than it will
take at this point.
Fix a broken build — immediately. As soon as you stop taking a
Continuous Integration build seriously, whatever it might be, you have lost all
the value of doing a CI build.
The "design hat" never comes off.
Scott Bellware and
Sam Gentile have both posted recently about their feelings toward continuous
design and the role of an architect or design leader on Agile projects.
Pushing aside the definition of roles and responsibilities on a project, doing
continuous design effectively requires the team as a whole to adopt an attitude
of constant challenge to their design. Talk and think
about your design. Analyze the effectiveness of your design over time. Don't act on a design
idea until it's time, but do think about the future and keep a running queue of
design ideas circulating in the team. All of the worst systems I've ever
worked with shared a common history: the team picked a technical direction early that
wasn't ideal, then thoughtlessly marched along said flawed path without any
thought for altering the design.
If a manual build or deployment process is repeatedly slowing you down, automate it!
If you're producing too many bugs, think about changing the way you unit test
or code.
If your estimating practices or project management processes don't seem to work, change them. The "process" is there to serve the team, not the team
existing to serve the process. If you think iteration kickoff meetings are
some sort of sadistic exercise, you've got a severe problem that needs to be
addressed. If you hate the process, it needs to change. Grumbling
never seems to help — .
Does Quality Even Matter?
Absolutely. If you're like me, your management doesn't care or understand, but
quality absolutely matters — even to management, they just don't always
understand the implications. Quality code, configuration management, and
testability maintains the level of the team's
productivity. Bad code degrades the team's productivity over time.
Good designs enable efficiency in supporting the code later. Bad designs
increase the cost of ownership.
Almost without fail, anytime somebody posts on a design pattern or design
approach, another person will comment that they don't have time for all this academic nonsense because they're too busy building code under time constraints in the real world.
Regardless of process or philosophy or technology, the best teams are those that
ditch that attitude of "I can't stop to sharpen
the saw because I'm too busy cutting wood!"
Besides, there's that little "pride in your craftsmanship" thing too.