Modularity in Programming
Reuse means writing a set of instructions once, naming it, and calling that name multiple times throughout a program
The Repetition Problem
Programs often need to perform the same kind of task in several places. For example, a program might need to check whether a number is valid in five different locations. If the checking instructions are copied into all five locations, each copy takes space and must be maintained separately. A change to the checking process must then be made in every copy.
Reuse solves this repetition problem by putting a set of instructions in one place, giving that set a name, and calling the name wherever the instructions are needed. The program is built from named pieces instead of repeated copies of the same instructions.
Reuse means writing a set of instructions once, naming it, and calling that name multiple times throughout a program.
Following a Reused Instruction Set
A call to a named instruction set changes the path of execution. The program reaches the call and temporarily leaves its current location. Execution moves to the definition of the named instruction set, runs all of its steps, and then returns to the line immediately after the call. The original program then continues from there.
Tracing CheckValidity
Follow execution when a program reaches a call to the named instruction set CheckValidity.
Reach the call: The program arrives at the location that says to use CheckValidity.
Jump to the definition: Execution moves to wherever CheckValidity is defined instead of immediately continuing to the next line in the original location.
Complete the instructions: The program runs through every step in CheckValidity.
Return to the caller: After CheckValidity finishes, execution returns to the line immediately after the call.
Continue: The rest of the original program continues from that returned location.
Execution makes a temporary detour to the reused instruction set and then resumes where the call left off.
One Definition, Many Calls
A single named instruction set can be invoked from many different locations in a program. Each call leads to the same definition, where the same instructions are run. The instructions do not change merely because the call comes from a different location; only the context in which they are called differs.
Sharing ValidateEmail
A program needs email validation during signup, during a profile update, and when an email is entered in a form. How does reuse organize this logic?
Write the logic once: The email-validation instructions are placed in one named instruction set called ValidateEmail.
Call from signup: The signup part of the program invokes ValidateEmail when it needs email validation.
Call from profile update: The profile-update part invokes the same named instruction set rather than using a separate copy.
Call from form entry: The form-entry part also invokes ValidateEmail.
Change one definition: If the validation logic needs a fix or improvement, the definition of ValidateEmail is changed in one place, and all three callers use the updated logic.
One named instruction set serves three call locations, creating a one-to-many relationship and avoiding three separate copies.
Why Naming Makes Programs Manageable
Naming an instruction set creates an abstraction. The name acts as a container for the details inside it. A reader can understand a line such as Call ValidateEmail at a high level without tracing every individual validation step immediately.
- The instructions exist in one place, which makes the program smaller and easier to read.
- A fix or improvement can be made in one location and then used everywhere the name is called.
- The instructions can be considered in isolation instead of being traced through multiple scattered copies.
- Callers can remain unchanged when the internal details of the named instruction set change.
When several parts of a program need the same instructions, prefer one named reusable set over separate copies. This keeps the logic in one place and gives the program a clearer high-level structure.
Mistakes About Reuse
Thinking that reuse means copying the instructions into every location.
The instructions then exist in multiple places and must be maintained separately.
Fix:
Write the instructions once, give them a name such as ValidateEmail, and call that name from each location.Thinking that execution continues directly to the next line after a call.
A call first sends execution to the named instruction set, which must complete its steps before execution returns.
Fix:
Trace the call as a detour: move to the definition, complete it, return, and then continue.Assuming that each call requires a different instruction set.
One named instruction set can be called from many different locations.
Fix:
Look for logic that can be shared and connect multiple call locations to the same named definition.Believing that changing the named instruction set requires changing every caller.
The purpose of reuse is that the shared definition is maintained in one place.
Fix:
Update the definition and leave the callers unchanged when the callers still need the same high-level task.
Trace and Apply
A program calls a named instruction set called CheckValidity from two different locations. Describe the execution path for one call and explain what happens when the instructions in CheckValidity are improved.
Hints
- Start at the call location.
- Identify where execution goes before it returns.
- Consider whether the two locations use separate copies or one shared definition.
What do you think happens?
A named instruction set is called from three different locations. If its definition is improved, how many definitions need to be changed for all three locations to use the improvement?
Reveal answer
Answer: One
Reuse keeps the instructions in one named definition. The multiple call locations use that shared definition, so changing it applies the improvement wherever the name is called.
Modularity in Practice
Modularity through reuse organizes a program around named instruction sets. Execution can move from a call location to the shared definition, run its steps, and return to the original program. Because many locations can call one definition, repetition is reduced and changes can be made centrally. The name also hides internal detail, allowing the larger program to be understood as a composition of manageable pieces.
Key Takeaways
- Reuse means writing instructions once, naming them, and calling the name multiple times.
- A call sends execution to the named instruction set, which runs completely before execution returns to the next location in the original program.
- One named instruction set can have many call locations, creating a one-to-many relationship.
- Reuse reduces duplicated instructions and makes programs easier to understand, maintain, and modify.
- Naming creates an abstraction that lets programmers work with a task at a high level without repeatedly examining every internal step.