By Rajiv Ramnath

Trained software developers will go about this formally, through a process known as requirements analysis. But for small iOS apps and simple systems, informal methods work quite well. Simply write up a page or two (or three) about your app, how it’s supposed to work, and how its users are supposed to interact with it, and that’s your documentation.

Follow these steps to analyze your material:

  1. Go through the material carefully and pull out

    • Nouns: These become candidate (not final) classes.

    • Verbs: These become candidate responsibilities.

  2. Write the definition of each noun and verb.

    If there are just a few nouns and verbs, you may even be able to keep track of the definitions in your head.

  3. Review your definitions, looking for similar items. If you find two nouns or two verbs that mean about the same thing, remove one of them.

    If a noun or verb has more than one definition, see if splitting it into two nouns or verbs allows you to define each one specifically. Feel free to rename nouns and rewrite verbs so that they fit your definition better.

  4. Delete any nouns and verbs that are only physical objects in the environment in which your system operates. These physical objects are outside the context of your system.

  5. Allocate the consolidated set of verbs (which are the responsibilities) among the nouns (the classes).

    When you are done with this, each noun (that is, class) should have only those responsibilities that properly belong to that noun.

    Here’s a quick test for proper allocation: The responsibilities should not cause the definition of the class to lose cohesiveness.

  6. Create a few detailed scenarios that capture the essential capabilities of your app. Use these scenarios to identify the collaborations by walking through the steps of the scenario in detail, identifying which class and which method enables that step.

    You may also find missing classes and methods. If necessary, repeat Steps 2 through 6 to incorporate missing nouns and verbs in your classes and methods.

  7. For each class, run through this checklist for a good class:

    • Does the class have a suitable name?

    • Does it have a cohesive description that says that it does just one thing?

    • Does it have responsibilities (methods)?

    • Does it have collaborators?

    • Does it — or its components — maintain state?

  8. Consolidate and clean up the class hierarchy.

    Look for classes that have similar data and responsibilities to see if creating a superclass that holds common responsibilities (and having the original classes inherit from this superclass) will increase reuse.

    Before you do a consolidation, perform the “Is-A” test. Say (to yourself): “<Subclass> Is-A <Superclass>.” If that sentence doesn’t completely make sense, the creation of the superclass is incorrect. For example, say, “kettle Is-A vessel.” This sounds correct. Now say, “Vessel Is-A stove.” This doesn’t sound so correct.

  9. Clearly specify (or at least understand) how each method functions:

    • Actions that the method is supposed to perform

    • Inputs that it needs in order to do so

    Go class-by-class, method-by-method, and define its signature, that is, its input parameters and its output result.

Classes of naturally occurring objects (like in the team-making example) automatically tend to follow the preceding principles. This is one reason why extracting classes from your natural environment is a useful way to go about things.