A-Level Computer Science / Unit 12: Software Design, Testing and Evolution

12.3.6 Maintaining and Extending Existing Software

πŸ”’ Lesson slides are available to signed-in users. Sign in

12.3.6 Maintaining and Extending Existing Software

Releasing a program does not end its development. Faults may be discovered, requirements may change and the internal design may become difficult or inefficient. Developers therefore continue to analyse, modify and test software throughout its useful life.

The reason for a change determines its maintenance category. Corrective maintenance repairs a known fault. Adaptive maintenance responds to a changed requirement or environment. Perfective maintenance improves the quality, performance or maintainability of software that already behaves correctly.

By the end of this section, you should be able to:

  • Explain why software requires continuing maintenance.
  • Distinguish corrective, adaptive and perfective maintenance.
  • Classify a change from the reason it is required.
  • Describe a systematic corrective-maintenance process.
  • Carry out an impact analysis for a changed requirement.
  • Explain how refactoring can improve maintainability.
  • Explain how a change can improve performance.
  • Analyse existing pseudocode and amend it to extend functionality.
  • Explain why changed software requires retesting and regression testing.

Why Software Requires Continuing Maintenance

Software does not physically wear away, but the conditions surrounding it do not remain fixed. New inputs, new devices, changed working practices and previously unseen paths may all reveal a need for change.

Reason for continued work Example Likely response
A fault is reported. An irrigation recommendation is wrong when soil moisture is exactly 18%. Locate and correct the fault.
A requirement changes. The allotment must now follow weekly water-restriction rules. Extend the program to support the new rule.
The operating environment changes. The dashboard must run on handheld devices used outdoors. Adapt the interface and input handling.
The code becomes difficult to change. The same moisture-validation code appears in several modules. Refactor the repeated logic.
Performance becomes unacceptable. Every screen refresh scans the complete sensor-history file. Improve how the latest reading is found.
Common misconception: Maintenance does not mean only repairing broken code. It also includes adapting and improving an existing system.

The Three Maintenance Types

Type Main reason for the change Question to ask Allotment example
Corrective An identified fault must be repaired. Is the current program producing incorrect behaviour? Moisture of exactly 18% receives the wrong watering duration.
Adaptive The requirements or operating environment have changed. Must the program now do something different or work somewhere new? The scheduler must apply water-restriction rules.
Perfective A working system is improved in quality, structure, maintainability or performance. Does the behaviour remain essentially the same while the implementation improves? Repeated validation is moved into one reusable function.
Classification principle: identify why the software is being changed, not merely what code is edited.
Exam tip: State both the maintenance type and the reason. Naming the type alone does not explain why it fits the scenario.

Corrective Maintenance

Corrective maintenance: modifying existing software to repair an identified fault that causes incorrect behaviour or failure.

The fault may be a logic error or a run-time error. It may affect every execution, or it may appear only under a particular combination of data and conditions.

Reported symptom Possible underlying cause Evidence needed
Incorrect recommendation Wrong comparison operator or formula Input, expected result and actual result
Program stops Invalid array position or arithmetic operation Error message, call sequence and data
Program does not terminate Loop-control variable is not updated correctly Repeated variable values and loop condition
Stored data becomes inconsistent Only one of several related records is updated Database state before and after the action

Why faults may appear after release

  • The faulty path is rarely selected.
  • The fault requires an unusual combination of valid data.
  • A limit or boundary was not tested.
  • The production environment differs from the test environment.
  • A previous change introduced a regression.
  • A large data volume exposes a problem that small test files did not reveal.
Common misconception: Software that has worked for a long time is not necessarily fault-free. The conditions needed to expose a hidden fault may not have occurred yet.

A Corrective-maintenance Process

  1. Record the report. Capture the program version, environment, user actions, input, expected result and actual result.
  2. Reproduce the fault. Repeat the reported conditions in a controlled environment.
  3. Reduce the failing case. Remove irrelevant actions or data until the smallest repeatable example remains.
  4. Locate the first incorrect state. Use traces, logging, breakpoints or watched variables.
  5. Identify the root cause. Do not assume that the visible symptom is the faulty statement.
  6. Design the correction. Consider which modules, interfaces and stored data may be affected.
  7. Implement the smallest safe change. Avoid unrelated edits during the correction.
  8. Retest the original failure. Confirm that the reported behaviour is now correct.
  9. Run regression tests. Check nearby boundaries and related existing behaviour.
  10. Update records and release the correction. Record the changed version, test evidence and deployment decision.

