Object-Oriented Python · Lesson 157

Refactor Duplicated Code

Refactoring changes code structure without intentionally changing observable behaviour.

ConceptWorked examplePracticeKnowledge check
Textbook walkthrough

Refactor Duplicated Code

Refactoring changes code structure without intentionally changing observable behaviour. When the same logic appears in several places, extracting it into a well-named function or method creates one source of truth, makes testing easier and reduces the risk that later fixes are applied inconsistently.

Learning goal: explain why Refactor Duplicated Code behaves this way, apply it to a small example, and verify the result independently. Begin by being able to justify this first step: Identify genuinely duplicated logic rather than merely similar-looking lines.

Deeper walkthrough

Read Refactor Duplicated Code as a mechanism, not a recipe

Treat this as a sequence of observable decisions rather than one opaque command. Stage 1: Identify genuinely duplicated logic rather than merely similar-looking lines. Stage 2: Define the varying inputs as parameters and the common result as a return value. Stage 3: Replace each duplicate block with a call to the new abstraction. Final checkpoint: Prefer a simple function over a class hierarchy when no persistent object state is needed.

Mechanism

Follow the transformation

Identify genuinely duplicated logic rather than merely similar-looking lines.

Define the varying inputs as parameters and the common result as a return value.

Replace each duplicate block with a call to the new abstraction.

Evidence

Know what would convince you

  • Trace a tiny input by hand and compare the runtime result.
  • Inspect type, value/shape and any mutation/side effect explicitly.
Useful distinctionInput: Objects/values supplied to the operation.
How it works

Trace the mechanism step by step

  1. Identify genuinely duplicated logic rather than merely similar-looking lines.
  2. Define the varying inputs as parameters and the common result as a return value.
  3. Replace each duplicate block with a call to the new abstraction.
  4. Run tests before and after the refactor.
  5. Prefer a simple function over a class hierarchy when no persistent object state is needed.
Worked demonstration

Extract duplicated formula

# Step 1 — Define the reusable `net_amount` function; its indented body describes what happens for each call.
def net_amount(gross, discount_rate):
    # Step 2 — Return the computed value to the caller so the result can be reused or tested.
    return gross * (1 - discount_rate)

# Step 3 — Display the current value explicitly so the result/state can be inspected during execution.
print(net_amount(100, 0.10))
# Step 4 — Display the current value explicitly so the result/state can be inspected during execution.
print(net_amount(250, 0.20))
Expected / illustrative result
One tested function now defines the discount calculation for both cases.
Interpret the result.

For Refactor Duplicated Code, trace the specific input through the mechanism above and independently verify one returned value, state change or side effect.

Distinctions & related ideas

Place the concept correctly

InputObjects/values supplied to the operation.
StateNames or mutable objects that may change during execution.
OutputReturned value, side effect, file, plot or exception to inspect.
Use deliberately

When it is appropriate

Use Refactor Duplicated Code when it answers a defined question in Object-Oriented Python and its inputs/assumptions match the current data or program state.

Boundary conditions

When to stop or reconsider

Reconsider Refactor Duplicated Code when the required information is unavailable, the operation would violate a validation/data boundary, or a simpler operation answers the question more transparently.

Common mistakes

Failure modes to recognise

  • Running the operation on the wrong object/type or in the wrong environment.
  • Inferring correctness from “no exception” without checking the produced value/state.
  • Hiding a boundary case instead of making its behaviour explicit.
Verification

How to check the result

  • Trace a tiny input by hand and compare the runtime result.
  • Inspect type, value/shape and any mutation/side effect explicitly.
  • Run an edge or invalid case and confirm the exception/behaviour is deliberate.
Hands-on practice

Demonstrate understanding

Try this:

Construct a tiny example of Refactor Duplicated Code. First identify genuinely duplicated logic rather than merely similar-looking lines. Then define the varying inputs as parameters and the common result as a return value. Predict the result before execution and explain one boundary or failure case.

Use the smallest values that expose the language rule. Write the expected value and type first, then compare the actual state/output with that prediction.
Knowledge check

Check reasoning, not memorisation

Which approach best demonstrates understanding of Refactor Duplicated Code?

Quick reference

Remember the logic

Step 1Identify genuinely duplicated logic rather than merely similar-looking lines.
Step 2Define the varying inputs as parameters and the common result as a return value.
Step 3Replace each duplicate block with a call to the new abstraction.
Step 4Run tests before and after the refactor.
Lesson summary

What to remember

  • Refactoring changes code structure without intentionally changing observable behaviour. When the same logic appears in several places, extracting it into a well-named function or method creates one source of truth, makes testing easier and reduces the risk that later fixes are applied inconsistently.
  • Identify genuinely duplicated logic rather than merely similar-looking lines.
  • Running the operation on the wrong object/type or in the wrong environment.
  • Trace a tiny input by hand and compare the runtime result.