Truly Profound Statements on Essential Software Stuff ...
A few fundamental beliefs, supported by more or less witty
quotes from (more) renowned gurus.
The objective is not to be funny, but to state some insights and hallmarks
characterizing good software craftsmanship.
Object
Oriented Fundamentals
Object Oriented Programming
Using an OOPL (Object Oriented Programming Language) or any other OO tool
does not guarantee an Object Oriented system. Object Orientation is a way
of thinking rather than a way of doing, a mind-set rather than a tool-set.
Object languages allow advantages but don't
provide them.
-- Tom Hadfield (quoted by Martin
Fowler in "UML Distilled")
A hallmark of good object-oriented design is
that you can modify and extend a system by adding code rather than by hacking
it. In short, change is additive, not invasive.
- John Vlissides
Attributes
Each object attribute holds some information about the object. Do not confuse
the attribute with its implementation - some are persistent variables,
and some are derived from other attributes. An attribute tells you something
about the object, but nothing about the design of the class.
A person has the attributes age
and date of birth.
One might be implemented as a persistent variable,
and the other as a method operating on that
variable.
It appears that age can be derived
from date of birth,
and that the opposite might be somewhat shortsighted.
-- Peer Törngren (inspired
by Peter Hugosson-Miller)
Objects and Identities
Objects are unique, tangible things. Most objects have some unique identifier.
Do not confuse the object with its identifier.
... every hospital lies in only one city. Inevitably
someone points out that this is not the case since many cities in the world
have a St. Mary's hospital. The error here is one of the oldest in logic
and philosophy - the confusion between the name of a thing and the thing
itself. A hospital is much more than a sequence of letters: It is buildings,
an organization, people, a legal entity, many things that make St. Mary's
Hospital on the Isle of Weight different from St. Mary's hospital in London.
Clearly, nobody would actually mistake one for the other if they actually
ran into the object.
-- Martin Fowler (Analysis
Patterns: Reusable Object Models)
Optimization
Most programmers optimize the wrong stuff, i.e. what looks tedious from
a human perspective. The compiler and/or computer may (and do) often have
a completely different opinion. Never optimize if you cannot verify what
you are doing by metrics, and don't compromise your design - a clean design
means less code to optimize.
Make it Run, Make it Right, Make it Fast
-- Kent Beck (quoted by Ken Auer)
The best code is no code
-- Roml Lefkowitz (quoted by Ken Auer)
The First Rule of Program Optimization:
Don't do it.
The Second Rule of Program Optimization (for
experts only!):
Don't do it yet.
-- Michael A. Jackson
Scope
Place Your Bets
Find out what to build before building it. Find out why you're building
it, and what stakeholders expect. Declare what is
likely to change in future, what is likely to be customized for each
user, and what will never change. Base your architecture on expected variations,
and violently ignore the rest. Have the guts to say "no". Every variant raises
the complexity of the system - you can not afford to build a system that
can in fact handle any change. It is the job of the architect to define as many
invariants as possible, as early as possible. It is OK to design your webshop
with no leeway for deep space rocket mission control.
Compare a software system architecture with
the architecture of a house: Some parts (foundation and outer walls) change
infrequently. Other parts (inner walls and partitions) change more often,
while yet other parts (furniture in each room) change fairly often. It
would be pointless to build houses where the outer walls can be replaced
easily, and madness to glue the furniture of each room to the floor.
-- Jacobson, Griss, Jonsson (Software
Reuse Architecture: Process and Organization for Business Success)
Extend and Adapt!
One size does not fit all, unless it is a very large size. And even then,
it is not a good fit. You can build a system that everyone accepts but
nobody likes. Or your system could offer everything anyone ever asked
for, and drown all users in unwanted features. Or it could do most
things for most users, and let the users add the missing parts. This is
an extensible system; it is designed for diversity and it is the only
way to handle contradicting desires. An extensible and adaptive system
has a small core with extension points for new and ever-changing user
requirements. In many domains, this agility is crucial.
Ein Mädchen für Alles
-- Napoleon?
One for All, All for One
-- Switzerland
-- Three Musketeers (Alexandre Dumas)
Unity in Diversity
-- European Union
-- House of Blues
Bhinneka Tunggal Ika
-- Indonesia
Structure
Divide and Conquer
A large system can easily become very complex. The remedy is simple; just
as we break up code in classes, we break up the system in components to
minimize interaction and control dependencies. Each component can be
understood (and tested) on its own, and the system can be discussed in
terms of its components rather than its classes. It can be hard to
structure the system and manage the dependencies, but it is even harder
not to. Just as we don't put all code in one class, we don't put all
classes in one component.
The more complex a system is, the more likely it is
to fail. It is difficult to figure out the requirements for complex systems. It
is hard to design complex systems. And it is hard to implement complex systems.
At every step in the system life cycle, errors accumulate at an ever increasing
rate. The solution to this problem is to break large complex systems up into
small simple systems that can be worked on independently. But in breaking up the
large complex systems, great care must be done to minimize the overall system
complexity. There are many ways to break up a system and the vast majority of
these make the problem worse, not better.
...
Let’s say you have a system with one function: F1. If a
problem arises, there is only one place to look for that problem: F1.
Let’s say you have a system with two functions: F1 and F2.
If a problem arises, there are three places you need to look. The problem could
be in F1, the problem could be in F2,
or the problem could be in both. Let’s say you have a system with three
functions: F1, F2, and F3.
Now there are seven places the problem could reside: F1, F2,
F3, F1+F2, F1+F3,
F2+F3, F1+F2+F3.
You can see that the complexity of solving the problem is increasing faster than
the amount of functionality in the system. Going from 2 to 3 functions is a 50%
increase in functionality, but more than a 100% increase in complexity.
-- Roger Sessions (The
Mathematics of IT Simplification)
Organize for Change
There are many ways to structure a system; discussions on how to cut the
cake are sometimes long and animated. "Cohesion" or "coherence" are
common drivers - but what does this mean? I say "change drivers": things
that change together belong together. It is no harder than seating
passengers in buses - those who go in the same direction sit in the same
bus. They all turn when the bus turns. Whether or not they look the
same, have the same names, or share family relations doesn't matter. The
same goes for software; elements that move in the same direction and
turn for the same reasons belong together. When a change occurs, it
affects one module. Or maybe two. If your whole system is affected to
accommodate a single change, you know you made a mistake. Or that you
are expected to do the unexpected.
It is not one of his
best. It lacks a cohesive structure, you know? You get the feeling that he’s not
absolutely sure what it is he wants to say.
-- Man in theatre line, Annie Hall (Woody Allen)
Frameworks
Building generic (reusable) components is expensive. Using generic components is
expensive. Building unused generic components is stupid. Do build
generic frameworks and reusable components, but only if you know that there
is a need, and what the need is. Let the framework evolve as part of the
application development. Do not assign technology teams to build a framework
that satisfies imaginary requirements. Frameworks grow from application
requirements!
A framework is a micro-architecture that provides
an extensible template for applications within a specific domain.
-- UML, the Unified Modeling Language
Simplicity is often the key to generality.
The more complicated a framework is, the less general it is likely to be.
...
Before something can be re-used, it has to
be used.
...
Up to a point, "real" frameworks simply laugh
at requirement changes -- simply re-parameterize the framework! But changing
requirements kill framework projects that have become de-generalized. Somewhere
along the line, some manager thinks "what is an adjustable wrench but a
handle for this particular bolt I have to turn" and soon someone works
the adjustability out of the wrench, perhaps even welding it to the manager's
particular bolt. Now the requirement for the size of the bolt changes!
-- Frameworks are Grown, Not Born (Bytesmiths in Smalltalk Report 1997, http://www.bytesmiths.com/pubs/9707FrameworksAreGrown.html)
Analysis
and Design
Analysis differs from Design. Analysis relates to the domain, design relates
to the software representation of the domain. Technical decisions are design
decisions, not analysis decisions - the speed of the database does not
affect how a person relates to his or her home address.
Remember: Analysis occurs only when the domain
expert is in the room (otherwise it is pseudo-analysis).
-- Martin Fowler (UML Distilled)
The
Development Process
The waterfall approach has proven itself a failure. Any development task
above micro level must be performed in several iterations with an incremental
approach. This is how man grows from a baby to an adult. You don't know
what you need to know until you've started learning. The thought of learning everything
at once is appealing but impossible. You may call this approach "agile". Or you
may simply refer to it as common sense.Good judgment comes from experience, and a
lot of that comes from bad judgment.
-- Texas B. Bender
When to Use Iterative Development
You should use iterative development only on projects
that you want to succeed.
-- Martin Fowler (UML Distilled)
When to Prioritize Requirements
If you can in fact do anything, then you can forget
about prioritization; the rest of us need a way of knowing how to deal
with resource constraints, with unseen design difficulties, and with all
the other kinds of project risks, in ways that will be acceptable to the
customer.
-- IBM OOTC (Developing Object-Oriented
Software: An Experience-Based Approach)
Changing the Process
The problem of software process change are often
complicated by the fact that no one is responsible to make it happen. If
software process improvement isn't anybody's job, it is not surprising that is
doesn't get done! If it is important enough to do, however, someone must be
assigned the responsibility and given the necessary resources. Until this is
done, software process development will remain a nice thing to do someday, but
never today.
-- Watts Humphrey
,
Creating a Software Engineering Culture)
Political Risk Management
I can't offer you any advice on this because I'm
not a skilled corporate politician. I strongly suggest you find someone
who is.
-- Martin Fowler (UML Distilled)
Agility
Agile methods focus on user requirements. Does this contradict code quality
or architecture?
Why should we bother with structure, naming conventions, unit tests or refactoring when
the customer never asked for it? Well, our profession is software. The user
expects us to know our profession, and to implement requirements in a
professional way. The user's job is to request changes, our job is to
respond. Sloppy coding kills agility, and agility is a user requirement.
It is not good enough that a program works. A program
must also be written well. As a programmer you should take pride in your work
and never leave a mess under the hood. Remember, a product that works, but that
has a bad internal structure is a bad product.
-- Robert C. Martin (Object
Mentor blog 2007-10-29)
There's a simple way to find out if an operating
system has been well designed. When you get an error message, go to the help
system and look up the exact words in that message to see if there was enough of
a concept of an architecture that they have a consistent vocabulary to talk
about what's broken.
-- Bill Joy (Fortune, 29 September 2003)
If builders built like programmers program,
a woodpecker could destroy civilization.
-- Gerald Weinberg (quoted by Magnus
Ahlgren, Q-Labs, while presenting
CMM)
Fix it Later
I have frequently heard project managers say "Just hack it up, we'll fix
it later". But I have yet to discover when "later" actually
occurs.
If you don't have time to do it right the first
time, when will you have time to do it over?
-- (unknown)
You aren't going to get TimeToDoItOver.
So what you have to do is do it over now.
-- Ron Jeffries
When some part of your system gets really crufty
and awful, it may well be too late to do anything about it. The refactoring
can get so difficult that no one can do it. This happens because the crufty
part causes strange code and assumptions all over the system and you can't
ever find them all to take them out. What you have to do is to keep the
system from ever getting there. You do this by learning not to tolerate pain.
When an object is hard to use, fix it right away. Don't just live with it.
When you see two methods doing the same thing, refactor them so there is
only one. Don't just live with it.
-- Ron Jeffries (Do
It Over All The Time)
To Succeed
Find and define your goals and
the criteria to test them before you begin the mission, and get all stakeholders
to sign off. Stay focused and keep at it until all tests pass, stop as soon as
they do. Apply this principle whenever "mission accomplished"
matters, be it programming, running a meeting, leading a project or having
lunch. How else do you know when you're done?
Think back to your last successful project. Was it
successful because you finished on time? Because you finished under budget?
Because the application didn't crash after it was deployed in a live
environment? While these are certainly good things, there's one overarching
element of success that you may have overlooked: Did the application adequately
address the problem that it was supposed to solve?
-- Amit Asaravala (Software
development newsletter, April 2004)
Third Party
Software
You don't want to write all the software yourself. So you use software
produced by someone else. New versions bring enhancement and resolve problems,
and old versions become unsupported, or fail to run in your evolving
environment. Hence, you need to update. However, new versions also have
bugs: every update introduces an element
of risk.
Mitigate risk by updating in small increments at convenient times: update early in each project cycle, whether you need it or
not. You avoid updating to resolve bugs you find in final testing. You
avoid big-bang migration when your Very Old Version no longer runs. You avoid
bugs in the bug fix at the worst possible time.
Mitigate risk by not running the most recent version on the day it was
released. Let someone else find the problems, and update when the most blatant
issues are fixed in a maintenance release.
There are more versions than "the latest", and there are other
times than "now".
-- Dr. Rickard Enander (internal Frameworx
Company email war)