Original fault example

The requirement for an irrigation scheduler is:

  • moisture below 18% β†’ 24 minutes;
  • moisture from 18% to 35% inclusive β†’ 12 minutes;
  • moisture above 35% β†’ no watering.

The existing condition is:

IF Moisture <= 18 THEN
    RETURN 24
ELSE
    IF Moisture <= 35 THEN
        RETURN 12
    ELSE
        RETURN 0
    ENDIF
ENDIF

At exactly 18%, the first condition is true, so the function returns 24 rather than 12. The comparison should be:

IF Moisture < 18 THEN
Moisture Expected before correction Actual before correction Retest after correction
17 24 minutes 24 minutes Pass
18 12 minutes 24 minutes Pass after correction
19 12 minutes 12 minutes Pass
35 12 minutes 12 minutes Pass
36 0 minutes 0 minutes Pass
Exam tip: A complete corrective-maintenance answer should include reproduction, root-cause investigation, correction, retesting and regression testing.

Adaptive Maintenance

Adaptive maintenance: changing existing software so that it continues to meet changed requirements or works in a changed environment.

The original program may be correct according to its original specification. The change is needed because the required behaviour or operating context is now different.

Source of change Allotment example Possible adaptation
New organisational rule Watering is restricted on selected weekdays. Add restriction-day data and scheduling decisions.
New user need Gardeners want recommendations for seedlings and established plants. Add a plot-stage field and different duration rules.
New external service A rainfall forecast becomes available. Connect the scheduler to forecast data.
New operating environment Staff need to use the system on outdoor tablets. Adapt layout, controls and offline behaviour.
Changed data format A sensor now transmits a decimal percentage rather than an integer. Update interfaces, validation and storage.
Exam tip: Make the changed requirement or environment explicit. Without this reason, an adaptive-maintenance explanation is incomplete.

Impact Analysis Before Adaptation

Impact analysis: identifying the parts of a system that may be affected by a proposed change before implementation begins.

A feature that appears small at the user interface may require changes to data, modules, interfaces, files, tests and documentation.

Change request

The scheduler must apply a water-restriction mode. During a restriction, normal recommendations cannot exceed eight minutes. Moisture below 10% is treated as an emergency and may receive twelve minutes.
Affected area Possible change Question to answer
Requirements Define emergency and non-emergency restriction behaviour. Are the limits inclusive?
Input Add RestrictionActive. Who sets the value and when does it change?
Processing Add restriction decisions after the normal recommendation. Which rule takes priority?
Module interface Pass the new Boolean parameter to the recommendation function. Which callers must be updated?
Stored data Record whether a recommendation was restricted. Is a new record field needed?
Output Explain when the normal duration has been reduced. What message should the user see?
Tests Add restriction and emergency cases. Which existing tests must still pass?
Documentation Update user instructions and module descriptions. Which documents describe the old behaviour?
Common mistake: Do not assume that a new feature affects only the module in which its final calculation appears.

Perfective Maintenance

Perfective maintenance: improving working software so that it is easier to understand, test, modify or operate, or so that it uses time and resources more efficiently.

Perfective maintenance generally preserves the required external behaviour. The improvement is mainly in quality, internal structure, maintainability or performance.

Working-system issue Perfective change Benefit
Moisture validation is repeated in several modules. Create one reusable validation function. One rule and message need to be maintained.
One procedure performs input, calculation, storage and output. Split it into focused modules. Each responsibility can be understood and tested separately.
Identifiers such as x1 and v are unclear. Rename them to express their purpose. Future developers can follow the algorithm more easily.
The full history file is scanned for every plot display. Maintain direct access to each plot’s latest reading. Fewer records need to be examined.
The same conversion is repeated several times in one request. Calculate once and reuse the result where safe. Unnecessary processing is reduced.
Common misconception: Adding a newly required feature is usually adaptive maintenance. Perfective maintenance improves the existing implementation or quality.

Improving Maintainability

Maintainability: how easily software can be understood, tested, corrected and changed in the future.

Maintainability can be improved by:

  • using meaningful identifiers;
  • dividing long routines into focused modules;
  • reducing duplicated code;
  • using parameters rather than unnecessary global variables;
  • keeping module interfaces clear and limited;
  • using consistent coding and documentation conventions;
  • removing unreachable or obsolete code;
  • adding suitable comments that explain purpose or non-obvious decisions;
  • maintaining automated regression tests where available.

Repeated validation before refactoring

