A logbook for curious waters
← Software Engineering Field Guide

Move Statements into Function

Before you begin: Functions, callers, and string construction.

Move Statements into Function moves work that callers repeatedly perform beside a function call into the function itself. The move is useful when that repeated work is part of the function’s responsibility, not just something these callers happen to do today. 1

Original version: every receipt caller adds the same closing text

The examples construct text rather than send email or contact a printer. Both delivery formats use the same receipt body and add the same thank-you line.

public static class Receipts
{
    private static string Body(int total) { return "Total: " + total; }
    public static string Email(int total)
    {
        return "EMAIL " + Body(total) + " | Thank you";
    }
    public static string Print(int total)
    {
        return "PRINT " + Body(total) + " | Thank you";
    }
}
def _body(total):
    return "Total: " + str(total)


def email_receipt(total):
    return "EMAIL " + _body(total) + " | Thank you"


def print_receipt(total):
    return "PRINT " + _body(total) + " | Thank you"

The closing text belongs to the receipt in both cases, but each caller is responsible for remembering it. A third delivery format could easily omit it.

Refactored version: the receipt body includes its closing text

public static class Receipts
{
    private static string Body(int total)
    {
        return "Total: " + total + " | Thank you";
    }
    public static string Email(int total) { return "EMAIL " + Body(total); }
    public static string Print(int total) { return "PRINT " + Body(total); }
}
def _body(total):
    return "Total: " + str(total) + " | Thank you"


def email_receipt(total):
    return "EMAIL " + _body(total)


def print_receipt(total):
    return "PRINT " + _body(total)

The callers retain only their delivery-specific prefixes. Their final text remains identical, while the shared closing rule now has one owner.

Inspect every caller before widening the function’s job

If another caller needs a bare total with no closing text, moving the suffix into the helper changes that caller’s result. You may need a separate operation or a different extraction rather than changing every consumer indiscriminately.

With side effects, check order and frequency. Moving a notification inside a function can make it run for callers that previously did not notify, or run more often if the function is called repeatedly.

This is not merely a search-and-replace for duplicate lines. Establish that the moved work belongs to the operation’s contract. Then remove the repeated statements from migrated callers so the work does not happen twice.

Sources

  1. Martin Fowler — Move Statements into Function.