A logbook for curious waters
← Software Engineering Field Guide

Replace Temp with Query

Before you begin: Classes, local variables, and methods that return values.

Replace Temp with Query moves a calculation from a local variable into a method that returns the value. Here query means an operation that asks for information without changing the object—not necessarily a database query. 1

Original version: a calculation belongs to one method

An order line qualifies for a promotion when its subtotal reaches 100 coins. The quantity and unit price are nonnegative integers in this simplified example.

public sealed class OrderLine
{
    private readonly int quantity;
    private readonly int unitPrice;
    public OrderLine(int quantity, int unitPrice)
    {
        this.quantity = quantity;
        this.unitPrice = unitPrice;
    }

    public bool Qualifies()
    {
        int subtotal = quantity * unitPrice;
        return subtotal >= 100;
    }
}

The subtotal exists only as a local variable inside Qualifies. A second operation needing the same calculation would have to repeat it or move it somewhere reusable.

class OrderLine:
    def __init__(self, quantity, unit_price):
        self._quantity = quantity
        self._unit_price = unit_price

    def qualifies(self):
        subtotal = self._quantity * self._unit_price
        return subtotal >= 100

The subtotal exists only while qualifies runs. Its formula is not yet available through a named operation.

Refactored version: ask the line for its subtotal

public sealed class OrderLine
{
    private readonly int quantity;
    private readonly int unitPrice;
    public OrderLine(int quantity, int unitPrice)
    {
        this.quantity = quantity;
        this.unitPrice = unitPrice;
    }

    public int Subtotal()
    {
        return quantity * unitPrice;
    }

    public bool Qualifies()
    {
        return Subtotal() >= 100;
    }
}

Subtotal owns the formula. Qualifies asks for its result. Five items at 20 coins still qualify, while four do not.

class OrderLine:
    def __init__(self, quantity, unit_price):
        self._quantity = quantity
        self._unit_price = unit_price

    def subtotal(self):
        return self._quantity * self._unit_price

    def qualifies(self):
        return self.subtotal() >= 100

subtotal owns the formula, and qualifies uses its result. The promotion threshold has not changed.

A query is not a cached value

Calling the new method calculates the subtotal each time. The old temporary stored one result for the remainder of that invocation. Those are equivalent here because the inputs do not change during the calculation and multiplication is inexpensive.

They need not be equivalent for a clock reading, a database lookup, an expensive traversal, or mutable inputs. Preserve a deliberate snapshot when later steps must use the same value. Do not turn one external request into repeated requests merely to remove a local variable.

The method is public here to demonstrate reuse; keep it private when only the class needs it. Extracting a query is valuable when the named calculation clarifies several operations, not because local variables are inherently undesirable.

Sources

  1. Martin Fowler — Replace Temp with Query.