Replace Parameter with Explicit Methods
Before you begin: Methods, string parameters, and state changes.
Replace Parameter with Explicit Methods replaces a parameter that chooses an operation with separate method names. The call itself then says what will happen. It is a form of Remove Flag Argument, even when the flag is a string rather than a Boolean. 1
Original version: a string chooses which setting changes
public sealed class Settings
{
public int Volume { get; private set; }
public int Brightness { get; private set; }
public void Set(string setting, int value)
{
if (setting == "volume") Volume = value;
else if (setting == "brightness") Brightness = value;
else throw new ArgumentException("Unknown setting.");
}
}class Settings:
def __init__(self):
self.volume = 0
self.brightness = 0
def set(self, setting, value):
if setting == "volume":
self.volume = value
elif setting == "brightness":
self.brightness = value
else:
raise ValueError("Unknown setting.")A typo in the string becomes a runtime error. A caller that knows it is adjusting volume still has to express that operation through a generic dispatcher.
Refactored version: name the operation directly
public sealed class Settings
{
public int Volume { get; private set; }
public int Brightness { get; private set; }
public void SetVolume(int value) { Volume = value; }
public void SetBrightness(int value) { Brightness = value; }
}settings.SetVolume(30) makes the target explicit and discoverable as a method. The implementation no longer checks a string to decide which field to write.
class Settings:
def __init__(self):
self.volume = 0
self.brightness = 0
def set_volume(self, value):
self.volume = value
def set_brightness(self, value):
self.brightness = valuesettings.set_volume(30) states the operation directly. The public attributes remain mutable as in the original; this example changes operation selection, not Python access enforcement.
Keep dynamic selection at the boundary that needs it
A configuration file may genuinely contain setting names. Its parser can still translate those names into explicit operations and reject unknown names. The point is to avoid making every ordinary caller speak the parser’s generic protocol.
If a user interface treats hundreds of settings uniformly, a data-driven API may be more appropriate than hundreds of methods. Use explicit methods when the operations deserve distinct names and contracts.
No range validation is added here; valid numeric ranges are a separate concern. Preserving the old valid assignments while migrating callers is the refactoring. Changing allowed values or error reporting should be reviewed separately.
Sources
- Martin Fowler — Remove Flag Argument, including Replace Parameter with Explicit Methods.