REPEAT
    INPUT Moisture
    IF Moisture < 0 OR Moisture > 100 THEN
        OUTPUT "Enter a percentage from 0 to 100"
    ENDIF
UNTIL Moisture >= 0 AND Moisture <= 100

REPEAT
    INPUT ReservoirLevel
    IF ReservoirLevel < 0 OR ReservoirLevel > 100 THEN
        OUTPUT "Enter a percentage from 0 to 100"
    ENDIF
UNTIL ReservoirLevel >= 0 AND ReservoirLevel <= 100

After refactoring

FUNCTION GetPercentage(
    BYVALUE Prompt : STRING
) RETURNS INTEGER

    DECLARE Value : INTEGER

    REPEAT
        OUTPUT Prompt
        INPUT Value

        IF Value < 0 OR Value > 100 THEN
            OUTPUT "Enter a percentage from 0 to 100"
        ENDIF
    UNTIL Value >= 0 AND Value <= 100

    RETURN Value
ENDFUNCTION

Moisture ← GetPercentage("Enter soil moisture")
ReservoirLevel ← GetPercentage("Enter reservoir level")
Exam tip: Do not write only that the refactored code is β€œcleaner.” Explain that duplication is reduced, future changes occur in one place and inconsistent behaviour is less likely.

Improving Performance

Performance improvements may reduce execution time, memory use, file access or network activity. The changed version must still produce the required results.

Current approach Possible improvement Measure to compare
Scan every historical reading to find the latest value. Maintain a direct latest-reading record for each plot. Records examined and response time
Open and reread the same configuration file for every calculation. Load the configuration once when appropriate. File operations and elapsed time
Calculate the same daily summary for every screen component. Calculate once and pass the result to each component. Number of repeated calculations
Load all plot histories when one plot is requested. Retrieve only the requested plot’s data. Memory use and data-transfer volume
Important: An optimisation should be supported by evidence. A more complicated implementation is not automatically faster or more appropriate.
Exam tip: Name the resource improved: execution time, memory, file access, network transfer or another measurable factor.

Comparing the Maintenance Types

Scenario Type Reason
Exactly 18% moisture receives 24 minutes rather than 12. Corrective The current program violates its existing requirement.
The scheduler must now obey a weekly water-restriction rule. Adaptive The required functionality has changed.
Repeated validation is moved into one function. Perfective The required behaviour remains the same, but maintainability improves.
The program must run on a new outdoor tablet platform. Adaptive The operating environment has changed.
A full-file search is replaced by indexed access. Perfective Working software is made more efficient.
A previous release sometimes stores the wrong plot identifier. Corrective An identified fault must be repaired.

A quick classification method

  1. Identify the behaviour before the change.
  2. Identify the reason a change is requested.
  3. Ask whether an existing requirement is currently violated.
  4. Ask whether the requirement or environment has changed.
  5. Ask whether external behaviour is preserved while internal quality improves.
  6. Select the type and justify it using the reason.
Exam tip: The same release can contain more than one maintenance type. For example, a fault may be fixed while a related module is also refactored. Classify each change separately.

Managing a Maintenance Change

Maintenance should follow a controlled process. Editing a released system without understanding the impact can introduce new faults.

Stage Main activity Evidence produced
1. Request or fault report Record why a change is needed. Change request or defect report
2. Classification Identify the maintenance type and priority. Reasoned category and severity
3. Impact analysis Identify affected requirements, modules, interfaces, data and tests. Impact list and risk assessment
4. Design Plan the amended behaviour and structure. Updated algorithms, interfaces or data design
5. Implementation Change a controlled version of the code. Version-controlled source changes
6. Testing Run new, direct-retest and regression cases. Expected and actual test results
7. Review and approval Confirm that the change is safe to release. Review decision or approval
8. Deployment Release the changed version and monitor it. Version, release notes and monitoring evidence
Common mistake: Do not edit the live version without retaining the previous working version and a record of the change.

Analysing and Extending an Existing Program

Consider the original working function:

FUNCTION RecommendMinutes(
    BYVALUE Moisture : INTEGER
) RETURNS INTEGER

    IF Moisture < 18 THEN
        RETURN 24
    ELSE
        IF Moisture <= 35 THEN
            RETURN 12
        ELSE
            RETURN 0
        ENDIF
    ENDIF
ENDFUNCTION

New requirement

