Sunday, March 18, 2012

Writing Good Specifications the Simple Way

When writing specification documents, whether requirements, functional specifications, software design specifications, use cases, user stories or even briefing documents and statements of work, it is easy to become caught up in technical detail: is this a functional or a non-functional item, do I draw up an activity diagram, or model state...?
As Schiller (very loosely) said,
Don't try so hard, pleasing everyone can be a bad thing.
After many years of specification writing, and diving deep into IEEE standards, UML, semantic models and a myriad of other fine, worthy, but complex approaches, I have come to the conclusion, that you should just think like a primary schooler (grade schooler).
Specification is about communication: whether from a client to a technical team, from one member of a technical team to another, or from a technical team back out to a client or a regulator. When you first learn to write, your teacher's initial focus is on having you communicate i.e. express your ideas clearly.
So - even though thorough, technically focused systems can be great - the cornerstone of a good specification is plain, understandable, concise English. A very simple structure can take you a long way and - like "progressive enhancement" in HTML - allows you to build a more complex structure around it. So:...

SIMPLE RULES

  1. Don't write passive sentences. Specifications are about a system or parts of a system doing and responding, so focus on active sentences - it's just good object orientation anyway...
  2. Do structure any specification with WHO, WHAT, WHY, WHERE, and WHEN.
  3. Then add to your structure with WHO NOT, WHAT NOT, WHY NOT, WHERE NOT, and WHEN NOT.
  4. When you've done this, give examples (for both paths)
  5. Then focus on the HOW: first of all HOW OFTEN, HOW MUCH.
  6. Next focus on the HOW TO (which is unfortunately where a lot of specification starts).
Keeping to these simple rules and practices is often all that is needed for a comprehensive, understandable and deliverable specification.

PUSHING FURTHER - JOINING IDEAS TOGETHER

Of course, if you want to push further, then:
  • If you need to link ideas up into activities and flows, try to keep in binary mode: it will keep the flow and decision points simple. 
    • (For example for inputs it is a good idea to specify for valid, invalid and null values, but rather than keeping a three-value decision point, split it into two binary decisions i.e. value provided - Y (not null)/N (null); then value valid Y (valid)/N (invalid).)
  • Break use cases into simple "SIPOC" (supplier, input, process, output, customer) stories by not mentioning SIPOC at all. Instead, just note down: 
    • what you "start with:", 
    • who this is "provided by:" will deliver you with a great set of preconditions for your... 
    • ...big "do: something" block. 
    • finishing up with "end with: (result)", 
    • and adding "given to:" will keep you results-focused and looking at the next use case in the value chain.
    • You can - if you are feeling adventurous - add some useful detail in a series of use cases by being clear about what "does change" (variables) and what "does not change" (constants) during the use case.
  • Never take anyone's model (including this one) at face value - there will always be cases when it does not quite fit: one format does not fit every type of specification item, so just pick the most appropriate item. For instance, "plain English" may not be the most appropriate specification language for communicating with physicists!
  • Know when to add complexity (by reading about and understanding all the different ways and means of specifying - see "Reading and Improving")
  • Know when to stop paper-specification and move to code (including tests and comments, for example JavaDocs) - or you will spend a great deal of time maintaining paper documents which will ALWAYS be slightly out-of-date and inaccurate.

READING AND IMPROVING

A short blog post talking about simplicity will never be comprehensive, so I would strongly recommend the following books and authors (just a short(!) selection):

  • Requirements Engineering Fundamentals (Pohl & Rupp)
  • Any of Karl Wieger's books on Software Requirements
  • The RSpec Book (Chelimsky et al)
  • Specification by Example (Adzic)
  • Writing Effective Use Cases (Cockburn)
  • Test Driven (Koskela)
If you are interested in what Schiller actually said, it is:

Kannst du nicht allen gefallen durch deine Tat und dein Kunstwerk,
mach' es wenigen recht; vielen gefallen ist schlimm.

I will try to follow up on this post with more detail on the SIMPLE RULES, but in most cases, just thinking about each of these super simple questions without any other background is a really helpful technique, as I hope will become evident in the example below.

Examples


Just to make things somewhat easier to understand, here is a completely invented example which is far from perfect, but shows how applying the simple rules can help to build up into a solid requirement or specification item.

1. Not "an email will be sent"... BUT "The software's email component will send an email" (active sentence)
2. Even better still is..

  •   "The software's email component will send an email to the designated recipient" (who)
  • "The software's email component will send a confirmation email to the designated recipient" (what)
  • "The software's email component will send a confirmation email to the designated recipient to allow him/her to know their request has been successfully processed" (why)
  • "When a submitted request has been confirmed as completely processed, the software's email component will immediately send a confirmation email to the designated recipient to allow him/her to know their request has been successfully processed" (where and when)

3. Even better still is...being very precise about "triggers" and "non-triggers".

  • "When a submitted request has been confirmed as completely processed, the software's email component will immediately send a confirmation email to the designated recipient to allow him/her to know their request has been successfully processed. A confirmation email will not be sent when the request has not been confirmed as completely processed or where a designated recipient has not provided his/her email address." (NOT)

4. ...and adding in the "how often, how much" detail helps also...

  • "When a submitted request has been confirmed as completely processed, the software's email component will immediately send a confirmation email to the designated recipient to allow him/her to know their request has been successfully processed. A confirmation email will not be sent when the request has not been confirmed as completely processed or where a designated recipient has not provided his/her email address. A confirmation email will only be sent once a week to any individual designated recipient regardless of how many requests have been submitted."


If you then start to add in examples of each of the elements and what output you expect for each example (such as where a request is in the submission process, or different designated recipient details, or expected content of a confirmation email, or designated recipients who have made single requests, multiple requests etc.), then you really start to get a coherent, complete and testable specification item.

No comments: