Замена параметра набором специализированных методов
Также известен как: Replace Parameter with Explicit Methods
Проблема
Метод разбит на части, каждая из которых выполняется в зависимости от значения какого-то параметра.
Решение
Извлеките отдельные части метода в собственные методы и вызывайте их вместо оригинального метода.
До
void setValue(String name, int value) { if (name.equals("height")) { height = value; return; } if (name.equals("width")) { width = value; return; } Assert.shouldNeverReachHere(); } После
void setHeight(int arg) { height = arg; } void setWidth(int arg) { width = arg; } До
void SetValue(string name, int value) { if (name.Equals("height")) { height = value; return; } if (name.Equals("width")) { width = value; return; } Assert.Fail(); } После
void SetHeight(int arg) { height = arg; } void SetWidth(int arg) { width = arg; } До
function setValue($name, $value) { if ($name === "height") { $this->height = $value; return; } if ($name === "width") { $this->width = $value; return; } assert("Should never reach here"); } После
function setHeight($arg) { $this->height = $arg; } function setWidth($arg) { $this->width = $arg; } До
def output(self, name): if name == "banner" # Print the banner. # ... if name == "info" # Print the info. # ... После
def outputBanner(self): # Print the banner. # ... def outputInfo(self): # Print the info. # ... До
setValue(name: string, value: number): void { if (name.equals("height")) { height = value; return; } if (name.equals("width")) { width = value; return; } } После
setHeight(arg: number): void { height = arg; } setWidth(arg: number): number { width = arg; } Причины рефакторинга
Метод, содержащий варианты выполнения, разросся до грандиозных размеров. В каждой из таких цепочек выполняется нетривиальный код. При этом новые варианты добавляются очень редко.
Достоинства
- Улучшает читабельность кода. Куда очевидней, что делает метод
startEngine()чемsetValue("engineEnabled", true).
Когда нельзя применить
- Не стоит применять замену параметра явными методами, если метод редко меняется, а новые вариации внутри него не добавляются.
Порядок рефакторинга
-
Для каждого варианта исполнения метода создайте свой метод. Запускайте эти методы в зависимости от значения параметра в основном методе.
-
Найдите все места, где вызывается оригинальный метод. Подставьте туда вызов одного из новых методов в зависимости от передающегося параметра.
-
Когда не останется ни одного вызова оригинального метода, его можно будет удалить.