Navigation

Искусство программирования под Unix (и не только). Часть пятая, «правило простоты»

Я продолжаю цикл статей, посвященных некоторым простым правилам разработки под Unix «по версии Эрика Реймонда», которые, по моему глубочайшему убеждению, могут быть распространены на любые другие операционные системы. Я уже рассказывал в первых трех частях о правилах модульности, ясности, композиции и разделения. Сегодня дело дошло до пятого правила —

Правило пятое: добавляйте сложность лишь там, где она действительно необходима (Design for simplicity; add complexity only where you must.)

Проектируя различные информационные системы, я часто говорю себе «стоп: выходит сложнее, чем должно быть» и возвращаюсь к началу, чтобы понять, что пошло не так. Сложность системы плоха не столько стоимостью поддержки, сколько стоимостью развития. Ответ на вопрос, какие последствия повлечет изменение, для усложненной системы потребует значительного большего времени, чем требует бизнес. Шаг за шагом система умирает и среди программистов начинают все чаще и смелее высказываться мысли о полной переделке всего продукта.

О принципе KISS и «бритву Оккама» я писал ранее, в статье про принцип «ясность лучше заумности». Поэтому эту статью я представлю в виде дайджеста чужих мыслей на тему простоты и сложности.
Антуан де Сент Экзюпери сказал по этому поводу отличнейшую мысль, «Как видно, совершенство достигается не тогда, когда уже нечего прибавить, но когда уже ничего нельзя отнять». Вспомните времена, когда появился новый айфон: стеб на тему «что нет у айфона и есть у пенсионерского телефона моей бабушки» был лейтмотивом всех форумов. Потому что для того, чтобы было хорошо и во время, все это было лишним. Китайцы, как мы видим, думают ровно наоборот.

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

В языке Perl есть пара девизов, приписываемых Ларри Уоллу. Первый — «Есть больше одного способа сделать это» (There’s More Than One Way To Do It. На это даже сокращение имеется — TMTOWTDI). Второй — «Простые вещи должны быть простыми, а сложные — возможными» (Easy things should be easy and hard things should be possible). Ситуация, когда разработчик не может относительно быстро ответить на вопрос о реализуемости доработки и хотя бы ориентировочно прикинуть трудозатраты и необходимые изменения, должна настораживать. Значит, теперь не разработчик управляет системой, а она им…

Особенно следует стремиться к простоте в структурах данных. Эрик Реймонд в книге «Собор и базар» изрек очень правильную мысль: «Хорошие структуры данных и плохой код работают несколько лучше, чем хороший код и плохие данные». Переделывая систему «заново» основной сложностью очень часто являются именно данные и допущенные ошибки в проектировании. Буквально на прошлой неделе я собеседовал программиста, который в ответ на вопрос о правильном, на его взгляд, варианте хранения адресной информации, предложил хранить все в одном поле, разделяя каким-нибудь редким символом. У меня исчезли сразу все последующие вопросы.

Еще одно выражение на эту тему приписывается Людвигу Виттгейнштейну, «Хороший архитектор отличается от плохого тем, что плохой поддается искушению, а хороший — его избегает». Так и в программировании: если хочется что-то добавить, остановись, запиши на бумажку и продолжай работать как работал. Если проектируешь систему с нуля, оставляй только самое необходимое, а потом вдумчиво добавляй небольшие «излишества» (их же без кавычек добавлять не надо).

Очень много усложнений происходит на уровне разработки спецификации продукта, когда заказчик наконец понимает, что он хотел в самом начале (второй раз он это понимает, когда увидит первый прототип, а третий — когда все уже внедрено). Усложнить спецификацию очень просто — к этому располагает буквально все. Работать же по ней будет очень непросто. Поэтому стоит руководствоваться правилом: цена любого изменения включает не только это изменение, но анализ влияния и цену закладки на высоковероятные расширения (в их числе и снятие этого изменения при необходимости). Понятно, что с ростом количества требований возрастает цена таких изменений, как в проектной документации, так и в продукте. Поэтому я при первой возможности все неключевые требования, поступающие дополнительно, рекомендую относить на следующий этап, чтобы как можно быстрее начать первый, чтобы как можно скорее получить прототип и первый релиз. Пусть простой, пусть недостаточно функциональный, но готовый для испытаний на производительность, юзабилити, надежность.

Завершу сегодняшнюю статью известным выражением Оскара Уальда, подтверждение которого я встречаю буквально на каждом шагу: «В жизни нет ничего сложного. Это мы сложны. Жизнь — простая штука, и в ней что проще, тем правильнее».