
|
|
Almost every day for years,
during the course of scores of software projects, developers and project
leaders would come into my office to discuss project status and issues.
Eventually many of these “issues” developed a familiar ring, and I found
myself responding at times “I think you’ve forgotten the first rule of
programming!” This happened so often that I began a list on my whiteboard
of “rules of programming” so I could just point and say “I think the
4th rule of programming applies here.”
A few years ago we made
some posters of the “Rules of Programming”, but opted to say nothing
about them, believing
they would be self-explanatory to those who have been through the development
process.
However, I’ve observed that
these rules have an interesting property—shared perhaps by other shorthand
lists like the 7 deadly sins or 7 wonders
of the ancient world—the property that when removed from the contexts
which gave rise to their formulation, they seem to have limited meaning
and potency. On the other hand, in moments of crisis—such as potential financial loss, career disaster, or harm
to one’s reputation—their significance is all too real. Except, then,
it is usually too late.
So, in the interest of making
a small contribution to reduced-crisis software development, I’ve added
a few comments to
the list of rules.
- Understand. The number
one rule of everything. Equivalent to “build your house on rock.” Any
software development not based on
a thorough and true understanding of the problem domain, the needs and
desires of the stakeholders, the technologies involved, the process of
development, the skills and psychology of the developers, and ..., is
a problem about to happen. Software development is not for the intellectually
lazy. You need the desire to understand, and the energy and discipline
to achieve understanding—every day.
- Believe nothing; assume
nothing. How many times have small, “insignificant” assumptions caused
projects
to fail? Many, many times, and unnecessarily. Do you accept someone’s
word “this will be ok, it will work” or do you verify it? You can
make 50 assumptions and believe someone 50 times, but being wrong
just once can destroy
a project—NASA was probably correct in 99.9% of its assumptions about
Columbia.
It’s much less expensive to verify absolutely everything than to
tolerate unnecessary risks—even at the expense of team members rolling
their eyes
and shaking their heads. You’re right to question everything.
- First
A, then B. Impatience to see “results” is just a fact of life. Developers
have an urge to implement, even if the design isn’t “there” yet.
They have an urge to design, even if the requirements and problem domain
aren’t
fully understood. This even justified in certain prototype-oriented
development methodologies—which aren’t completely wrong, but certainly
aren’t right
if they say it’s cheaper and quicker to achieve good design or understand
requirements based on a prototype. That‘s equivalent to constructing
a prototype home, then after seeing its full-scale shortcomings,
adjusting the requirements, changing the design, modifying the home
construction and then repeating the process. Not only is this expensive
and time-consuming, it tries to escape an inescapable fact—that in
every successful software application, there must come the time when
need is
well understood, when design responds well to need, and when the
final product efficiently implements the design. There’s no denying
the efficacy
of iterative development, but as mentioned in the Development Process section, “first A, then B” is essential within each thread of development.
- Take
your losses now. If something is not working, admit it, change it,
and get on with the project. It may be a software or hardware component,
or a member of the development team, or perhaps the application architecture.
It may even be the client. Avoid denial—if there really is a problem,
and we can’t honestly show a way to live with it, then it’s time
to make
a change, and take the loss. It’s much cheaper in the long run.
- Be
pragmatic. Every detail of software development supports this ultimate
objective: an application which serves its users well, with excellent
performance,
reliability, ease of use and fit for purpose. In every project there
are times when parts of the development process are unnecessary or
inappropriate. It is the developer’s responsibility to be effective
and to thoughtfully
adjust the process as necessary to best serve the goals of the project.
- Get it done. Closure. Some projects, some tasks, seem
to never end. You’ve seen them. Sometimes it’s because requirements
are incomplete, leading
to an endless loop of implementation, disappointed stakeholders,
design revisions, and more implementation. Other times it’s a developer
in over
his/her head. Sometimes unreliable hardware or third-party components.
Whatever. Developers and project managers need to recognize this
phenomenon quickly, then change something to break the cycle. Getting
it done is
an essential attitude of the successful developer.
- Do it right. When are compromises OK and
when aren’t they? Nothing’s perfect, so in the real world where I’m
exhorted to “be pragmatic” what does it
mean to “do it right?” “Do it right” is an attitude which translates
as follows: within the economic realities of this project, I work
to really understand the problem domain and the true needs of the users.
Based on this, as well as the need for reliability, good performance
and ease of use, I conscientiously create a lucid design specification
that will support efficient implementation. And during implementation,
my decisions will respect these factors in my attempt to create an
optimal
product within the time and budgetary constraints of the project.
- Balance. All of these rules connect at the center of the development process—none
can be taken in isolation. How to balance the variables, the rules,
the procedures, the goals and constraints—that’s the essence of our
profession. That’s our job as software developers.
|