Pull to refresh
-3
0

Программист

Send message
От if == null вы уходите, только если ссылочный тип не может быть null

Совершенно верно. Заодно компилятор даст по рукам, тому кто попытается null туда запихнуть.


а если может — вы снова напишите шаблонную проверку.

Совершенно верно. Только после первой же успешной проверки у меня будет значение ссылочного типа, не допускающего null и его, в отличие от нынешних, не надо будет проверять по всей глубине стека вызовов. Заодно компилятор даст по рукам тому, кто рискнет пропустить обязательную проверку.


Итоги:


  1. Полностью исключены проверки с выбросом InvalidArgumentException
  2. А там где null — не ошибка, наличие проверки проконтролирует компилятор.
  3. NRE исключено по построению
  4. PROFIT

98 год?
Да, все то, про что я думал как о лучших альтернативах, еще не существовало, даже файберы надо руками писать.
Дикий капитализм — цена разработки системы меньше чем недельная прибыль от ее эксплуатации, офигеть.

Сколько сбоев за 10 лет на миллион строк кода?

У меня нет такой статистики, к сожалению — я уже давно не работаю в той компании. Да и 10 лет тому проекту нет и сейчас. Условия тоже иные — требования по надежности менее жесткие, а вот унаследованного технического долга был вагон и маленькая тележка. Тем не менее от исключений, которые сами по себе означали ошибку в коде, мы избавились.


Это маркетинговые сказки. Или некомпетентность. Невозможно отловить все ошибки

Речь ни в коем случае не идет об ликвидации всех ошибок! Я имею в виду только предотвращение тех из них, которые вызывают исключения, чей тип гарантированно означает ошибку в коде (не в окружении и не во входных данных).


Следующее по опасности — FPE.

Это исключение само по себе ошибку в коде не означает. Но в ваших условиях его цена понятна. Остальное из вашей четверки для меня всегда было уже некрологом.


Только забыли упомянуть, что он появился лишь в Delphi 5, и в VCL далеко не всегда используется.Так что получить NRE в деструкторе формы после исключения во время создания формы — не так сложно.

Коммерческий опыт у меня начался с Delphi 7. Для младших версий FreeAndNil несложно написать самому. От формы (а в идеале от GUI вообще) исправность системы ИМХО зависеть не должна.


PS: Большая статья о вашей системе станет украшением любого тематического сайта.

Ну в опытной эксплуатации на фоне промышленной все наоборот — надо "ломать и крушить", давая нагрузки и условия заведомо жестче боевых.

"Всего лишь механизм транзакций" — это уже из серии "90% любой крупной программы на C++ представляет собой медленную и глючную реализацию подмножества спецификации Common Lisp" (по памяти).
Если нужны качества, которые может дать только безопасный рантайм — логично использовать готовый и проверенный безопасный рантайм вместо велосипедов. А для некоторых тем вроде криптографии это вообще категорический императив.

Вы можете попробовать читать именно то что написано.


"Смысл в том, что по ссылке всегда объект" — исходя из Ваших же слов, именно тут и будет создан пустой объект.

Это не чьи-то слова — это ваши собственные идеи.


  1. Совсем не факт что будет использован паттерн null object — у него есть существенные ограничения.
  2. Когда null object все-таки применяется — нейтральный объект обычно создается статически и переиспользуется многократно.

Например, метод FindPerson вместо null (всеми почему-то ненавистного) вернет «пустой» объект, потому что null вернуть он не может.

  1. Вы статью вообще прочитали? Недостатки реализации null в C# расписаны еще до ката.
  2. С чего вы взяли что FindPerson должен использовать именно null object? Исключение при неудачном поиске бросить не судьба?
  3. Позволяющих null ссылок заведомо меньше, чем их общее число, а на практике от силы процентов 5. Кроме того, при наличии ссылок без поддержки null проверку для каждого случая появления null достаточно сделать лишь однажды.

Лично для меня в такой логике ничего полезного нет, проверки на null остались, плюс добавились абсолютно бесполезные «пустые» объекты.

Вы сами предложили такую логику, не надо приписывать ее кому-то еще.

Так в эрланге и изоляция настоящая, и источник реально доверенный, и отказоустойчивость неиллюзорная.

С диагностикой понятно — она всегда полезна. Анализ логов позволяет выделить часто встречающиеся проблемы и понять приоритет при исправлении. Да и сам поиск ошибок становится проще.

Логирование исключений в диагностических целях не требует перехвата и обработки именно NRE. Обычно делается хук на выброс исключения и логируется все подряд, за редким исключением. Для ошибок в коде разве что приоритет ставится FATAL.


Изоляция полезна всегда, когда у приложения много функций.

"Изоляция" при NRE — это попытка делать вид, что "все хорошо, прекрасная маркиза", при том, что о реальном состоянии системы вам известно только то, что воспроизвелась ошибка в коде.
Типовая реакция от VCL на этот случай годится только для тех приложений, ответственность за исправное функционирование которых невелика.
Опять-таки, это делается хуком c отловом всех необработанных исключений без специальной реакции конкретно на NRE.
Во всем остальном коде пытаться перехватить и обработать NRE значит стрелять себе же в ногу.


