Рефакторинг метода с опциональными параметрами
class PageRepository
{
...
public function find($pageId, $prerender = false)
{
...
if ($prerender === true) {
$page->prerender();
}
...
return $page;
}
public function findOrFail($pageId, $prerender = true)
{
$page = $this->find($pageId, $prerender);
if ($page === null) {
throw new Exception("Page $pageId not found.");
}
return $page;
}
...
}
Метод PageRepository::find
имел опциональный параметр $prerender
, с значением по умолчанию false
. Проблема в том, что метод PageRepository::findOrFail
имеет тот же необязательный параметр, но его значение по умолчанию равно true
!
Если вы невнимательно читаете сигнатуры методов и значения параметров по умолчанию, вы можете легко ошибиться и выполнить пререндер страницы (а это дорогостоящая операция), не желая этого или не нуждаясь в этом.
Методы с опциональными параметрами-флагами могут быть потенциально опасны, и их трудно разглядеть.
Есть несколько вещей, которые можно сделать, чтобы они стали лучше и читабельнее.
1. Изменение значений по умолчанию опциональных параметров на одинаковые
Здесь всё просто. Просто измените опциональное значение по умолчанию $prerender
в PageRepository::findOrFail
на false
(или наоборот).
2. Укажите опциональное значение параметра
Просто укажите значение в явном виде, чтобы любой, кто будет читать ваш код (даже через пару месяцев), знал, что оно было задано и использовано намеренно.
$pageRepository = new PageRepository();
$page = $pageRepository->find($pageId, false);
А ещё лучше — использовать переменную с семантическим значением при вызове метода.
$pageRepository = new PageRepository();
$page = $pageRepository->find($pageId, $prerender = false);
Знаю, что линтеры или IDE могут выделять параметр $prerender, но есть несколько способов справиться с ним, и оставляю на ваше усмотрение выбор способа, как с ним справиться.
3. Рефакторинг метода с опциональным параметром flag на два отдельных метода
Удалите вызов $page->prerender()
из метода PageRepository::find
и перенесите его в отдельный метод PageRepository::findAndPrerender
.
class PageRepository
{
...
public function find($pageId, $prerender = false)
{
...
if ($prerender === true) {
$page->prerender();
}
...
return $page;
}
public function findAndPrerender($pageId)
{
$page = $this->find($pageId, true);
if ($page === null) {
throw new Exception("Page $pageId not found.");
}
return $page;
}
...
}
Таким образом, придётся осознанно выбирать, какая функциональность (или, скорее, какой побочный эффект) нужна.
Это был просто краткий совет по рефакторингу, который я обычно настойчиво предлагаю при проведении ревью кода, чтобы сделать код понятным и избежать путаницы.