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

Прошла ужасная неделя! После того, как я освободился от работы с WPF, мне пришлось сконцентрироваться на исправлении мерзких багов и добавлении требуемых фич в «только что законченный» проект, который мы писали с шестью другими разработчиками. Я чувствовал себя виноватым, так как всё, что я мог сделать на прошлой неделе, ограничивалось добавлением новых строк кода и условий if в этот код, который мои коллеги и так разукрасили миллионами if’ов. Иногда я успеваю сделать многострочный нарост кода до компактного, порою в одну строку. Это спасает мой день. На прошлой неделе таких дней не было.

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

Мир был бы лучше без условий if — знакомо это чувство? Когда ты пишешь очередной if, твой код становится зависимым от случая. Иногда ты даже не уверен, какая именно ветка кода будет на самом деле выполнена. Если посмотреть с другой стороны, алгоритм без условий — необходимый, обязательный, он выполняется только так, как ты запрограммировал. Самый ущербный if — тот if, который ты пишешь «на всякий случай», когда не можешь представить ситуацию, которая будет при выполнении кода.

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

А давай посмотрим на пример? Это реальный код, который я нашел в одном проекте несколько лет назад. Основываясь на данном значении суммы, он считает контрольную цифру Финского банка (Finnish bank reference number):

Не зная о существовании данной процедуры, я набросал свою версию:

Чувак, никаких условий! Если быть точным, одно условие не делает здесь большого различия, и первая строчка кода показывает, что автор CheckDigit_a не осмыслил весь смысл до этого расчета. В конце кода отнюдь не судьба определяет значение суммы, равное 10, а может и нет. Это вполне может быть посчитано и, какое бы ни было значение, оно всегда не условно. То есть, однажды передав функции значение, мы имеем конкретный результат, вытекающий из неё. Тут нет места сомнениям, никаких условий!

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

В связи с тем, что мы никак не можем жить без условий if, я хочу предложить следующую вещь. Чтобы общее количество операторов if оставалось наименьшим, программисты должны платить штраф за каждый написанный ими if. Если хочешь не уйти в минус и получить хоть что-то после рабочего дня, помни следующее:

  • используй арифметику, функции для работы со строками, символами и т.п. везде, где это возможно!
  • пытайся уменьшить количество вложенных if, анализируя свои условия. Когда ситуация становится сложна для понимания, используй карандаш, клочок бумаги и таблицы истинности. Этот метод может помочь объединить несколько операторов if в один и, что вполне возможно, найти ветку, которая никогда не выполнится;
  • используй оператор ?: при простых условиях. Логически он эквивалентен if, но очень компактен. Так легче представлять конструкцию как один логический блок, в то время как if делает конструкцию размытой;
  • используй оператор switch вместо if .. else if, где это возможно;
  • не вздумай использовать if как заплатку! Бывает, что кажется простым решением добавить всего один маленький if, но, анализируя код глубже, можно найти действительно верное решение проблемы.

Если в проекте наблюдается постоянно растущее количество операторов if, там наверняка закрадётся ошибка в самом начале. Использование switch может быть забыто, или не учтены все возможные ситуации. Или дизайн может оказаться слишком сложным, так и не достигнув цели: ты хотел крошечный файл, а получился швейцарский нож.

«Хороший план — половина работы» (“Well planned is half done”) — гласит известное высказывание, которое можно интерпретировать как «Плохо спланированное требует всё больше условий if«. Когда твой код раздувается от количества условий, всё еще возможно сохранить большую часть работы, меняя структуру приложения. На практике такое вряд ли возможно, кто-то признает недочёт в начальном дизайне, поэтому всё, что останется делать, это учиться на своих ошибках. Пытаться избавиться от этого проекта, быть мудрее при работе над следующим, если такой предвидится.

(c) Heikki Valkonen (aka Hex), http://www.sysgen.fi
(c) crystalbit, http://parsers.info — перевод с английского (translation)

Вот я и перевёл статью горячего финского парня :) Хотя сам в Финляндии никогда не был, да и за границей тоже. Один раз отдыхал в Крыму — разве это настоящий туризм? Вот туры в Египет, туры в Мармарис (Турция) — это да :)