Как называть свои функции и методы

Опыт программирования для больших проектов на PHP и JavaScript подсказывает, что подбор названий функций и методов очень важен. Да, часто нехватка времени и/или лень и/или усталость приводят к таким названиям, как checkOtherThings() или handlingSomeArrayStuff() или даже cb(). Чем это плохо? Код работает, лень удовлетворена, заказчик/начальник довольны, о чем и говорить? Однако, все это чревато отложенными проблемами и часами, потраченными впустую. Если потом кто-то будет работать с вашим кодом, заниматься отладкой или расширением функционала, он вас точно не поблагодарит за doSomeStuff() и putArToOtherAr(). Этим «кем-то» всегда можете оказаться вы сами через месяц или год. Если сейчас вы чувствуете себя в своем коде, как рыба в воде, то через пару месяцев, вероятно, вы не вспомните даже, зачем вообще весь этот модуль был нужен.

Когда говорят про язык программирования, обычно делают акцент на втором слове. Но ведь, помимо всего прочего, это еще и «язык». Вот представьте, что вас спрашивают, как пройти до ближайшей поликлиники. И вы вместо «Это вам прямо до перекрестка, затем повернете направо, пройдете еще полкилометра, и она будет перед вами» скажете: «Ну это вы должны пройти 225 шагов до остановки, потом еще 15 от остановки, потом делаете 20 итераций по 2 шага, потом ваша зрительная кора, обрабатывая визуальный сигнал, задействует центр принятия решений, который определяет поворот, далее 2 раза по 45 градусов поворот через правую руку, и потом идите-идите-идите, прочитаете в инструкции, которую я вам дам, сколько конкретно шагов, и там поликлиника». Какое из объяснений будет понятнее? Часто встречается код, который написан наподобие второго варианта, будто программист специально хочет запутать своих коллег или себя самого в будущем.

У Мартина Фаулера есть чудесная статья о том, насколько маленьким может быть метод. Он убедительно показывает, насколько важно проводить грань между тем, что метод делает по сути (его «намерение») и его технической реализацией. Он цитирует программиста на Smalltalk, приводя в качестве примера программу, написанную в те времена, когда еще не было цветной графики. В программе была функция инверсии строки (чтобы вместо черным по белому она бы печаталась белым по черному). Возникла необходимость выделить строку в тексте. Можно было бы обойтись простым вызовом этой функции инверсии, но авторы приняли решение добавить новую функцию выделения строки, тело которой состояло лишь из вызова функции инверсии. Так что название новой функции было длиннее, чем ее тело. И это было очень правильное решение. Если в будущем понадобится выделять строки каким-то другим способом, тело функции легко можно будет поменять. А вот если бы для этого использовалась функция инверсии, пришлось бы вносить правки по всей кодовой базе. Да и при чтении кода вам гораздо проще понять, для чего осуществляется вызов конкретной функции, если название соответствует ее предназначению. В общем, не бойтесь создавать маленькие функции с длинными названиями — от этого все только выиграют. Мартин эмпирически установил для себя, что тело функции редко состоит больше, чем из 6 строк, без потерь для архитектуры приложения и понимания кода.

Я бы советовал писать код таким образом, чтобы он читался, как простой текст на английском языке. Имеет смысл подумать и о контексте, в котором будет использоваться функция. Например, у меня часто встает вопрос, как назвать функцию, которая возвращает булево значение. Например, вам надо написать функцию проверки на равенство двух величин. Что это будет: equal, equals, checkEquality, isEqualTo, areEqual, ifEqual, whetherAreEqual…? Я в этом случае задумываюсь о контексте, в котором она будет использоваться, чтобы код читался, как грамматически верная конструкция на английском (когда это возможно). Например,

$a = 1;
$b = 2;
if (equal ($a, $b)){
 // do something here
}

или

$a = 1;
$b = 2;
$c = areEqual($a,$b);
// do more stuff

или

class ExampleClass{
  public function isEqualTo (ExampleClass $object_to_compare_with)
  {
  // some code here
  }
}

$example_object1 = new ExampleClass();
$example_object2 = new ExampleClass();
if ($example_object1->isEqualTo ($example_object2)){
 // some code here
}

Понятно, что контекст может меняться и вообще быть каким угодно для одной и той же функции, но все же часто он достаточно однообразен, и попытка того стоит. Зато код потом читается очень легко. Труд человека, который будет в нем разбираться после вас, будет сильно облегчен.

1 комментарий

Добавить комментарий для Сергей Отменить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.