Welcome to Defensive Design!

In this chapter, we are going explore how programmers make sure their software is robust. A robust program is one that doesn't crash or behave strangely if a user makes a mistake or if something unexpected happens. Think of it like "bulletproofing" your code!

We will look at how to stop users from breaking our programs and how to write code that is easy for other humans to read. Don't worry if this seems a bit technical at first—it's actually just about being organized and prepared!

1. What is Defensive Design?

Imagine you are designing a car. You wouldn't just assume the driver is a perfect professional. You would add seatbelts, airbags, and a warning light if the door is open. Defensive Design is the same thing but for computer programs. It's the practice of thinking ahead to prevent things from going wrong.

Anticipating Misuse

Programmers must anticipate misuse. This means thinking: "What's the silliest or most dangerous thing a user could try to do with my program?"
Users might:
- Enter a word when the program asks for a number.
- Leave a required box empty.
- Try to guess a password 1,000 times (a brute-force attack).
- Try to enter data that is way too long for the system to handle.

Quick Review: Defensive design is about making a program robust so it can handle mistakes without crashing.

2. Input Validation

Input Validation is a defensive design technique where the program checks if the data entered by the user follows certain rules before it is processed. If the data is "invalid" (wrong), the program should reject it and ask the user to try again.

Common Validation Checks:

- Type Check: Does the input have the right data type? (e.g., Is it a number and not a word?)
- Range Check: Is the number within a certain limit? (e.g., An age must be between 0 and 120).
- Presence Check: Did the user actually type something, or did they leave it blank?
- Format Check: Does it look the way it should? (e.g., Does a postcode have the right mix of letters and numbers?)
- Length Check: Is the input too short or too long? (e.g., A password must be at least 8 characters).

Analogy: Think of a "Shape Sorter" toy for toddlers. If you try to put a square block into a round hole, it won't go in. That is physical validation!

Key Takeaway: Validation checks rules, not truth. If a program asks for your birthday and you enter a fake date that follows the rules, the program will accept it. It just ensures the data is sensible.

3. Authentication

Authentication is the process of confirming the identity of a user. It's about making sure the person using the program is who they say they are.

The most common way to do this is with a username and password.
- Step 1: The user enters their credentials.
- Step 2: The program checks these against a stored database.
- Step 3: If they match, access is granted. If not, access is denied.

Pro-tip: To make authentication even more "defensive," a programmer might limit the number of failed login attempts to stop hackers from guessing passwords.

4. Maintainability

A "robust" program isn't just one that doesn't crash; it's also one that other programmers can understand and fix later. This is called maintainability. If you write messy code, it's very hard to find and fix bugs (errors)!

To keep code maintainable, we use these four tricks (Memory Aid: S.I.N.C.):

1. Sub-programs (Functions and Procedures)

Instead of writing one giant "wall of text" for your code, you should break it into smaller, manageable chunks called sub-programs.
Analogy: Instead of one long recipe for a 5-course meal, you have separate recipes for the starter, the main, and the dessert.

2. Indentation

This means moving lines of code to the right when they belong inside a loop or an "if-statement." It makes the structure of the code easy to see at a glance.
Example: In Python, if you don't indent, the program won't even run!

3. Naming Conventions

Use descriptive names for variables and sub-programs.
- Bad: x = 50
- Good: user_score = 50
Descriptive names tell anyone reading the code exactly what that data is for.

4. Commenting

Programmers add notes to their code (starting with symbols like # or //) that the computer ignores. These are for human readers to explain what a specific part of the code is doing.
Example: # This function calculates the total price including tax

Quick Review Box:
- Sub-programs: Break code into chunks.
- Indentation: Shows where blocks of code start and end.
- Naming: Use clear, sensible names for variables.
- Commenting: Explain the logic to other humans.

Common Mistakes to Avoid

- Confusing Validation with Verification: Validation checks if data is allowed (e.g., is it a number?); Verification checks if it is correct (e.g., double-typing a password to make sure you didn't make a typo).
- Thinking "Robust" means "Fast": A robust program might actually be slightly slower because it's busy doing all these extra checks, but it is much safer!
- Forgetting comments: You might think you'll remember why you wrote a line of code, but three months later, you (or your teammates) will be very confused without comments!

Summary: Defensive design is about protecting the program from the user (via validation and authentication) and protecting the code from future confusion (via maintainability).