Контрольные списки из «Совершенного кода»

20.01.2018

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

Поэтому, чтобы освежать в памяти действительно важные детали мастерства программирования, я нашёл в сети кем-то заботливо переписанные контрольные списки из книги «Совершенный код». Тем более, бумажную книгу уже скоро придётся отдавать.

Обязательно к прочтению

Нижеперечисленные списки могут вправить мозг большинству разработчиков. Я сам допускал очень много объективно неприятных ошибок, которых теперь не делаю потому что прочитал книгу и внимательно изучил контрольные списки. В этом блоге только то, что относится непосредственно к программированию.

О проектировании

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

Весьма желательно

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

Но, конечно, простой просмотр контрольных списков не заменит чтения прекрасной книги Стива Макконнелла. Я, как и прежде, настоятельно рекомендую прочитать её всем, кто действительно хочет научиться хорошо программировать.

P.S. А если у вас всё хорошо с английским, то все эти списки можно прочитать на официальном сайте книги «Совершенный код». Вот здесь — cc2e.com/Page.aspx?nid=73. Только не спрашивайте у меня, почему Стив при всех своих достоинствах не додумался сделать ЧПУ :)

Комментарии

  1. # samlowry

    Я знаю! Я! Стив настолько суров и совершенен, что ?nid=73 для него — ЧПУ!

    ЗЫ: не, билят, уж лучше на русском, красиводизайненом сайте, чем на убогом, времён доткомов, да ещё и со съехавшим в Сафари дизом, да ещё с навязываинем регистрации.

  2. # Тормоз

    Да уж, в юзабилити чувак не силён, это точно. И про навязывание регистрации я не знал, просто открыл список и скопировал URI. Сейчас проверил — действительно, заставляют регистрироваться. Глупо.

    Но сама книга на самом деле очень хорошая, я с неё много почерпнул. Именно о программировании.

    Кстати! Большинство программистов вообще не умеют разрабатывать GUI. Они умеют говорить с машиной, но с человеком вообще никак.

  3. # Evgeny Sergeev

    Про циклы и условия. Хочется отметить, что пхп позволяет писать в стиле функциональных языков, снижая тем самым количество условий

  4. # Тормоз

    А какие основные особенности стиля функциональных языков? Можешь привести пример задачи с циклами или условиями, в котором PHP выигрывает в сравнении с каким-то другим языком?

  5. # Evgeny Sergeev

    В двух словах трудно сказать. Вот ссылка там довольно понятно все www.ibm.com/develope…

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

  6. # samlowry

    Могу. В ряде языков ООП навязан, да ещё — и ужасно тяжёлый ООП. Джава например, там пустой проект — уже класс с нечитаемым именем.

  7. # Тормоз

    Евгений, прочитал статью на IBM, узнал про замыкания и лямбда-функции, довольно интересно это всё… но всё равно не понял, как это связано с сокращением условий в PHP :)

    Samlowry, ой, Java мне вообще пока тёмный лес. Скорей всего я даже не буду изучать этот язык, я уже практически на 100% определился, что следующим у меня будет Ruby. Ну ещё «Эрланг» довольно интересен.

  8. # Сергей М.

    Ну, на вскидку, три вещи по «сокращению»:

    «Ленивые» логические операторы – $condition && operator; (типично функционально и навевает о времени, проведенном с лиспом)

    Динамические функции (классы и т.д.) – например, вызов нужной функции в зависимости от условий без полиморфизма, или, наоборот, при полиморфизме быстрая работа с пулом классов. Сюда же извороты с __call и подобным.

    Ну и, соответственно, лямбда функции, которые вообще мечта для всяких там map и reduce, а не только сокращение места. Плюс, соответственно, хитрости «неймспейсов» замыканий.

  9. # Сергей М.

    Ну и samlowry, конечно, не до конца прав – в Джаве даже пустой проект класс потому что это объектное программирование, которое навязывает стиль (прежде всего, для командной и проектной работы), хоть оно и далеко от того, что рисовали нам в Смоллтоке (и сделали что-то похожее в Обжектив Си).

  10. # Тормоз

    Я такие && не использую, потому что нифига не помню, что они значат, не могу это в голове держать. Ключевые слова типа OR гораздо лучше, на мой взгляд.

  11. # Сергей М.

    Ну, после сишных флагов приедается :)

    А or тоже самое – особенно классно выглядит db_connect() or die(); %)

  12. # Тормоз

    Да, забавно :) Только die, наверно, всё же дурной тон в скриптах писать, надо какую-то ошибку выдавать.

  13. # Evgeny Sergeev

    Тормоз, выше уже все написали про использование. Поэтому приведу пример.

    If a > b {

    If b < 5{ RunX() } If b > 6{ RunY() } }

    Можно представить так:
    runner(a > b and b < 5, runX)

    runner(a > b and b > 6, RunY)

    Function runner(cond, func){

    Return cond and func()
    }

  14. # Тормоз

    Что-то не наблюдается в этом примере особой читаемости или простоты.

  15. # Evgeny Sergeev

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

  16. # Сергей М.

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

    Я лучше приведу сегодняшний ночной пример.

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

    Такая вот штука iskariot.ru/fin1.png

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

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

    Но дальше мне надо рисовать эти списки однотипным образом – вводим функцию рисовки show, которая по типу рисует тот или иной список, а всю дополнительную информацию берет из поля li_add, которое мы предварительно записали на стадии сбора.

    Но остается еще куча однотипных функций по коду, которые проходят по нужному им массиву и отбирают только попадающие под условия элементы, плюс заодно ведут пул id‘шников, чтобы их можно было посылать на сервер как «прочитанные» (addToPool()). И выходит такая вещь:

    function map($sort, Closure $f){
    $db = $this->db;
    a = $this->$db;

    $self = $this;
    array_walk($a, $sort, function($item, $key) use($self, $f){ $el = $f($item); $self->addToPool($el); ArrayOperations::$sort($a); } );
    }

    И все функции приобретают вид:

    $code = ‘tax’;
    //инициализируем
    $this->flushPool($code, self::T_CONTRACT);
    //помещаем в пул только нужные
    $this->map(function(&$c){ if($c[‘tax’]){ $c[‘li_dop’]=’<small>(’.maybe_price($c[‘tax’]).’ руб.)</small>’; return $c; }
    });
    //рисуем
    $this->showPool(‘Числится <span style=«color:#900»>госпошлина</span>’,
    array(‘show’=>‘active’, ‘mark’ => ‘tax’, ‘sortby’=>‘sum_credit’, ‘sort’=>‘DESC’));

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

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

  17. # Evgeny Sergeev

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

  18. # Тормоз

    Какой именно?

  19. # Evgeny Sergeev

    Для примера хочу взять вот этот код – pastie.org/1223867

  20. # Тормоз

    У-у-у, этот код древний уже, да ещё и с ошибкой (сейчас увидел, там неиспользуемая константа вместо переменной). Возьми лучше актуальную версию. У тебя в ящике подарочное письмо от робота, можешь скачать Daos.

    Критиковать имеет смысл именно функции чтения/записи, потому что остальной код был написан фактически другим человеком :) В смысле я очень сильно изменился за последний год как программист, и почти всё теперь делаю иначе.

    Заранее спасибо. Очень интересно будет увидеть твою реализацию.

    P.S. Если письмо снова в «спам» попало, то напиши в ту ветку gmail, с которой у нас всё ОК было.

  21. # Evgeny Sergeev

    Спасибо, письмо дошло. Критиковать не собирался, просто некоторые приемы показать которыми сам пользуюсь.

  22. # Тормоз

    Как это не собирался? Надо! :) Серьезно, я ж ещё только учусь, да все мы учимся. Адекватная критика помогает взглянуть на свой код с другой стороны.

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

Комментирование этой статьи закрыто.

Интересное Покупки ТехникаРазное Отдых Статьи Строительство Услуги Общество Хобби Культура Советы Уют