Chapter 2: Gathering Requirements

In the previous chapter, we talked a lot about how customer satisfaction is really important(The first step in writing great software) but do you know how to figure out what a customer really needs? and how to make sure that the customers even know what they really want?

In this chapter, we will discuss a lot about gathering requirements and customer satisfaction also we'll learn some steps to follow to make sure that our apps will be "satisfaction guaranteed".

Doug's Dog Doors (Start-up company).

You've just been hired as the lead programmer. Doug’s got a pretty high-tech door under development and he's decided you're the programmer that can write all the software to make his killer hardware work.

Here are the new sales insert that is running in all the Sunday papers this week.

image.png

Todd and Gina (Your first customers)

Todd and Gina want more than a "normal plastic flap" dog door for their dog (Fido). So they called us to build them the dog door of their dreams which is a door operating off with a remote control.

Fido's Door (V1)

Let's try to represent the system's entities by classes.

DogDoor.java -> This class will act as an interface for Doug's custom door hardware.

public class DogDoor {
    private boolean open;

    public DogDoor() { this.open = false; }

    // This function opens the door
    public void open() { this.open = true; }

    // This function closes the door
    public void close() { this.open = false; }

    // This function checks door's state
    public boolean isOpen() { return this.open; }
}

Remote.java -> This class will act as an interface for Doug Door's remote control.

public class Remote {
    private DogDoor door;

    public Remote(DogDoor door){ this.door = door }

    public void pressButton() {
        if (this.door.isOpen()){
            this.door.close();
        }else{
            this.door.open();
        }
    }
}

