Рефакторинг метода с опциональными параметрами
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;
}
...
}Таким образом, придётся осознанно выбирать, какая функциональность (или, скорее, какой побочный эффект) нужна.
Это был просто краткий совет по рефакторингу, который я обычно настойчиво предлагаю при проведении ревью кода, чтобы сделать код понятным и избежать путаницы.