На мій погляд, є різниця між поверненням NULL, поверненням порожнього результату (наприклад, порожній рядок або порожній список) і киданням винятку.
Я зазвичай дотримуюся наступного підходу. Я розглядаю виклик функції або методу f (v1, ..., vn) як додаток функції
f : S x T1 x ... x Tn -> T
де S it - "стан світу" T1, ..., Tn - типи вхідних параметрів, а T - тип повернення.
Я спершу спробую визначити цю функцію. Якщо функція є частковою (тобто є деякі вхідні значення, для яких вона не визначена), я повертаю NULL, щоб сигналізувати про це. Це тому, що я хочу, щоб обчислення нормально закінчувалося, і сказати мені, що запитувана мною функція не визначена на заданих входах. Використання, наприклад, порожнього рядка як зворотного значення неоднозначне, оскільки може бути, що функція визначена на входах, а порожня рядок - правильний результат.
Я думаю, що додаткова перевірка на покажчик NULL у викликовому коді необхідна, оскільки ви застосовуєте часткову функцію, і це завдання викликаного методу повідомити вам, чи функція, якщо вона не визначена для даного вводу.
Я вважаю за краще використовувати винятки для помилок, які не дозволяють здійснити обчислення (тобто знайти відповідь не вдалося).
Наприклад, припустимо, що у мене є клієнт класу, і я хочу реалізувати метод
Customer findCustomer(String customerCode)
шукати клієнта в базі даних програми за його кодом. У цьому методі я б
- Поверніть об’єкт класу Клієнт, якщо запит успішний,
- Поверніть нуль, якщо запит не знайде клієнта.
- Накиньте виняток, якщо неможливо підключитися до бази даних.
Додаткові перевірки на нуль, наприклад
Customer customer = findCustomer("...");
if (customer != null && customer.getOrders() > 0)
{
...
}
є частиною семантики того, що я роблю, і я б не просто "пропустив їх" для того, щоб зробити читання коду краще. Я не думаю, що це спрощена практика спростити семантику розглянутої проблеми просто для спрощення коду.
Звичайно, оскільки перевірка на null відбувається дуже часто, чи добре, якщо мова підтримує для неї якийсь спеціальний синтаксис.
Я також розглядав би можливість використання шаблону Null Object (як запропонував Laf), доки я можу відрізнити нульовий об'єкт класу від усіх інших об'єктів.