Пользователь
0,0
рейтинг
9 августа 2010 в 13:55

Разработка → Искусство программирования под Unix (и не только). Часть вторая, Ясность лучше заумности

Продолжаю цикл статей, связанных с правилами Эрика Реймонда из «Искусства программирования под Unix».

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

Сегодня речь пойдет о следующем правиле —

Правило ясности: Ясность лучше заумности (или ясность лучше, чем мастерство)
Rule of Clarity: Clarity is better than cleverness.

Наверное, вы не раз слышали о принципе и процессе проектирования, известного как KISS. Эта аббревиатура расшифровывается как «Keep it short and simple» («делай это просто») или «Keep it simple, stupid» (что-то типа «не усложняй, тупица!»). На практике, оно выражается в том, что если вам известно два решения задачи — простое и сложное, то стоит два раза подумать, прежде чем останавливать выбор на втором.

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

Маленькое отступление в сторону: Здесь очень распространена ситуация, что, возможно, вы додумали себе требования, которых не было в исходной задаче. Они действительно могут быть не лишними, но их ни в коем случае нельзя прятать в себе. Если у задачи заказчик внешний, то очень правильно эти требования фиксировать и утверждать, показывая альтернативы, риски, преимущства и недостатки.

Стоит вспомнить известные выражения Альберта Эйнштейна, относящиеся к этому правилу: «Всё следует упрощать до тех пор, пока это возможно, но не более того» и «Вы не можете утверждать, что понимаете что-либо, до тех пор, пока вы не сможете объяснить это своей бабушке». Не уверен, что логику системы подбора аксессуаров или обработки прайс-листов я смогу объяснить бабушке. Но объяснить кратко и емко человеку от бизнеса — должен. Если это не удается, вы придумали слишком сложную систему. Упрощайте, иначе она — не жилец…

Есть близкое к теме философское понятие, «бритва Оккама». Суть его в том, что если существует несколько определений или объяснений какого-то явления, то следует считать правильным самое простое из них. Но чаще «Бритву Оккама» вспоминают в другом контексте, «Не умножай сущности без надобности» (что не совсем верно по отношению к философу, но правильно само по себе). Это правило пригождается практически на каждом шагу в программировании.



Итак, резюмирую:
  • Давайте ход в первую очередь простым и понятным решениям;
  • Все сложные решения подвергайте критическому анализу, желательно на самом раннем этапе, пока не убедитесь, что упрощать себе дороже;
  • Любое усложнение должно иметь основание, в идеале согласованное и утвержденное с заказчиком

