понедельник, 30 ноября 2009 г.

[comp.prog; management] Субъективность при оценке чужого дизайна программы

Хорошо обучать вытачиванию деталей – сделал ученик слишком тонкую, нагрузили ее как следует – сломалась. Сделал слишком толстую, показали разницу с нормальной деталью и спросили – зачем лишний металл расходовать?

В каратэ технике обучать так же удобно: выпрямил в майя-гири опорную ногу, сенсей по ней шлепнул слегка, ласково приговаривая при этом “что прямое, то ломается” – и запомнишь урок на всю жизнь ;)

А вот в живописи уже гораздо сложнее. Еще хорошо, когда учитель говорит – здесь тени неправильно лежат при таком источнике. В крайнем случае можно ученика заставить натурный эксперимент поставить, чтобы доказать это. А вот как быть, когда недостатки формулируются как “передний план перегружен” или “тона в левом верхнем углу слишком яркие”? Есть здесь какие-то объективные критерии проверить правильность претензий учителя? По-моему, нет. Либо веришь и набираешься ума-разума. Либо не веришь и идешь к другому учителю. Ну или пытаешься доказывать всему миру, что твое видение предмета правильное :) В конце-концов, у Винсента ван Гога и Поля Гогена получилось. После смерти…

Программирование же в этом смысле является чем-то средним между слесарным ремеслом (или каратэ, если хотите) и живописью. С одной стороны, написана программа, которая работает – т.е. выполняет то, что от нее требуется. Но смотришь на ее исходник, и понимаешь, что “передний план-то перегружен”. Что можно сделать проще. Или чуть сложнее, но гибче. Понимать-то понимаешь, но когда дело доходит до объяснения… Тут-то и начинаются сложности.

Хорошо, когда буквально на пальцах можно объяснить, как сделать проще. Например, было:

int get_multiply() {
  int result = SINGLE_FACTOR;
  if( some_condition() )
    result = DOUBLE_FACTOR;
  return result;
}

а можно было бы сделать:

int get_multiply() {
  return some_condition() ? DOUBLE_FACTOR : SINGLE_FACTOR;
}

(Хотя, если такого кода много в разных ипостасях, то указывать на каждую возможную модификацию нереально – время находится только на то, чтобы сказать: “можно сделать проще.”)

Хуже, когда дело касается “вкусовых” пристрастий, ведь любую более-менее серьезную задачу можно решить несколькими способами. Кто-то делает ее решение с использованием классов A, B, C и D. Мне кажется, что можно было бы обойтись классами C и D, но добавив общего предка E. Работать будет и так, и так. Но какое решение лучше? Мне на основании собственного опыта и набитых шишек может казаться, что моим способом. Моему подчиненному может так не казаться.

Аргументы “Поверь моему опыту, у тебя передний план перегружен” или “Передний план перегружен, я сказал!” не проходят. Программа работает. Как она будет расширяться в будущем – это гадание. Может как я говорю, может не так. Худшее, что здесь может произойти – это долгая и бессмысленная перепалка на тему того, какая вероятность больше (еще одна вариация соревнования “у кого длиннее”).

Поэтому свою точку зрения нужно аргументировать (хорошо сказано, *ля). Но для аргументации нужно время, нужна демонстрация альтернативной реализации. А ведь код уже есть, и он работает, да только мне не нравится. Поскольку выработанный за долгие годы нюх подсказывает, что “передний план-то перегружен”, и все это придется основательно дорабатывать напильником, если придется этот код сопровождать. (А сопровождать-то придется. Причем, в соответствии со всеми законами подлости, сопровождать именно тебе, и в самые кратчайшие сроки, когда какому-нибудь VIP-клиенту что-нибудь в голову стукнет.)

И все этого хорошо, если не возникло никаких личностных претензий, вроде “Ты всегда ругаешь мой код!” Тут вообще руки опускаются, и хочется оставить все как есть, отрезав напоследок: “Ну смотри сам, сопровождать будешь лично ты.”

В общем, жалко, что аргументы “Потому, что я так сказал!” не канают… :(

PS. С программами-то еще ладно. Там хоть какие-то объективные критерии могут быть найдены. А вот с документацией куда хуже. “Этот абзац непонятен” – “Как непонятен? Я же здесь все подробно написал.” – “А мне, как читателю, непонятен.” – “Ну не знаю, я все понимаю!”

PPS. Любые совпадения с реальными персонажами, фрагментами программ и диалогов являются случайными и непредумышленными. Я описал сборный портрет молодого программиста. Сам был таким в районе 1992-1999 годов, особенно в части документации.

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

8 комментариев:

Skynin комментирует...

Если не рассматривать сложности отношений учитель-ученик то:
Чтобы стать хорошим программистом нужно много читать хорошего кода. А не, как в одном программерском канале о студентах пошутили "чукча не читатель, чукча писатель". Поэтому чтобы убедить без личных затрат - нужно найти качественный код как можно более близкий к написанному фрагменту - и таки заставить объяснить - почему там написано вот так, чем руководствовался тот программист? а теперь посмотри на свой код.
"Разбор полетов" - полезная вещь. В юности каратэ тоже занимался, и сенсей собирал в кружок и - какие ошибки были совершены? НЕ - да Вася круче - а ЧЕМ круче?

О документации... мне понравилось у серьезных франчей 1С - начинающих программистов пару месяцев постоянно сажают на линию консультаций (тех поддержки). Приговаривая - "Они научились деньги зарабатывать чтобы тебе заплатить, а если ты не научишься им объяснять - то останешься без денег, они найдут умней тебя который их поймет, утешит и объяснит. Так кто из вас тупой?"

eao197 комментирует...

>нужно найти качественный код как можно более близкий к написанному фрагменту - и таки заставить объяснить - почему там написано вот так, чем руководствовался тот программист? а теперь посмотри на свой код.

Мне когда-то сильно помогал код Вирта и Страуструпа в их книгах.

>начинающих программистов пару месяцев постоянно сажают на линию консультаций (тех поддержки)

Вот это сильно. Одобрям-с! :)

