To develop high quality software consistently and reliably
is to learn how to master complexity.
You master complexity when you understand the different sources of
uncertainty and the different risk characteristics of each uncertainty. Uncertainties introduce delays in development
as you attempt to resolve them.
Resolving uncertainties always involves alternative designs and
generally affects your base architecture.
Poor architecture choices will increase code complexity and create uncertainty
as future issues become harder to resolve in a consistent manner.
The key principle here
is that uncertainty will introduce delays in development. Let's look at the average speed of
development. The Mythical
Man Month conjectures that an average developer can produce 10 lines of production
code per day regardless of programming language. Let's assume for the sake of argument that
todays developers can code 100 lines of code per day. Development speed is limited because of meetings,
changed and confused requirements, and bug fixing.
We use the term "learning curve" to indicate that we will be slower when working with new technologies. The slope of the learning curve indicates how much time it will take to learn a new technology. If you don't know the programming language,
libraries/APIs, or IDE that you need to work with this will introduce
uncertainty. You will be constantly
making syntax and semantic errors as you learn new languages, but this should
pass rather quickly. What will take
longer is learning about the base functionality provided by the libraries/APIs.
In particular, you will probably end up creating routines only to discover that
they are already in the API. Learning a
new IDE can take a very long time and create serious frustration along the way!
In all cases technical
challenge is resolved either by searching for a documented solution in
publications, on the Internet, or by trial an error. Trial and error can be done formally or
informally but involves investigating multiple avenues of development, possibly
building prototypes, and then choosing a solution. While you are resolving a technical challenge
your software project will not advance.
The net effect of insufficient requirements is that you end up with poor architecture. Poor architecture will cause a technical challenge every time you need to implement a feature that the architecture won't support. You will end up wasting time every time you need to work around your own architecture.
Management will not endorse the proper solution, i.e. fixing the architecture, because they have a very poor understanding that every work around that is made is pushing the project closer and closer to failure. Eventually the software will have so many work arounds that development will slow to a crawl.
It is interesting that the project will probably fail, yet, soon enough the organization will attempt to build the same software using the same philosophy.
Summary
Uncertainty
Suppose we take a working 200,000 line program and print all
the source code. If we ask a programmer
to type this code in again, they are likely to be typing at least 2,000 lines of
code per day. So to develop the program
from scratch would have taken 2,000 man days, but to type it in again
would only take 100 man days.
The time difference has to do with uncertainty. The developer that develops the application
from scratch faces uncertainty whereas the developer that types in the
application faces no uncertainty.
If you
have ever done mazes you discover that to do the maze from the entry to the
exit point involves making decisions, and this introduces delays while you are thinking. However, try doing a maze from the exit back to the entry, you will find there are few decisions to make and it is much faster. Fewer decisions from resolving uncertainty faster leads to fewer delays.
It is always faster to do something when you know the solution.
Sources of
Uncertainty
The major sources of uncertainty are:
- Untrained developers
- Incomplete and inconsistent requirements
- Technical challenges
Incomplete and inconsistent requirements are a big source of
uncertainty. Incomplete requirements
occur when you discover new use cases as you create a system. They also occur when the details required to
code are unavailable, i.e. valid input fields, GUI design, report structure,
etc. In particular, you can end up
iterating endlessly over GUI and report elements – things that should be resolved
before development starts. Inconsistent requirements occur because of multiple sources of requirements as well as poor team communication.
Technical challenges come in many forms and levels of
difficulties. A partial list of
technical challenges includes:
- Vendor APIs that are poorly documented
- Vendor APIs that are buggy
- Interfacing incompatible technologies
- Insufficient architecture
- Performance
problems
A common source of uncertainty is insufficient
architecture. Insufficient architecture
occurs when the development team is not aware of the end requirements of the
final software system. This happens when
only partial requirements are available and/or understood by the developers. The development team lays down the initial
architecture for the software based on their understanding of the requirements
of the final software system.
Subsequently, clarified requirements or new requirements
make developers realize that there was a better way to implement the
architecture. The developer and manager
will have a conversation that is similar to:
Manager: We need to have
feature X changed to allow behavior Y, how soon can we do this?
(pause from the developer)
Developer: We had asked if feature X would ever need behavior Y and we were
told that it would never happen. We
designed the architecture based on that.
If we have to have behavior Y it will take 4 months to fix the
architecture and we would have to rewrite 10% of the application.
Manager: That would take too long. Look I don't want you to over engineer this,
we need to get behavior Y without taking too much of a hit on the schedule. What if we only need to have this for this
screen?
(pause from the developer)
Developer: If we ONLY had to do it for this one screen
then we can code a work around that will only take 2 weeks. But it would be 2 weeks for every screen
where you need this. It would be much
simpler in the long run to fix the architecture.
Manager: Let's just code the work around for this
screen. We don't have time to fix the
architecture.
The net effect of insufficient requirements is that you end up with poor architecture. Poor architecture will cause a technical challenge every time you need to implement a feature that the architecture won't support. You will end up wasting time every time you need to work around your own architecture.
Management will not endorse the proper solution, i.e. fixing the architecture, because they have a very poor understanding that every work around that is made is pushing the project closer and closer to failure. Eventually the software will have so many work arounds that development will slow to a crawl.
It is interesting that the project will probably fail, yet, soon enough the organization will attempt to build the same software using the same philosophy.
There is never enough time to get the project done properly,
but there will always be enough time to do it again when the project fails.
http://www.geekherocomic.com/2009/06/03/clever-workaround/ |
- Uncertainty comes from several sources
- Untrained personnel (language, API, IDE)
- Inconsistent and incomplete requirements
- Technical challenges
Next part (2 of 3)
- Defining and understanding risk
- Matching uncertainties and risks
No comments:
Post a Comment