« Начало: правило модульности Продолжение: правило композиции »
Рауф Алиев @raliev
карма
130,2
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (26)

  • +5
    Конечно автор — царь и Бог, но под катом хотелось бы увидеть, что-нибудь более специфичное для Unix. За статью, спасибо.
    • +3
      Не хотелось опускаться на уровень конкретных примеров. Но в будущих статьях обязательно что-нибудь придумаю
    • +2
      конкретные примеры скорее будут мешать. хоть и говорится о принципах программирования под Unix, но я думаю и для других они тоже будут полезны. А примеры для Unix могут сбить с толку.
    • +5
      Конкретно про юникс: как и в случае с модульностью, с простотой в юниксах — полный швах, хотя сам принцип и имеет право на жизнь.

      Лучший пример принципа «Зачем нам дизайн, если можно сделать ОВЕРдизайн» — это знаменитый x.org
      Я не разбираюсь в X настолько глубоко, как Julien Danjou, но для того, чтобы понять насколько там все печально достаточно подумать о том, когда Вы в последний раз использовали сетевые возможности X вместо, скажем, vnc? Кроме того, что эти сетевые возможности практически нигде не используются, они открывают забавный вектор атаки (подозреваю, что в переусложненном коде 80-х годов, который никто уже не понимает есть некоторое количество ошибок) — одной из которых долгое время являлась возможность снятия keylog-а с удаленной системы, не имея даже аккаунта на ней. С появлением xauth осталась только возможность делать keylog ЛЮБОЙ активности на десктопе (в том числе gksudo, терминала и вообще всех рутовых процессов) из-под непривилегированного пользователя.

      Чтобы обойти высокую латентность и низкую пропускную способность сетевых протоколов, в конце концов появляются расширения типа MIT-SHM, которые полностью отказываются от сетевых возможностей во имя производительности, при этом все еще оставляя видимость, что все таки происходит по сети. Этого оказывается мало и появляется DRI/DRM, имеющий полный доступ к аппаратуре и физической памяти, но «для галочки» работающий как user-mode процесс.

      Да и сама юзермодовость X сервера — не более, чем «потемкинская деревня» для демонстрации как все хорошо. Если углубиться в детали, оказывается что он работает от root-а, что в сочетании с довольно дурацкой юникс-безопасностью автоматически означает то же, что и kernel-mode модуль — то есть полное и ничем неограниченное доверие (даже если кому то захочется ограничить x сервер с помощью какого нибудь LSM, о которых отдельный разговор, то придется оставить R/W доступ на /dev/mem, что опять таки означает полный и ничем не ограниченный доступ к системе).

      Был ли выучен урок? не думаю (зато аудиостек нативно поддерживает стриминг по сети, кроме случаев, когда он вообще не работает).

      xkcd 619 появилось не на пустом месте, да
      • 0
        Я с вами согласен.

        Правда я не понимаю, почему все ругаются на сетевую составляющую иксов. Сетевая составляющая иксов — скорее плюс (фича), чем минус. Можно сделать терминальный сервер :) Можно запустить клиентскую прогу на одном unix, а сервер будет на другой машине с другой архитектурой и другой ос. Конечно мало кто этим пользуется, но все же. Если x-server и клиент работают на одной машине — данные передаются через оперативную память, не используя сетевую подсистему. Если по сети — клиенту кажется, что удаленные приложения исполняются у него на компьютере. Только подлагивают чуть-чуть ;) Правда протокол иксов очень требовательный к каналу и почти не сжимается — это минус.

        Сетевая составляющая pulseaudio — очень хорошая фишка. Задержка приемлемая. В системах где она неприемлема обычно используют jack и realtime ядро. Зато появляются такие интересные фишки, как простая возможность с ноута послушать аудио на больших колонках, подключенных к другому компьютеру. И все будет нативно работать. И тоже самое с записью звука.

        Прозрачность работы через сеть — это не проблема xorg, проблема другая. В те далекие времена, когда сделали иксы, никто и подумать не мог, для чего его будут потом использовать. Тогда были другие компы, другие ресурсы на тех компах. Нужно было просто рисовать виджеты и окошки. В тех «окошках» не было ни видео, ни 3d-графики. Xorg создавался с определенной целью, но со временем в xorg начали пихать другие фишки, которые там не нужны, но запихать надо. С появлением видео и 3d-графики, когда надо прокачивать большие объемы данных, придумали ещё кучу костылей.

        Вообще, xorg ужасен и никто его переписывать видимо не собирается. Это как скелет в шкафу unix. Xorg тянет слишком многое: дрова, кучу скомпилированного под него софта, совместимость с qt и gtk, поэтому просто взять и что-то поменять кардинально не получится. Нужно очень много скооперированной работы разработчиков из разных проектов. И не факт ещё, что в этой работе будет смысл.

        Эх, много воды получилось
        • 0
          почему все ругаются на сетевую составляющую иксов
          Потому что она плохо себя зарекомендовала для сетевого доступа (все пользуются компрессированными vnc/rdp), и создает кучу проблем для локального доступа (уже упоминавшиеся здесь MIT-SHM и DRI как раз ОБХОДЯТ сетевую составляющую иксов, чтоб выжать производительности). Более того, давно и успешно разрабатываются всякие библиотеки, типа нотификаторов в трее, которые используют чисто локальные штуки типа d-bus. Вот и получится, что x-сервер у Вас будет на одном компьютере, а трей — будет отображаться (если будет) локально на машине с клиентом. В общем овердизайн в чистом виде.

          Сетевая составляющая pulseaudio — очень хорошая фишкаНе совсем. Это наружение слоистоисти же. Слой который отвечает за вывод и микширование звука не должен знать, как к нему этот самый звук приходит. А TCP/UDP стриминг PCM звука — не совсем то, что нужно подавляющему большинству пользователей.
          • 0
            А у нас вот все X11 гоняют, а не vnc. Объём данных слишком большим становится только в софте, написанном с намеренным игнорированием сетевой составляющей.
    • –1
      Специфичного хватает в оригинальной книге. Лучше что-нибудь не специфичное и не UNIX-овое. Должно же быть отличие?
  • –2
    Прекратите уже использовать слово «UNIX» в заголовке, потому что идеология-то посиксовая, но правила применимы к любому программированию, поэтому UNIX в заголовке отсекает виндузятников.
    • +3
      В загловке используется UNIX, потому что именно так называется оригинальная книга Реймонда, откуда все эти статьи почти полностью и беруться. Книжка конечно хорошая, но в своем роде беллетристика, мне она пользы много не принесла.
    • +8
      Ну, виндузятники, которые не читают статью только потому, что в заголовке есть слово UNIX — сами себе злобные бакланы. Хотя пока в этом цикле статей я не увидел ничего про UNIX. Да и вещи банальные.
    • 0
      А примеры на Схеме отсекают s-exp'офобов от SICP. ССЗБ.
  • –1
    Beautiful is better than ugly.
    Explicit is better than implicit.
    Simple is better than complex.
    Complex is better than complicated.

  • 0
    Оффтоп: А у вас нет такой же бритвочки, но в PNG с прозрачностью? :)
  • +3
    А вы остальные 8 статей напишете в таком же стиле? Или они будут более информативные и на тему юникса?
    • +1
      Если честно, это имеет прямейшее отношение к UNIX, поэтому даже примеров нет :)). Да и нафиг Вам описание того, чем read() отличается от pread() и про то, чем отличается поддержка Linux'ом спецификации SUS 3 от таковой во FreeBSD и Solaris :)? Это всё достаточно просто изучается с помощью man'ов, и уж точно вряд ли кого-то заинтересует на хабре…
  • 0
    Вкратце содержание статьи: Исскуство погромированния на ЮНИКС для тех, кто не умеет читать по английски.
    А для тех кто умеет catb.org/esr/writings/taoup/html/
  • 0
    К Юниксу статья отношения не имеет.

    Она для всех в тему, включая Web, Windows, Unix, embedded и всякие Баду.
  • –3
    Хочу отметить — правила изложенные в статье — есть правила функционального программирования.
    Скажем так — начальный уровень.
  • +1
    мне показалось, что упоминание Оккама/П.Д.О. было бы уместнее в предыдущей статье — про модульность. здесь же он ясности не добавил). в программировании нередко приходится добавлять обозначения для того, чтобы повысить ясность. сравните:

    print 1 * 3

    и

    price_of_apples = 1
    number_of_apples = 3
    print price_of_apples * number_of_apples

    первый пример несомненно короче. но где больше ясность?

    Кроме того:
    Последующее развитие логики показало, однако, что отнесение Принципа Достаточного Основания к числу логических законов лишено /достаточных/ оснований.
    wiki: Принцип достаточного основания) иными словами, бритва Оккама не нужна))
    • +1
      Ну если весь ваш пример и есть вся программа — то первый пример лучше намного :)
      А вообще очень напоминает metaleks.net/programming/the-evolution-of-a-python-programmer
      • 0
        А чем лучше? Мы не будем говорить про вычисления на калькуляторе, где «программа» живет лишь до получения первого результата. Давайте рассмотрим более привычную для разработчиков ситуацию ситуацию, когда программа должна использоваться и поддерживаться в течении продолжительного времени. Как это часто бывает, проходит полгода, и цены на яблоки вырастают на на 1 рубль. Этот факт нужно отразить в чудо-программе. Разумеется, предыдущего гения-программиста уже месяц, как схантил йандекс, и задачу предстоит решать другому. Что он видит? Он видит в коде две волшебные константы: что из них цена, которую нужно менять «1» или «3»? В исходнике нет ответа, поэтому он идет выяснять состояние прайса на яблоки в предыдущем периоде, проклиная всех долбаных гениев, решивших (уж не знаю чем вам этот код приглянулся) — допустим, сэкономить 10 секунд на написание 2 строчек проясняющего суть текста. :)
    • 0
      Вы ничего не понимаете в ясности. ООП — наше всё! :P

      (let ((apples-cost 42))
        (defun apples-update-price (new-price)
          (setf apples-cost new-price))
        (defun apples-calculate-cost (&key (number 1) (discount 0))
          (when (/= discount 0)
            (error «Discount not supported yet»))
          (* apples-cost number)))

      (apples-update-price 1)
      (prin1 (apples-calculate-cost :number 3))
      • 0
        Моноширинный шрифт использовать не могу. Кармы не хватает.
      • 0
        а че это такое?

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.