Skynin комментирует...

Мне когда-то сильно помогал код Вирта и Страуструпа в их книгах.
Начинать конечно нужно с такого кода.
Но вот что и трудно объяснить начинающему программисту - это разницу между учебным кодом и профессиональным.
Что это в учебном коде printf("Hello world"); а вот в профессиональном надо бы о проверочке подумать, а вывелась ли надпись? А может - puts? а может вообще cputs более уместно? А если строка придет извне, и в UTF-16? А ...,

То есть профессиональный код делающий тоже самое обычно развесистей. Потому что уже есть понимание слова "безопасность"

Вспомнилось, домашняя проблема - электророзетки слабые, задумал двухглавый удлинитель, чтобы из двух разеток подлючать. Ладно, нулевую и плюсовую фазы - определю. А вот как сделать безопасно, 1. чтобы не перепутать, 2. чтобы на второй вилке не было напряжения когда первая включена

И такое все муторное в реализации показалось - что отказался.
А будь мне 18, слепил бы не задумываясь об опасности конструкции.

Так и молодые программисты. Убедить можно только на примерах, что там дальше может быть - они еще напрочь не знают, и даже фантазии у них нет - представить возможные кошмарики отладки при создании 3ей версии.

eao197 комментирует...

>Что это в учебном коде printf("Hello world"); а вот в профессиональном надо бы о проверочке подумать, а вывелась ли надпись? А может - puts? а может вообще cputs более уместно? А если строка придет извне, и в UTF-16?

Ну в этом смысле я, наверное, экстремальный пофигист :)
По мне профессиональный код должен быть минимальным и функциональным, хорошо оформленным и, главное, обоснованным. Т.е. любое решение, которое принял программист, должно быть обосновано. Грубо говоря -- завел переменную i, должен суметь объяснить, зачем. Вызвал метод f(), должен суметь объяснить, почему именно f(), а не g().

А не профессиональный код -- это когда "я привык так писать" и "я думаю, что так должно быть быстрее". Про быстрее -- это вообще отдельная песня, поскольку сразу же выясняется, что никаких замеров не выполнялось.

Собственно из этого есть важное следствие -- профессионал в одной области (скажем, real-time) может быть абсолютным дилетантом в другой (скажем, в SQL). И если в real-time он будет писать как бог, то в SQL-е использовать (по крайней мере по началу) надерганные из разных учебников фрагменты "потому что работают".

Skynin комментирует...

и, главное, обоснованным. Т.е. любое решение, которое принял программист, должно быть обосновано.
Вот об том и я - "почему там написано вот так"

Вопросы начинающих на форумах именно на это указывают в первую очередь - отсутствие навыка ставить вопрос:
"С какой целью?"
Объем знаний, количество прочитанных книг - дело наживное.

Но вот отсутствие рефлексии...
"Мудрость делает человека быстрее опытным, чем опыт - мудрым"


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

Или - а вот регесп медленный, потому я тут лучше полсотни своих строк, "сам распарсю", а на вопрос - "как часто в худшем случае будет вызываться этот метод?" - "ммм... на трети запросов к БД" - "и каково соотношение времени: регеспа и запросов, твоего кода и запросов?"

Повышение быстродействия без замеров - просто умиляет :)

eao197 комментирует...

>Вот об том и я - "почему там написано вот так"

Ну а я еще к тому, что профессионал может сказать "а проблемы UTF-16 при вызове printf в данном конкретном случае мне по барабану" :)

Skynin комментирует...

Ну а я еще к тому, что профессионал может сказать "а проблемы UTF-16 при вызове printf в данном конкретном случае мне по барабану"
"Когда я начинал заниматься дзен, я видел горы как горы, а реки как реки. Через 15 лет я увидел, что горы вовсе не горы, и реки, вовсе не реки. И вот, прошло 30 лет, и я вижу горы и реки" (какой-то учитель дзен)

Вот таже и разница между "мне по барабану на UTF-16" студента и профессионала :)

eao197 комментирует...

Постигшего Дао чувствую я в словах сиих.

;)