Замена параметра набором специализированных методов
Также известен как: 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)
.
Когда нельзя применить
- Не стоит применять замену параметра явными методами, если метод редко меняется, а новые вариации внутри него не добавляются.
Порядок рефакторинга
-
Для каждого варианта исполнения метода создайте свой метод. Запускайте эти методы в зависимости от значения параметра в основном методе.
-
Найдите все места, где вызывается оригинальный метод. Подставьте туда вызов одного из новых методов в зависимости от передающегося параметра.
-
Когда не останется ни одного вызова оригинального метода, его можно будет удалить.