Пирамида судьбы
В программировании проблема под названием пирамида судьбы — это довольно распространённый случай, который возникает при структурировании программы путём вложения друг в друга множества однотипных конструкций для обеспечения корректности вычислений. Возникает довольно часто при проверке нулевых указателей или при обработке обратных вызовов.[1] Два примера, имеющих отношение к данному термину, связанные с определённым стилем программирования в JavaScript[2], а также вложенные друг в друга операторы if в ООП языках когда один из объектов может иметь нулевой указатель.[3][4]
ПримерыПравить
Современные объектно-ориентированные языки программирования предлагают стиль кодирования, известный как точечное обозначение, позволяющий вызывать несколько методов подряд в одной строке кода, путем отделения каждого вызова точкой. Например:
theWidth = windows("Main").views(5).size().width();
Данный код содержит четыре отдельные команды. Сначала в коллекции окон находится окно с именем «Main», затем среди изображений внутри данного окна выбирается изображение номер 5, далее вызывается метод size
, возвращающий структуру содержащую размеры данного изображения, и в заключение вызывается метод width
для данной структуры, производящий результат, который помещается в переменную theWidth
.
Проблема здесь состоит в том, что код отталкивается от факта существования каждого из перечисленных значений. Несмотря на то, что вполне резонно ожидать наличия размеров у каждого изображения, а также ширины у каждого размера, мы никогда не можем гарантировать ни существование окна с именем «Main», ни того что у него будет пять изображений. Если одно из вышеперечисленных обстоятельств не будет иметь места, один из методов будет применён к нулевому указателю, что приведёт к ошибке.
Чтобы избежать ошибки, программист вынужден проверять существование объекта перед каждым следующим вызовом. Безопасная версия кода может выглядеть так:
if windows.contains("Main") {
if windows("Main").views.contains(5) {
theWidth = windows("Main").views(5).size().width();
//далее код, использующий theWidth
}
}
Если программист желает использовать это значение различным образом, в зависимости от того существует ли оно или нет, то в таком случае весь полезный код внутри конструкции if
будет существенно смещён вправо, что приводит к трудностям при чтении кода. Это вынуждает применять «плоские» конструкции, например:
if windows.contains("Main") { theWindow = windows("Main") }
if theWindow != null && theWindow.views.contains(5) { theView = theWindow.views(5) }
if theView != null {
theWidth = theView.size().width();
//дальнейший код
}
или:
if !windows.contains("Main") {
// обработчик ошибки
} else if !windows("Main").views.contains(5) {
// обработчик ошибки
} else {
theWidth = windows("Main").views(5).size().width();
//далее код, использующий theWidth
}
Конструкции подобного рода весьма распространены и некоторые языки программирования в настоящее время предлагают некоторое подобие синтаксического сахара для борьбы с данным явлением. Например, в Apple Swift реализована концепция оператора безопасной навигации в операции if[5]. В тоже время в Microsoft C# 6.0 и Visual Basic 14 добавлены элвис-операторы ?.
и ?[
для доступа к членам класса и индексирования, соответственно.[6][7][8] Основная идея — позволить цепочке вызовов методов возвратить null немедленно, как только встретится отсутствующий объект, например код:
theWidth = windows("Main")?.views(5)?.size.width;
должен присвоить null переменной theWidth
если либо «Main», либо пятое изображение отсутствуют, либо завершить вычисление и вернуть ширину в том случае если они оба существуют. Во многих ситуациях программист должен выполнять различные действия в двух вышеперечисленных случаях, поэтому Swift предлагает дополнительный синтаксический сахар для данных обстоятельств: выражение if let
, известное также под именем «необязательная привязка»:
if let theView = windows("Main")?.views(5) {
//код если view существует...
theWidth = theView.size.width
}
СсылкиПравить
- ↑ Dave Herman. Why coroutines won't work on the web (неопр.). The Little Calculist (14 декабря 2011). Архивировано 6 марта 2016 года.
- ↑ The Pyramid of Doom: A javaScript Style Trap (неопр.) (27 ноября 2012). Архивировано 9 декабря 2015 года.
- ↑ Eberhardt, Colin Tearing Down Swift's Optional Pyramid Of Doom (неопр.) (8 декабря 2014). Архивировано 31 июля 2016 года.
- ↑ New Language Features in Visual Basic 14 (неопр.) (9 декабря 2014). Архивировано 25 декабря 2014 года.
- ↑ Optional Chaining (неопр.). Apple. Дата обращения: 6 ноября 2021. Архивировано 25 марта 2016 года.
- ↑ Null-conditional Operators (C# and Visual Basic) (неопр.). Microsoft. Дата обращения: 6 ноября 2021. Архивировано 23 июня 2016 года.
- ↑ What's New for Visual C# (неопр.). Microsoft. Дата обращения: 6 ноября 2021. Архивировано 3 апреля 2017 года.
- ↑ What's New for Visual Basic (неопр.). Microsoft. Дата обращения: 6 ноября 2021. Архивировано 17 ноября 2016 года.
На эту статью не ссылаются другие статьи Википедии. |