--Dilbert (Dilbert)
Attitude
If you think it will go wrong, it probably will. If you keep staring at the
problem, you'll never see the solution.
People who say it cannot
be done should not interrupt those who are doing it.
-- George Bernard Shaw
Simplicity
Beauty lies not in mastering difficulties, but in making difficulties appear
simple.
Our enemy is complexity, and our job is to
kill it.
-- Jan Baan (quoted by Grady Booch
at RUC98)
Perfection is achieved, not when there is nothing
more to add, but when there is nothing left to take away.
-- Antoine de Saint Exupery
... there are two ways of constructing a software
design:
One way is to make it so simple that there are obviously no deficiencies,
and the other way is to make it so complicated that there are no obvious
deficiencies.
-- C.A.R. Hoare, "The Emperor's Old Clothes", 1980 ACM Turing Award
Lecture, CACM vol. 24 no. 2, February 1981
You do not really understand something
unless you can explain it to your grandmother.
--
Albert Einstein
Simplicity is not natural. You have
to choose to make it happen. To get Simplicity, you have to want it badly
enough.
-- Dr. Edward de Bono
Almost anything can be simplified
further.
-- Dr. Edward de Bono
Brilliance
Some years ago I spent a week giving an in-house
program design course at a manufacturing company in the mid-west of the
United States. On the Friday afternoon it was all over. The DP Manager,
who had arranged the course and was paying for it out of his budget, asked
me into his office.
'What do you think?', he asked. He was asking
me to tell him my impression of his operation and his staff. 'Pretty good',
I said. 'You've got some good people there.' Program design courses are
hard work; I was very tired; and staff evaluation consultancy is charged
extra. Anyway, I knew he really wanted me to tell me his own thoughts.
'What do you think of Fred?' he asked. 'We
all think Fred is brilliant.' 'He's very clever', I said. 'He's not very
enthusiastic about methods, but he knows a lot about programming.' 'Yes',
said the DP Manager. He swiveled round in his chair to face a huge flowchart
stuck to the wall: about five large sheets of line printer paper, maybe
two hundred symbols, hundreds of connecting lines. 'Fred did that. It's
the build-up of gross pay for our weekly payroll. No one else except Fred
understands it.' His voice dropped a reverent hush. 'Fred tells me that
he's not sure he understands it himself.'
'Terrific,' I mumbled respectfully. I got the
picture clearly. Fred as Frankenstein, Fred the brilliant creator of the
uncontrollable monster flowchart. That matched my own impression of Fred
very well. 'But what about Jane?' I said. 'I thought Jane was very good.
She picked up the program ideas very fast.'
'Yes,' said the DP Manager. 'Jane came to us
with a great reputation. We thought she was going to be as brilliant as
Fred. But she hasn't really proved herself yet. We've given her a few problems
that we thought were going to be really tough, but when she finished, it
turned out they weren't really difficult at all. Most of them turned out
pretty simple. She hasn't really proved herself yet - if you see what I
mean?'
I saw what he meant.
-- Michael Jackson (Software Requirements
& Specifications)
What's with the trees? Well, I never wrote any book. So the
trees simply love this lttle electronic page ...
or at least I hope they do.
|