A new Boolean parameter named RestrictionActive must be supported:

  • when no restriction is active, preserve the existing behaviour;
  • during a restriction, a normal recommendation is limited to eight minutes;
  • during a restriction, moisture below 10% is an emergency and receives twelve minutes;
  • a recommendation of zero remains zero.

Step 1: preserve the original calculation

First calculate the existing recommendation. This reduces duplication and makes it easier to verify that unrestricted behaviour has not changed.

Step 2: apply the new rule

FUNCTION RecommendMinutes(
    BYVALUE Moisture : INTEGER,
    BYVALUE RestrictionActive : BOOLEAN
) RETURNS INTEGER

    DECLARE RecommendedMinutes : INTEGER

    IF Moisture < 18 THEN
        RecommendedMinutes ← 24
    ELSE
        IF Moisture <= 35 THEN
            RecommendedMinutes ← 12
        ELSE
            RecommendedMinutes ← 0
        ENDIF
    ENDIF

    IF RestrictionActive = TRUE THEN
        IF Moisture < 10 THEN
            RecommendedMinutes ← 12
        ELSE
            IF RecommendedMinutes > 8 THEN
                RecommendedMinutes ← 8
            ENDIF
        ENDIF
    ENDIF

    RETURN RecommendedMinutes
ENDFUNCTION

Step 3: identify all affected calls

Every call must now supply the new argument:

Minutes ← RecommendMinutes(
    CurrentMoisture,
    RestrictionActive
)

Step 4: design tests before release

Moisture Restriction Purpose Expected minutes
9 FALSE Existing low-moisture behaviour 24
9 TRUE Emergency during restriction 12
10 TRUE Immediately outside emergency condition 8
18 FALSE Preserve existing boundary behaviour 12
18 TRUE Restriction cap applied 8
36 TRUE No watering remains no watering 0
Exam tip: When amending an existing program, identify the new parameter, affected calls, changed decisions and tests for both new and preserved behaviour.

Testing Maintenance Changes

Every maintenance change can introduce a regression, including a change intended only to improve internal structure.

Testing activity Purpose Example
Direct retest Check the original fault after correction. Retest moisture of exactly 18%.
New-feature tests Check added adaptive behaviour. Test restriction and emergency combinations.
Regression tests Check that existing behaviour still works. Repeat unrestricted recommendation cases.
Interface tests Check changed parameters and return values. Confirm every caller supplies RestrictionActive.
Performance comparison Check whether a perfective optimisation achieved its aim. Compare records scanned before and after indexing.
Equivalence tests Check that refactoring preserved externally visible behaviour. Run the same validation inputs before and after refactoring.
Regression testing: repeating relevant existing tests after a change to check that previously working behaviour has not been damaged.
Common misconception: A perfective change still requires testing. Refactoring can accidentally alter control flow, parameters or returned results.

Documentation, Versions and Release

Maintenance changes should be understandable to future developers and users.

Record Information to update
Requirements specification New or changed behaviour and acceptance criteria
Design documentation Changed modules, data structures, algorithms and interfaces
Source comments Purpose of non-obvious decisions rather than a history of every edit
Test plan New cases, regression cases and recorded outcomes
Fault or change record Reason, priority, affected version and resolution
User documentation Changed screens, workflows or messages
Release notes Version number, corrections, adaptations and known limitations
Exam tip: Documentation is part of maintenance because an unexplained change makes future analysis and modification more difficult.

Interactive: Corrective-maintenance Debugger

Follow a reported boundary fault through reproduction, diagnosis, correction and regression testing.

Existing function

IF Moisture <= 18 THEN
    RETURN 24
ELSE
    IF Moisture <= 35 THEN
        RETURN 12
    ELSE
        RETURN 0
    ENDIF
ENDIF
Fault report

A boundary result is incorrect

At exactly 18% moisture, the scheduler recommends 24 minutes. The requirement says it should recommend 12 minutes.

Focus: record the version, input, expected result and actual result before editing the code.
Moisture First condition Expected minutes Actual minutes Finding

Interactive: Adaptive-maintenance Change Explorer

Select a new requirement and inspect the modules, data, interfaces and tests that may be affected.

New requirement

Apply water-restriction limits

The working scheduler must now reduce recommendations when a restriction is active, while preserving an emergency rule for very dry soil.

Existing program works Requirement changed
Affected areas

Step 1 of 5

Clarify the new rule

Define the restriction cap, emergency threshold and priority between rules.

Exam focus: Explain that the existing program is changed because the required behaviour has changed, then identify affected modules, data and tests.

Interactive: Perfective-maintenance Refactor Lab

