Если метод, например, имеет такую сигнатуру:
QuestData GetQuestData(string questId)
Вы, когда его вызываете совершенно не рассчитываете получить
null. Но бывает, что метод при этом может вам его вернуть не показав ошибки или не упав. Не зная этого вы растиражируете это значение по коду и упадете неизвестно где. И от этой рандомной точки нужно будет вернуться к этому методу в обратном направлении затратив время на поиск ошибки. Это потеря времени просто, чтобы узнать, что например, ошибка в данных и такого questId не существует.Плохая реализация выглядит так:
QuestData GetQuestData(string questId)
{
if (_quests.TryGetValue(questId, out QuestData data))
return data;
return null;
}
Если у вас один такой метод или малый проект, то это особо может и не страшно (но точно неудобно). Те кто не обращают на такие мелочи внимание, далее как правило накручивают еще больше подобных методов и неустойчивость кода растет очень быстро.
Это плохо в первую очередь потому, что ошибка происходит, но делает это втихую — не сообщая ничего. Во-вторых заставляет вызывающий код делать проверки вида
if (questData != null) везде где этот метод вызывается, а это повсеместный мусор. И, конечно, замедляет разработку.Реализация чуть лучше:
QuestData GetQuestData(string questId)
{
if (_quests.TryGetValue(questId, out QuestData data))
return data;
throw new Exception("Quest id '{questId}' not found.")
}
Тут мы уже узнаем, что у нас ошибка в данных. Внешние проверки результата уже не нужны — это хорошо. Но это все еще плохо потому, что в реальности ошибка скорее всего должна быть известна, но не ломать игру.
Хорошая реализация:
bool TryGetQuestData(string questId, out QuestData data)
{
return _quests.TryGetValue(questId, out data);
}
Почему хорошо:
- Понятность, вам не придется ловить null непонятно где. Внешний код уже по сигнатуре метода знает, что данных может не быть, значит обработает это корректно (например, отправит ошибку в аналитику, выведет лог и не будет ломаться на попытке запустить этот квест в игре).
- Вы не тратите время и мысленно не "спотыкаетесь" когда пишите код, при работе с подобными методами. Это дает скорость в работе. Вам не надо заходить в методы и проверять их реализацию. Такая фобия может развиться, стоит вам найти 3-4 метода в проекте, которые почему-то неявно возвращают
null.- Например, у вас из 1000 есть целых 10 не валидных
questId, которые вы передаете в метод. В варианте с возвращением null или throw new Exception — вам надо будет 10 раз запустить игру, чтобы их найти. В варианте, где вы очевидно обрабатываете отсутствие данных и, например, выводите лог, то вы узнаете все 10 неверных questId за один запуск. Это снова экономия времени.- Делает код чище и проще. Меньше лишних проверок, меньше строк и снова буст к простоте проекта и скорости разработки.
#техничка@cat_and_code
Поддержите автора лайком или отправьте пост другу
Предложить тему для поста