Pull to refresh

Программировать сложно или о вреде догматического мышления

Reading time5 min
Views1.4K
У каждого явления существует «плохая» и «хорошая» сторона. При этом абсолютного зла не существует. Также как и абсолютного добра.

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

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

Начнем с того, что программирование — это плохо. Почему?



Потому что оно сложное. Что лучше? Конструирование.

Ошибки конструирования видны сразу. Ошибки программирования незаметны.

Программирование — трудоемкий процесс, требующий массы знаний и умений. Конструирование требует низкой квалификации.

Представьте, что 25 лет назад вам поставили задачу — запрограммировать «динамическую страницу с картинками и текстом», которая высвечивает ссылки, при нажатии на них высвечивает другую «динамическую страницу» и так далее.

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

А сейчас? А сейчас любой ботаник за день сконструирует такую страницу из HTML и CSS. Причем ошибки при конструировании такой страницы, как правило, видны сразу и легко исправляются.

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

Сложность присуща программированию по его природе. Она неизбежна. Это «темная сторона» программирования.

Но есть и «светлая сторона». Программирование дает и неоспоримо хорошее — программы, поведение которых позволяет решать разнообразные задачи, операционные системы, драйвера и пр.

Догматический взгляд на программирование (как процесс в целом) часто сводится к отрицанию его сложности.

Но этот взгляд не всегда высказывается явно. Например, некоторые апологеты, евангелисты и другие пациенты любят утверждать, что программирование «пока еще является сложным». Но вот с появлением «вот этой вот штуки все изменится».

Давайте рассмотрим далее догму о том, что…

«автоматическое управление памятью (java) лучше (проще) ручного (C++) и, вообще, Java (C#) лучше C++»

Ручное выделение и освобождение памяти — это сложность.

Однако, есть определенные техники, которые позволяют управлять этой сложностью, то есть держать под контролем.

Например. Любой ресурс (который нуждается в явном освобождении) всегда принадлежит какому-то объекту. Он выделяется при создании объекта и возвращается системе при уничтожении объекта. Любой объект всегда принадлежит другому объекту. На самом верху этой иерархии находится главный владелец всех объектов — приложение.

Если требуется разделить владение объектом, вводим владельцев со счетчиком. Последний владелец (который установил счетчик в ноль) освобождает объект. Владение объектом можно явно передать.

Зачем пишу это здесь? Чтобы стал понятен уровень сложности.

Из своей практики могу сказать, что эти приемы решают 99% проблем ручного управления памятью. Никаких больше настроек или хитростей не требуется; только внимательность.

И вот приходит автоматическое управление памятью. И «упрощает» эту сложность.

Ушла ли сложность? Нет, конечно. Она трансформировалась.

Появился сборщик мусора. Это отдельная задача, которая требует ресурсов в непредсказуемые моменты времени (приостанавливая ваше приложение). Его требуется настраивать, то есть сборщик привносит свою (дополнительную) сложность.

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

Самое интересно — нехватка памяти. Оказывается, в java она теперь стала _разной_. Если в C++ нехватка памяти означала нехватку памяти, то в Java нехватка памяти означает… Да непонятно что! Еще одна сложность.

Уф. Ну, хорошо, меня загрузили по уши новой сложностью. Но взамен? Взамен-то я избавлен, наконец, от утечек памяти, если у меня есть автоматическая сборка мусора?

НЕТ.

В чем тут был догматизм? И почему так вышло? Попробую объяснить.

Сложность требует высокой квалификации.

Программирование — как сложный процесс — требует высокой квалификации. Это дорого.

Взрывной рост IT привел к взрывному повышению спроса на разработчиков.

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

Java — это и есть одна из таких попыток. Java задумывалась как средство разработки для программиста невысокой квалификации (да простят меня сейчас Java-гуру :-) ).

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

Но можно ли однозначно утверждать, что автоматическое управление памятью _лучше_ ручного?

Оставляю этот вопрос на ваше усмотрение.

А можно ли однозначно сказать, что Java проще C++?

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

Эта задача в C++ _не является задачей_. Вообще. Почему я так уверен? Потому что Гугл!

Гугл не может найти топика «C++ fastest replacing non-printable characters». Такой темы не существует.

А в Java — это задача. Требуется поиск решения. Требуется копание внутренностей Java.

Постойте, как же так?! Ведь Java это же «слошное хорошее»?! Это же стандартная библиотека, абстракция за абстракцией, ООП везде и нужно печтать очень много букф знакомый синтаксис!

Байты спрятались за классами. Это хорошо. И это плохо.

Еще догма.

«XML отлично подходит для хранения настроек»

Хранение персистентных (переживающих жизнь самого приложения) настроек — это сложность. Решает ли эту сложность XML?

Не читайте дальше, подумайте.

XML действительно удобен из-за своей иерархической структуры. Он позволяет быстро получать доступ к нужной ветке (когда он уже загружен в память). Он легко расширяется. Он хранится в текстовом файле, который может быть отредактирован вручную человеком.

Итак, у нас есть 100 мегабайтный XML-файл с настройками. Я хочу поменять в настройках один флаг с «0» на «1», то есть фактически один байт. Сколько байт мне придется записать на диск, чтобы отразить эту замену?

100 (сто) мегабайт.

Да, XML неплох для хранения read-only настроек. Но сложность, связанная с персистентностью, никуда не ушла. Она «прикрылась» небольшим размером XML-файлов.

Чтобы получить доступ к малюсенькой настройке требуется прочесть целиком весь XML-файл. Чтобы сохранить малюсенькое изменение — надо записать целиком файл.

Почему так вышло?

Давайте вычленим самое главное «хорошее» XML.

Это «человеко-читаемый» текстовый формат.

Бывает хорошее без плохого? Не бывает!

«Хорошее» всегда идет под руку с «плохим» — текстовый формат убог при больших объемах данных. Его невозможно обновлять по частям. Его нужно полностью загрузить в память, чтобы прочесть минимальный фрагмент данных.

Опять мы убеждаемся — плохое (т.е. сложность) никуда не ушла.

Хотим настоящую персистентность — RDBMS нам в помощь. Она контролирует эту сложность, отнимая у нас иерархию, человеко-читаемый формат и прямой доступ к настройкам (только через язык запросов — SQL).

И так далее.

Так можно ли сделать программирование простым? Существует ли «серебряная пуля», которая позволит школьникам создавать за пару дней свои операционные системы?

Нет, программирование было и осталось сложным.

Появилось много технологий, которые держат под контролем разные аспекты этой сложности.

Но сказать, что программирование стало простым — нельзя.

Поиск пути разумного контролирования сложности — это хорошо. Поиск пути без сложности — потеря времени.

PS Примеры в этой статье намеренно упрощены. Это сделано, чтобы статья не превратилась в многотомный труд. Разумеется, любая из затронутых тем является более глубокой и многосторонней.
Tags:
Hubs:
0
Comments0

Articles