Compare duplicated validation, a reusable routine and a faster latest-reading lookup. Observe which quality measure is being improved.

Before perfective maintenance

REPEAT
    INPUT Moisture
UNTIL Moisture >= 0
  AND Moisture <= 100

REPEAT
    INPUT ReservoirLevel
UNTIL ReservoirLevel >= 0
  AND ReservoirLevel <= 100
Repeated code

The program works, but one rule is duplicated.

The same validation logic appears in several places. A later rule change may require several edits and could create inconsistent behaviour.

Maintainability
40%
Performance
70%
Change safety
35%
Exam focus: Explain that duplicated logic makes future changes harder and less reliable.

Common Mistakes and Misconceptions

  • Calling every change corrective. Corrective maintenance specifically repairs a fault.
  • Calling every new feature perfective. A changed required function is normally adaptive.
  • Classifying from the edited code. The reason for the change determines the maintenance type.
  • Editing before reproducing a fault. The original failing case provides evidence for the correction.
  • Treating the symptom as the root cause. An incorrect screen value may originate in another module.
  • Adding a requirement without impact analysis. Inputs, interfaces, data, tests and documentation may all change.
  • Explaining perfective maintenance as β€œmaking code nicer.” State how maintainability, performance or resource use improves.
  • Assuming refactoring cannot introduce faults. Working behaviour must be retested.
  • Testing only the changed feature. Existing behaviour also requires regression testing.
  • Failing to update documentation. Outdated interfaces and requirements make later maintenance risky.

Practice

Core questions

  1. Explain why a released system may require continuing maintenance.
  2. Define corrective maintenance.
  3. Define adaptive maintenance.
  4. Define perfective maintenance.
  5. Explain how the reason for a change determines its category.
  6. State five stages in a corrective-maintenance process.
  7. Explain why impact analysis is needed before an adaptive change.
  8. Explain how refactoring can improve maintainability.
  9. Give two examples of perfective performance improvements.
  10. Explain why regression testing is required after maintenance.

Scenario A: Corrective Maintenance

A greenhouse controller should open a vent when temperature is greater than 28Β°C. Users report that it also opens at exactly 28Β°C.

  1. Classify the maintenance type.
  2. Suggest a possible faulty condition.
  3. State the corrected condition.
  4. Give suitable reproduction and boundary tests.
  5. Explain which regression tests should follow the correction.

Scenario B: Adaptive Maintenance

A working workshop-booking system must now allow remote sessions with video links.

  1. Explain why this is adaptive maintenance.
  2. Identify four affected parts of the system.
  3. Suggest one new data field.
  4. Suggest one changed module interface.
  5. Write three tests for the new behaviour.
  6. State two existing behaviours that require regression testing.

Scenario C: Perfective Maintenance

A record-search program returns correct results, but it scans 80,000 records from the beginning for every query. Several modules also contain copied search code.

  1. Explain why perfective maintenance is appropriate.
  2. Suggest one maintainability improvement.
  3. Suggest one performance improvement.
  4. State what should be measured before and after the change.
  5. Explain how to check that search results remain equivalent.

Scenario D: Analyse and Amend

FUNCTION DeliveryPriority(
    BYVALUE Distance : INTEGER
) RETURNS STRING

    IF Distance <= 5 THEN
        RETURN "LOCAL"
    ELSE
        RETURN "STANDARD"
    ENDIF
ENDFUNCTION

A new requirement adds an Urgent Boolean. An urgent delivery should return "EXPRESS" regardless of distance.

  1. State the maintenance type.
  2. Amend the function header.
  3. Amend the algorithm.
  4. Identify all calling code that may be affected.
  5. Design tests for urgent and non-urgent deliveries.
Challenge: Describe one release containing a corrective change, an adaptive change and a perfective change. Classify and justify each amendment separately.

Review

Prompt A strong response should include
Corrective maintenance Repair of an identified fault, followed by direct retesting and regression testing
Adaptive maintenance A change required by a new specification, user need, interface or operating environment
Perfective maintenance Improvement of working software’s structure, maintainability or performance
Impact analysis Identification of affected requirements, modules, interfaces, data, tests and documentation
Maintainability Ease of understanding, testing, correcting and modifying software
Regression testing Repetition of relevant existing tests after a change
Extending functionality Analyse the existing program, amend interfaces and logic, and test new and preserved behaviour
Final exam tip: Use the chain reason for change β†’ maintenance type β†’ affected areas β†’ amendment β†’ testing.