Once upon a time in 2002 or 2003, Mr Ed asked me if I had any interest in writing an essay for a new web site he was thinking of setting up called HackNot! I had a bunch of mostly sardonic and simple thoughts in a file somewhere and I sent it off to him asking if this was the kind of thing he was after. He relied yes, and I duly got busy with something else and evaded towards completing it.
I think Ed grew tired of waiting for me and edited my incoherent rambling into an ordered list and plugged it up into public view.
I thought that now, nearly 5 years later, would be a good time to re-examine some of those thoughts. I’m way kindler, way gentler, and way more verbose now. The process of looking at what I thought 5 years ago is bound to ignite a flame war with myself.
I’ve taken a copy of the HackNot! article and added notes along the way.
In 1995 the Unabomber’s manifesto was published in The New York Times. In 2001 the Agile Alliance published their Agile Manifesto. Now our own Tedious Soporific gets in on the act. His personal manifesto leaves no area of software development untouched – from the hazards of frameworks to the role of “doof doof” music in requirements elicitation, it’s all here. Truly a heartbreaking work of staggering genius.
Heartbreaking and staggering but not genius.
- Humans read requirements.
- Humans lose interest if they can’t understand the requirement, or why it’s there.
- Requirements numbers should never contain the section number of the document they are in.
- A requirement only needs to require an implementation in rare circumstances when you need to require a point of concrete integration(shall run inside IE 4.0 and up etc.)
- Requirements should be able to be tested. If you write a requirement that may be hard to test, write supporting notes about how you would envisage the requirement will be tested.
This is a bit of a crude list of things that have irked me about requirements in the past. I would say, without fail, that poorly written, or conceived, requirements cause me the most pain in my work. Both reading other peoples’ and re-reading my own hastily-prepared requirements can be a trial. These days I think I would just point to Carl Weigers’ two excellent texts and leave it at that.
According to Capers-Jones, best practice is to spend 10% of a “systems” software development project’s effort on systems engineering.
- User interfaces are design, not requirements.
- Track requirements met during development by mapping requirement coverage to test results.
I stand by my statement, but the reason it’s a manifesto entry is that UI design is not a requirements generation activity. It’s a design activity, and a vitally important one.
One of the most interesting diagrams about the importance of user interface design and its relationship to estimation I’ve seen is on page 39 of Steve McConnell’s “Software Estimation: Demystifying the Black Art” (see a spreadsheet I prepared earlier here) where he discusses the cone of uncertainty. This diagram is about the variability in estimates done as a project progresses.
Before “product definition” a project may take from one quarter to four times the time estimated at this point. Estimations done at the time detailed requirements are available take the likely variability ranges from two thirds to one and a half times estimates done at this time. The next step is user interface design. When the UI is designed, the likely variation from estimates done at this time are from 0.8x the estimate to 1.25x. If you’re not doing a UI design and re-estimating at each milestone of project definition, you’re not interested in estimates.
I’d go further than tracking requirements to tests and say that requirements should be mapped to architecture and design so the relationship between design decisions and requirements is obvious to developers and archaeologists who look upon your project in later years.
- Because a customer asks for a feature to be implemented, that alone doesn’t make it a good feature.
- Moral time: A man walks into a hospital having already diagnosed himself with prostate cancer. He demands that a surgeon operate immediately to remove the cancer. The surgeon operates. The man is caused inconvenience, discomfort and pain for the rest of his life from side-effects of the operation. The surgeon could have refused to operate, citing that 80% of men die with, and not because of, prostate cancer. The surgeon gave the man what he asked for and not what he needed.
What a smarmy bastard I was.
A simpler way of putting this is that the job of a software professional is to tell your customer when they’re asking you to do something they shouldn’t do. Sure, they can go ahead and do whatever the silly thing is anyway, but you shouldn’t really let someone demand that your team build a content management system when there are free and commercial versions out there that may meet your customers’ needs. Customers tend to talk about how the system should look, so it’s easy to fall down a rabbit-hole of having the customer design everything for you. If you are mindlessly implementing everything your customer tells you to, you’re somewhere in the spectrum of working with a very capable customer to not behaving as a professional software developer.
- Q: What can you brush your teeth with, sit on, and telephone people with?
A: A toothbrush, a chair and a telephone.
This is a bit too subtle and clever, which contradicts something else in the manifesto (see below). I advocate looking at the problem to see if you’re solving one problem or several. Consider if it’s really appropriate to solve two or three distinct problems with one development or a monolithic product. Any way a project can be made smaller, or divided up into several projects is advantageous. In software we have know from Barry Boehm’s work that there is a diseconomy of scale of software development, so three small projects have a much greater chance of succeeding and coming in near to time than one big project does.
- Specify performance early.
- Optimise late.
Specify performance requirements as early as you can and realistically. If you find your customer pulling very ambitious figures out of thin air, mark the performance requirement for later. If you find there is hard and believable data behind the performance requirement, then you should note the source and breathe easy that the performance requirement is believable.
Optimising late is a reaction to developers who get carried away making code perfect up front. If you have a believable performance requirement that is unprecedented then you should see this as a project risk and consider prototyping, benchmarking and discovering early if your project needs to be sent to an early grave for being infeasible before you spend a lot of money and reputation on something impossible. Pay attention to performance and don’t optimize things that aren’t a bottleneck or won’t help you meet your project goals.
- Styles in Microsoft Word are your friend. If you want a Word processor, use Word. If you want a typewriter, use Notepad.
There are many things that may be reused in software development. Documents are one of the most commonly reused development artifacts. If you use Word to do your documentation, learn about styles, automation, cross-references, footnotes, and keep your source material close to the document and in source control. Don’t be too proud to go on a Word course – if you’re tabbing, or double-entering to get paragraph markers please go on a course.
Perhaps this should read “Beware the project with no end and no clear customer” as this entry was about projects that allow themselves the luxury to think that everyone wants what they’re producing they just don’t know it yet. I’m sure many successful frameworks came from over-resourced projects with an ambition to meet requirements they just invented for customers that “don’t even exist yet” but I’m also sure there’s a 20:1 ratio of failures to modestly successful frameworks born from over-generous budget allocation.
- Spurn the “reusable component.”
Reuse was big at the end of the 90’s, resurfaced as Product Line Engineering in the early 00’s and seems to have died down prior to resurfacing as SOA around about now. I’ve written before about how I think that design, experience and plain-old code-stealing are some of the most effective forms of reuse. Backed by tools that support findability and developer communication, code reuse will blossom in an organization. Building a repository of carefully curated reusable components and controlling their use and limiting their mutations is intended to reduce testing requirements and defect propagation, but it also stifles innovation and discourages reuse.
- It’s hard to specify a framework because what users might require rarely becomes what they’ll need for sure: “You ain’t gonna need it.” Your customer wants to pay for a solution for their problem, not everyone else’s.
Would you like to be a customer who wanted to pay for an SQL query and got an ORM framework for only twice the price?
- XML: it’s just a verbose way of representing structured data.
- SIP: it’s just a signalling protocol.
The road to hell is paved with overreaching hyperbole about the potential of new technologies. Both XML and SIP are useful technologies; both brilliant and compromised. Before them was WAP, Token-Ring, OpenDoc and a lot of other promising technology that was way over-hyped.
Most projects have version two of a product loaded up with features a long time before version 1.0 has been seen by customers. The absolute best resource for requirements is customers, and their best ideas don’t come in focus groups or interviews about the problems they have. Customers’ best ideas come when they’ve seen version 1.0 and hate it enough to tell you what they’d really like. If the next release is already full of requirements that are sourced from marketing or product management, customers will be upset with 2.0 as well. If you can’t make them happy with release 1.0, make them happy the second time they see a release. Customers you listen to become your ally and make marketing a whole lot easier.
- When someone says “I know this is a death march, but you will be rewarded well if you succeed or fail,” run (away) like the wind.
This was a lie told to me once. Use the experience to remain as professional as you can, or run.
- Habitable development environments.
This was a placeholder for something I read once and could never find again. The idea is that, like share accommodation, teams need to find their level of process and code hygiene. Some brilliant developers work with little infrastructure and formality and others work best with lots of structure. When building a team consider what each developer finds habitable and make sure you get a team that can accept the coding standards, process rigour and meeting load that you intend to inflict on them. In a share house, some people like to leave the dishes until there’s a good pile, others like to wash everything on a regular basis. If you have lived with people at either end of the cleanliness and habitability spectrum, you know how important this can be.
- Give directives in positive terms.
- Avoid saying what shouldn’t be done.
- Toddlers and software engineers want to please you, and do the right thing.
- Toddlers and software engineers hear “Don’t do X” and become paralysed with uncertainty because they now know for sure what they shouldn’t do,but can’t figure out what you do want them to do.
How patronising! It’s a subtle message.
If you want people to change, tell them what the outcome should look like in terms they understand. If an executive stands up and says “don’t be evil,” your expectation is that you can go right up to the line, lean over and smell the sulphur, and still be in the clear. If your executive says “from now on we’re not a services company” middle management might set about firing your services staff with no vision for what you really want to be.
- Usable interfaces should not be innovative. If it’s clever or tricky,then it’s probably confusing.
- Users don’t use the right mouse button.
Let’s back off to saying that you can’t expect users to rely on the right mouse button. Watch some regular users use applications sometime.
- It’s hard to know when to double-click unless someone shows you.
Watch some users sometime. A lot of older users double-click hyperlinks because someone once showed them that the way you get a computer to respond to you was to double-click.
- Users don’t use tree views. Users don’t get trees.
- Users only (very) rarely see trees on computers.
- Developers love tree-views.
- DevStudio [and Eclipse have] trees.
- Windows file explorer shows a tree.
- Most users never see or use tree-views when they’re using Windows (or Macs) and don’t find them comfortable.
- Think about where the Windows explorer is located in the Start-> menu(it’s an “Accessory”) and where the “My Computer” icon is (on theDesktop) and what happens when you double-click it.
- You have to configure Outlook to show a tree view of your folders on the left.
- Standard Windows application file (save/open) dialog does not show a tree.
- A tree is not an easy metaphor. When was the last time you saw a real live tree of folders?
I guess I was tired of seeing lots of new applications that looked just like the IDEs used to build them. The tree has thankfully been supplanted by the Google-like search & results list.
- It’s hard to write requirements unless you’re ears are being pounded by”doof doof” music.
Actually “doof doof, chikka, doof doof” music is better, I’ve found.
- Unfinished Sympathy is the finest pop song ever written.
I have to revise this one day. But the combination of serious-sounding nonsense lyrics, orchestral pomp and an addicting hook make it hard to beat.
- “Refactoring” is not synonymous with “fixing bugs”.
Like the XML and SIP thing, this was written at a time when the term was overused. “I’m going to refactor that bug report” or “I’m going to refactor my performance problems” were not uncommon.
I’ll follow up later with “Epiphanies about software” posts, but I think I’m done with manifestos.