DogDoorSimulator.java -> this class will act as an interface for dog (just for simulation purposes it's not part of the system)

public class DogDoorSimulator {
    public static void main(String[] args) {
        DogDoor door = new DogDoor();
        Remote remote = new Remote(door);
        System.out.println("Fido barks to go outside...");
        remote.pressButton();
        System.out.println("\nFido has gone outside...");
        remote.pressButton();
        System.out.println("\nFido’s all done...");
        remote.pressButton();
        System.out.println("\nFido’s back inside...");
        remote.pressButton();
    }
}

Let's go show Todd and Gina what We've done...

Customer Expectations

The Door doesn't work as expected, Todd and Gina didn’t expect to have to close the dog door, so they pressed the button on the remote only once to let Fido out. Even Worse, The way they used door created new problems. Rats and Rabbits started coming into their house too through the open door.

all of this happened because we built the door without having enough information about how the door really should work.

New Plan

So let's back to Todd and Gina again but this time with goals...

  1. Gathering requirements for the dog door.
  2. Figure out what the door should really do.
  3. Get any additional information we need from Todd and Gina.
  4. Build the door RIGHT!

Requirement: It's a specific thing your system has to do to work correctly.
Ex: The dog door system has to "do" lots of things: open, close let Fido out, keep rodents from getting inside... anything that Todd and Gina come up with is part of what the system does.

Remember, the customer decides when a system works correctly or not. So if you leave out a requirement or even if they forget to mention something to you, the system isn't working correctly.

The best thing you can do to gather requirements is to let the customer talk. and focus on what the system should really do (Don't worry about coding in this stage) and translate it into a list of requirements.

image.png

After listening to our customers let's write down their requirements.

List of requirements

  1. The dog door must be at least 12 tall(to fit Fido).
  2. A Single button on the remote control opens the dog door if the door is closed, and closes the dog door if the door is open.
  3. Once the dog door has opened, it should close automatically if the door isn’t already closed(after a few seconds).

Help customers figure out what they really want

It's not just getting a list of requirements but also you need to make sure that the customer understands his requirements.

We can achieve this by showing them a detailed step of how the system should really work.

What the door(V2) does

  1. Fido barks to be let out.
  2. Todd and Gina hear Fido barking.
  3. Todd or Gina presses the button on the remote control.
  4. The dog door opens.
  5. Fido goes outside.
  6. Fido does his business.
  7. Fido goes back inside.
  8. The door shuts automatically.

Also, we need to make sure that the system works as expected, even in unusual circumstances. so we should think about what can go wrong in this list and add some requirements to take care of it before customers know something could have gone wrong.

Plan for things going wrong
So let's read the list of requirements above and see what can go wrong.

  1. Fido barks to be let out.
    • Does Fido always bark when he needs to go outside? what if he just scratches at the door.
  2. Todd and Gina hear Fido barking.
    • What if they don't hear Fido? or even if they aren't home.
  3. Todd or Gina presses the button on the remote control.
    • What if Fido barks because he's excited or hungry?
  4. The dog door opens.
    • What if there is a problem with the hardware?
  5. Fido goes outside.
    • What if Fido stays inside?
  6. Fido does his business.
  7. Fido goes back inside.
    • What if the door closes before Fido gets back inside?
  8. The door shuts automatically.

The more problems you find, the less fragile you can make you apps.

Alternate Paths handle system problems
Now after we've figured out some of the things that can go wrong, we need to update our requirements list to handle these cases.

Let's write down what should happen if the door closes before Fido gets back inside.

  • What the door(V2) does

    1. Fido barks to be let out.
    2. Todd and Gina hear Fido barking.
    3. Todd or Gina presses the button on the remote control.
    4. The dog door opens.
    5. Fido goes outside.
    6. Fido does his business.
      1. The door shuts automatically.
      2. Fido barks to be let back inside.
      3. Todd and Gina hear Fido barking (again).
      4. Todd and Gina press the button on the remote control.
      5. The dog door opens (again).
    7. Fido goes back inside.
    8. The door shuts automatically.
  • We can use these sub-numbers to show alternate paths(these extra steps are called an alternate path).

With some extra steps, Fido can still get inside even if the problem we listed above occurred.

Use Cases

Yes! You've been writing use cases all along, so let's define what is use case is to make sure that we are aligned together.

  • Use Case:
    • A use case describes what your system does to accomplish a particular customer goal.
    • Each use case can provide one or more scenarios but only aims to achieve one customer goal.
    • A use case ends when the customer goal is complete.
    • Alternate path is still about achieving the same goal as the main path, so it's part of the same use case.
    • Use cases are meant to help you understand what a system should do. As a general rule, your use cases should use simple everyday language(not Programmers Languages :D).
    • Use cases are not about coding or programming details. It's all about helping you to make sure you and your customer are aligned for one goal. In our case, the use case is getting Fido outside to do his business, and then back inside. if our system does more than one thing like also counting how many times he's been out in an entire day then you'll need more than one use case, So We should only focus on the What the dog door needs to do? Remember don't worry about the How we will get into this a little bit later.

Also, pay attention that we care about the customer goal but this customer(Todd and Gina) and the user(Fido) are outside of our system(The dog door and remote only).

One use case, three parts
There are three basic parts to a good use case, and you need all three if your use case is going to get the job done.

  • Clear Valuse:
    • Each use case should have a clear value to the system. If the use case doesn't help the customer achieve a goal so it's useless.
    • Ex: our use case must help Todd and Gina deal with Fido.
  • Start and Stop:
    • Every use case should have a clear starting and stopping point. It must be a condition that indicates that the process is complete.
    • Ex: our use case starts up when Fido barks.. it stops when he's back inside.
  • External Initiator:
    • Every use case is started off by an external initiator(could be anything) outside of the system.
    • Ex: in our case, Fido is the external initiator. He's what starts the entire process.

Fido's Door (V2)

So far, we've got an initial set of requirements and a clear solid use case. let's check our requirements list and see what we're going to have to write code for:

  • Todd and Gina Requirements List V2
    1. The dog door must be at least 12 tall(to fit Fido).
      • This is something for the hardware guys to deal with. we don't need any coding here.
    2. A Single button on the remote control opens the dog door if the door is closed, and closes the dog door if the door is open.
      • We're already got the code to take care of this requirement
    3. Once the dog door has opened, it should close automatically if the door isn’t already closed(after a few seconds).
      • This is what Todd and Gina added when we talked to them..
      • We need to write code to take care of closing the door automatically.

Automatically closing the door Let's go back to our Remote class and handle the new requirement.

// 
import java.util.Timer;
import java.util.TimerTask;

public class Remote {
    private DogDoor door;

    public Remote(DogDoor door){ this.door = door }

    public void pressButton() {
        if (this.door.isOpen()){
            this.door.close();
        }else{
            this.door.open();
            // Close the door automatically after few seconds to achieve our goal.
            final Timer timer = new Timer();
            time.schedule(new TimerTask() {
                public void run(){
                    door.close();
                    timer.cancel();
                }
            }, 5000)
        }
    }
}

Also, we need to add some coding for simulation purposes. also, we've to handle the alternative paths to make sure that our system runs as expected for each scenario.

public class DogDoorSimulator {
    public static void main(String[] args) {
        DogDoor door = new DogDoor();
        Remote remote = new Remote(door);

        System.out.println("Fido barks to go outside...");
        remote.pressButton();
        System.out.println("\nFido has gone outside...");
        // we will just ommit "remote.PressButton()" events because the door will close automatically after a few seconds so there is no need to press the button again to close it.
        // remote.pressButton();
        System.out.println("\nFido’s all done...");
        // remote.pressButton();

        // simulate that the door closed automatically before Fido gets back.
        try {
            Thread.currentThread().sleep(1000);
        } catch (InterruptedException e) { }

        System.out.println("\n...but he's stuck outside!");
        System.out.println("\nFido starts barking...");
        System.out.println("\n... so Gina grabs the remote control.");
        remote.pressButton();
        System.out.println("\nFido’s back inside...");
        // Here's another line that should be omitted because the door will close automatically
        // remote.pressButton();
    }
}

The last thing I want to mention before testing our code is the difference between Main Path and ALternate Path.

  • Main Path (A.k.a Happy Path): It never misses an appointment, either. It never makes a mistake, nothing ever goes unexpectedly... you can really count on it to come through just like you want, every time.

  • Alternate Path: Don’t get me wrong... things definitely go wrong in the real world. But when that happens, Main Path just hands things off to my buddy, and it's Alternate Path's turn.

  • Main Path and Alternate Path: We’re all after the same thing which is getting the customer to their goal and making sure they're satisfied, and once we're defined well, actually coding an app is a lot easier.


It works! Let's show Todd and Gina...

Chapter Recap

  • Good requirements ensure your system works like your customers expect.
  • Make sure your requirements cover all the steps in the use cases for your system.
  • Use your use cases to find out about things your customers forgot to tell you.
  • Your use cases will reveal any incomplete or missing requirements that you might have to add to your system.

References

Head First Object-Oriented Analysis And Design