Многие знает этот большой контраст, при переписывании чужого легаси, где либо мы читаем совершенно незнакомый нам код, как страницы простой и интересной книги, либо видим кучу объектов и функций с абсолютно абстрактными названиями, иногда состоящими из нескольких букв или аббревиатур, заставляющих проваливаться в каждую реализацию и держать ее в памяти, изучая дальнейший контекст фичи.
Если вы и так являетесь приверженцем более декларативного и информативного нейминга в вашем коде, то эта статья покажет прям небольшие мелочи из официальной доки dart, которые позволят выкрутить читаемость на максимум.
1. Ставьте самое описывающее результат существительное в конец
Последнее слово в имени должно наиболее точно описывать, чем является объект. Все остальные слова — это уточнения, прилагательные и модификаторы, которые подготавливают читателя к главному смыслу.
/// Хорошие примеры
pageCount // Количество (count) страниц.
ConversionSink // Sink для конвертаций.
ChunkedConversionSink // ConversionSink, который работает чанками.
CssFontFaceRule // Rule для font-face в CSS.
/// Плохие примеры
numPages // Выглядит как коллекция страниц, а не число.
CanvasRenderingContext2D // По названию это "2D", но по сути — Context.
RuleFontFaceCss // Непонятно, это Rule, FontFace или CSS?
2. Пишите так, чтобы код читался как предложение
Если вы сомневаетесь в имени — попробуйте прочитать его вслух как обычное предложение. Хороший нейминг по возможности должен читаться естественно, почти как разговорная фраза.
/// Хорошие примеры
// "Если ошибки пусты..."
if (errors.isEmpty) {
// ...
}
// "Подписка – отменить"
subscription.cancel();
// "Заказы, которые в процессе."
orders.where((pages) => page.inProccess);
/// Плохие примеры
// Не совсем понятно, мы проверяем или вызываем операцию?
if (errors.empty) {
// ...
}
// Не понятно переключить куда и с какого состояния
subscription.toggle();
// Не понятно, фильтр исключает или оставляет заказы, которые в процессе
orders.filter((pages) => page.inProccess);
В идеале, если имя будет не просто валидным, а будет встраиваться в фразу. Хороший пример — это когда его можно прочитать так: «Если ошибки пусты — показать сообщение», «Подписка отменяется», «Взять заказы, которые в процессе»
Более проблемный подход — когда приходится: додумывать смысл, запоминать поведение по документации, часто открывать реализацию для каких то простых операций, подписанных неочевидным неймингом.
3. Используйте «положительные» имена для булевых свойств
В dart мы часто применяем оператор булевой инверсии, на какие то свойства вроде:
/// Плохо
if(!Screen.isClosed) {
// Работает с открытым экраном
}
Инвертировать булевую переменную занимает меньше секунды и помогает нам не отвлекаться от реализации основной бизнес логики. Часто можно заметить, что одно if условие может пополниться двумя и тремя новыми условиями, которые так же могут писаться через оператор булевой инверсии.
Рекомендация же заключается в том, чтобы вы потратили немного больше времени, и создали второй необходимый геттер, если его нет. Добавьте свойство isOpen наряду с isClosed, если объект часто используемый, то это сильно упростит читаемость условий в будущем.
Старайтесь составлять условия из переменных, которые синтаксически отражают true значения
/// Хорошо
if(Screen.isOpen) {
// Работает с открытым заказом
}
4. Избегайте get префикса в функциях с возвращаемыми значениями
Вместо малоинформативного get мы всегда можем добавить контекст функции другим префиксом
/// Малоинформативно
getData()
getUser()
getFile()
/// Чуть более информативно
fetchUser()
downloadFile()
readFile()
requestUser()
calculateTotal()
aggregateStats()
5. Избегайте прилагательных форм для названия bool переменных
Уместно использовать формы глагола to be:
isEnabled
isEmpty
wasShown
willFire
Либо же вспомогательные глаголы, когда важно выразить возможность, необходимость или условие:
hasElements
canClose
shouldConsume
mustSave
Но не делайте так
// В контексте типа bool переменная понятна,
// но без знания типа можно принять его за действие например
bool empty;
// Тоже в целом не сильно страшно, но не так очевидно, как isVisible
bool visible;