Я уточню, что речь идет об отлаженных приложениях. То есть NRE при выделении фразы — будет не на любой фразе, а на фразе со сложными знаками препинания, например с непарными кавычками. Тем самым мы сводим отказ от «программа вылетает» до «иногда не работает, но легко обходится». То есть понижаем важность исправления на 2 ступени.
Такая реакция — сладкая ложь для пользователя. Если ошибка и впрямь привязана к окружению и пользовательскому вводу, то перезапуск даст шанс их обойти, сохранив корректность работы. А вот продолжение работы с гарантированно поломанными инвариантами в надежде на "изоляцию" означает ненулевую вероятность действительно крупных неприятностей: от порчи важных данных и заведомо неудачных автоматических сделок на бирже до инъекции смертельной дозы обезболивающего.

Если вы не в курсе, самые опасные сбои в промышленной эксплуатации из-за ошибок в коде как раз редкие и плавающие. Частые и легко воспроизводимые чаще всего не доходят до боевой площадки, а если доходят, то легко исправляются.


У программ нет такого показателя как надежность. Есть корректность — отсутствие ошибок кодирования, есть отказоустойчивость — способность восстанавливаться после сбоев. Описанная вами методика при NRE дает иллюзию корректности с помощью иллюзии отказоустойчивости, по факту не обеспечивая ни того, ни другого.


В программе с высокой ценой сбоев, исключений, означающих ошибку в коде, не должно быть вообще. Для NRE этого добиться просто, для дедлоков — сложнее, но цель должна быть только такой. У меня был опыт доведения проекта, выдававшего по десятку страниц разных исключений вроде AV и т.п., до вылизанного состояния.

Аргумент "вместо ошибки периода выполнения непонятно где и когда получаем ошибку периода компиляции по месту дефекта" вы тоже не увидели?

Вы спрашивали, избавит ли в C# от проверок добавка фичи из котлина и каким образом.
Да, от части проверок избавит — ссылочные типы без null соответсвуют решению 12 из статьи и позволяют не проверять их значения на null по построению.
Смысл обсуждать котлин в теме про C# простой:


  1. Ссылочные типы без null всегда обсуждаются при разработке новых версий C#.
  2. Котлин свободен от NRE, кроме случаев взаимодействия с внешним не-котлин кодом.
  3. У JVM и Java проблема с null в точности та же что и в .NET и C#
  4. У C# в сравнении с котлином есть дополнительное обременение в виде совместимости с предыдущими версиями языка.

В котлине есть ссылочные типы, не допускающие null. Им проверки на null не нужны по построению.

Вы, возможно, спутали разные виды отказов. От NRE ваши способы 1-3 не помогают никак, 4-5 чуть лучше, но тоже ничего не гарантируют. Этим ошибки в коде кардинально отличается от сбоев в окружении, для обхода которых и придуманы ваши пять пунктов.

Самым обыкновенным — если тип не допускает null, то его значения проверять на null не нужно. Совсем как в котлине сделать не выйдет — обратная совместимость нужна.

Да, не ту часть проблемы я обозначил как пушного зверька

Как в С# симулировать поведение obj-c

Элементарно:


var a = obj1?.method1()?.method2()
а если смотреть шире (что и предлагает делать iqiaqqivik), то вполне себе можно

И создать себе геморрой еще и со значимыми типами.

Когда есть выбор между


  1. "писать код проще" и
  2. "задешево превратить целый класс ошибок периода выполнения в ошибки периода компиляции"

результат немного предсказуем.

Все (по крайней мере должны) проверяют входные параметры в функцию и выходные из функции.

Да, восемь строк проверки на три строки полезного кода смотрятся просто, чисто и элегантно.
Проверки выходных параметров и возвращаемых значений в коде не припоминаю за все время работы.
Посмотрите решение 11 — оно справится с проверками лучше программиста-человека.

А что будет при тесном взаимодействии с любым Java-фреймворком?

в «исторической альтернативе» все как-то, извините, «сдулось» в один маленький абзац.

А там и не требуется сильно больше: источником серьезной проблемы стала экономия буквально на спичках. Добавил примеры кода к альтернативе.


Сухие перечисления без примеров — бесполезны, никто не будет «заучивать» их наизусть, без понимания почему так.

В этом случае каждое решение грозит превратиться в отдельную статью, что повысит трудоемкость для меня и ухудшит усвояемость для читателей.
Я не стремился подробно осветить каждый нюанс каждого частного случая. Моей задачей было дать обзор типовых проверенных решений и высокоуровневые критерии для их выбора. Для тех, кто хочет узнать больше о конкретном варианте — в тексте есть ссылки.

Information

Rating
Does not participate
Location
Россия
Registered
Activity