Introduce Parameter Object
Before you begin: Functions, parameters, classes, and collections.
Introduce Parameter Object groups parameters that repeatedly travel together into an object representing their shared meaning. The objective is not merely to reduce the number of commas. It is to make a real concept explicit. 1
Original version: every operation receives two endpoints
A readings tool counts and totals values inside an inclusive interval.
public static class Readings
{
public static int CountWithin(int[] values, int low, int high)
{
return values.Count(value => value >= low && value <= high);
}
public static int SumWithin(int[] values, int low, int high)
{
return values.Where(value => value >= low && value <= high).Sum();
}
}def count_within(values, low, high):
return sum(1 for value in values if low <= value <= high)
def sum_within(values, low, high):
return sum(value for value in values if low <= value <= high)low and high represent one interval, but every call must supply the pair correctly. The same inclusive-boundary rule is repeated in both operations.
Refactored version: pass an interval with a contains operation
public sealed class Range
{
private readonly int low;
private readonly int high;
public Range(int low, int high) { this.low = low; this.high = high; }
public bool Contains(int value) { return value >= low && value <= high; }
}
public static class Readings
{
public static int CountWithin(int[] values, Range range)
{
return values.Count(range.Contains);
}
public static int SumWithin(int[] values, Range range)
{
return values.Where(range.Contains).Sum();
}
}new Range(3, 5) packages the endpoints, and Contains owns their inclusive interpretation. Both operations can reuse that same range.
class Interval:
def __init__(self, low, high):
self._low = low
self._high = high
def contains(self, value):
return self._low <= value <= self._high
def count_within(values, interval):
return sum(1 for value in values if interval.contains(value))
def sum_within(values, interval):
return sum(value for value in values if interval.contains(value))The interval groups both data and its relevant rule. It is more than a bag created to hide a long signature.
Preserve the boundary convention
For values 1, 3, 5, and 8, the interval from 3 through 5 contains two values totaling eight. Both endpoints remain included. Changing to an exclusive upper bound while introducing the object would be a separate semantic change.
The constructors deliberately do not add a low-before-high check: a reversed range matches nothing, as the original comparisons did. Add validation separately when the domain should reject such inputs.
Do not group unrelated parameters into a generic Options object solely to shorten a declaration. The group should have a name that explains why its members belong together. Preserve Whole Object is the neighboring move when that meaningful object already exists.