пятница, 27 февраля 2015 г.

[prog.thoughts] О сложности

К написанию этого текста подтолкнул интересный одноименный пост в блоге ув.тов.Сергея Теплякова (к прочтению рекомендую). Боюсь, что своей точкой зрения я буду противоречить не только Сергею, но и Фредерику Бруксу. Однако упрямства в своих заблуждениях мне не занимать, так то поехали :)

Мне думается, что программист сталкивается с тремя видами сложности:

  • естественная сложность (о ней говорится в упомянутом выше посте). Это сложность задачи, которую предстоит решить. Ну, например, реализовать соответствующий стандарту компилятор языка C++. Эта сложность измеряется тем, сколько времени и усилий потребуется разработчику, чтобы начать разбираться не только в задаче, но и в предметной области. Грубо говоря, для хорошего решения мало знать сам стандарт языка, нужно еще понимать что-то в теории компиляторостроения. И чем больше понимать, тем лучше;
  • сложность восприятия. Это усилия, которые нужно приложить для того, чтобы составить в своей голове адекватную картинку, максимально точно соответствующую задаче. А так же количество "промахов", т.е. ситуаций, когда мы воспринимали что-то одним образом, а на самом деле все оказалось совсем иначе. Ну очень грубо говоря, разработчик может прибывать в уверенности, что кнопка "Сделать все зашибись" должна быть красная, круглая и в центре. Тогда как заказчик уверен, что она должна быть квадратной, бледно зеленой и в правом нижнем углу. Причем выяснится все это, как обычно, в самом конце проекта, на демонстрации перед самым-самым высоким руководством заказчика;
  • сложность выражения. Это усилия, которые нужно приложить для того, чтобы описать сложившуюся в голове разработчика картинку посредством программного кода. Сюда же, например, идет разрыв между уровнем инструмента и уровнем задачи. Совсем грубо: если вам нужно отсортировать массив целых чисел произвольной размерности в Ruby -- это одно, а если на ассемблере x86 -- совсем другое. Ну и, наверное, эта сложность очень подходит под определение случайной сложности, о которой говорят Сергей Тепляков и Фред Брукс.

Но фокус, собственно, не в том, что сложностей три, а не две (фиг знает, сколько их на самом деле). Фокус в том, что они очень тесно завязаны между собой и на них оказывает непосредственное влияние личность разработчика (обратное воздействие так же присутствует). Так, если за разработку компилятора возьмется человек, который собаку съел на этом деле, то естественная сложность и сложность восприятия для него не будут представлять проблемы. Хотя человек может быть не самым выдающимся программистом и будет писать такой код, в который неприятно будет заглядывать, а отлаживать придется снова и снова, постоянно вылавливая один мелкий баг за другим. С другой стороны, на задачу может быть поставлен другой разработчик, который пишет лаконичный, понятный и надежный код, но который имеет слабое представление о разработке компилятора. Удельный вес каждой из сложностей станет совсем другим...

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

Вот такой вот итерационный круговорот сложностей в разработке :)

Комментариев нет: