Скорее соглашусь, чем не соглашусь. Со многими но. Грустно всё это — когда программистам нужен кнут для мотивации (и Кнут против premature optimization).
По опыту скажу — лучшие проекты (в срок и сверхнадежные) были, когда не было никаких менеджеров. Людей, правда, тоже мало: 1-3. Почему? Потому что хотя бы когда появляется менеджер, он может убить вопросом: «почему ты покрываешь тестами? Нам за это деньги не платят». Или «кто сказал, что покрытие тестами должно быть 100 процентов?».
Недавно показательная вещь случилась. Говорю: полдня надо еще, чтобы полностью покрыть тестами. Человек, который уж очень хочет забрать код, говорит: «не надо, мы тебе и так доверяем». В итоге нашли баг, который был как раз в том месте, не покрытом тестами. Но они потратили 2 дня на его поиски. (не ТДД, каюсь, но то был проект — взять готовый код, оптимизировать и рефакторить).
Мотивация у людей сильно растет в случае их личного ощущения причастности и участия в разработке. Всякие аджайлы этому помогают. Чтобы человек не отлынивал, можно, чтобы он сам участвовал в дележе задач. Задачи писать на доске, на стене, возле выхода. Всем видно, кто что делает. Взаимное ревью кода позволяет другим видеть, чем человек занимался, помогает распространять знания о системе (не должно быть — один заболел, от него зависящие бездельничают). ТДД (опять сказал это слово!) позволяет выполнять задачи равномерно, ощущая «на вес» каждый кусок кода — поэтому задачи становятся интересными. Появляется ощущение выполненной работы в любом части проекта.
Несколько хороших опытных программистов — и всё будет в порядке. Единственное, что это бывает в стране единорогов.
Если программисты ударяются в предварительную оптимизацию — факап — неопытные программисты. Если программисты рефакторят полгода — факап — неправильные программисты. Потому что рефакторинг — часть процесса, он должен быть незаметным и проводиться всё время. А если тормознули на полгода, значит говнокодили до этого долго и дошли до точки.
Риск быть уволенным, как кажется, нельзя считать таким уже и негативным риском. Проекты не часто меняются. Раз в году может и пойти поискать другую работу.
И вообще, эти ваши менеджерские игры мне не понятны. Менеджер не понимает (часто) ничего в программировании, поэтому не может влиять так как надо на процесс. Суть проблем он только узнает от других, решения принимает на основе предоставленной информации другими. Т.е. в этой «пищевой цепочке» он ничего не производит. В чем тогда опыт? В том, что награда за успешный проект, который он не делал, достается ему, но если проект неуспешный, который он не делал, то его «наказывают». Странно, очень странно.
Прототипирование тяжело назвать проектированием. Цель прототипа — не создать архитектуру, а проверить какой-либо подход, модель.
Часто прототипирование делают на функциональных языках, где понятие «архитектура» слабо применимо.
Обычно прототип — это наспех слепленная каша из кода, которого минимум, лишь бы что-то оценить. При прототипировании нет никаких правил проектирования. Также и нет запрета на эволюционное проектирование. Я и прототипы в чуть более сложных проектах развиваю эволюционно. Сначала пишется самая существенная часть функционала в прототипе. Потом добавляю то, что менее существенное.
TDD не обязательно опираться должно на user story. Последнее — хорошо и прекрасно для многих проектов. Но ТДД — это процесс разработки, а не обязательно процесс преобразования требований от заказчика.
Я, например, сейчас делаю дома один проект. Математические вычисления, большие объемы данных. Заказчика нет, я сам себе заказчик. Юзер-стори тоже нет, даже гуи-интерфейса пока нет, т.к. гуи-интерфейс далеко не связан с сутью проекта. Нет сущностей.
Но ТДД прекрасно работает. Требование в ТДД — это требование к следующему шагу кодирования. Не обязательно требование заказчика.
Скажу даже больше: на выходных я провел за полдня рефакторинг, который затронул почти весь код. И понял, что без того покрытия тестами уже проект бы умер. Но с тестами вообще практически без никаких рисков такие масштабные изменения.
Конечно, юнит-тесты не являются показателем, что проект по ТДД разрабатывается. Но всё же в этом проекте я бы не смог без него разрабатывать.
Если проект такого плана, что архитектура не может родиться сама по себе из кода, то тогда делают прототипы. Выбирают подходящий. На этапе прототипирования не покрывают тестами а оценивают только, какой подход будет более подходящим. А потом переписывание на чистовик — с ТДД. И в этом нет никакого минуса. Если вы собираетесь писать тест, то лучше его написать до, чем после. Во первых, виднее, какого размера код на метод выделить (как его удобнее тестировать). Во вторых не сидите в дебаге так много, проверяя, что не так, если тест есть. В третьих не забудете тест написать и покрытие при ТДД обычно более полное.
Нужно соблюдать процесс. Не я в крайности бросаюсь, а скорее вы, когда думаете, что есть выбор только одного из двух: «проектирование наперед» <-> «костыли».
Рефакторинг в ТДД гарантированно убирает костыли. Как раз наоборот получается. При небольших итерациях программист каждый раз «за собой подметает», исключая любой костыль.
Такие специалисты ценятся среди таких же специалистов )))) Буржуи же, когда считают деньги и сравнивают надежность и производительность — вносят свои коррективы в оценки ))
Лично меня устраивает то, что я написал в статье. Не такой хлеб и абстрактный в вакууме.
А бОльшую конкретику обсуждать не имею никакой возможности. Потому что объем текста будет гораздо больше статей.
А потом, просто аргументов в разговоре должно быть достаточно. Или хотя бы аналогий. Почему ТДД выгодно, уже несколько раз написал, под раз написал здесь под несколькими углами. А от вас не услышал ни одного аргумента, что выгодно проектировать наперед. Кроме того, что у вас есть положительный опыт. И вы после этого требуете от меня описания моего опыта, потому что не верите в мой опыт? Ну тогда я умею очень хорошо притворяться, что даже аргументы выдумываю на ходу логичные.
Но не суть важно. Проектирование мостов или электрических схем одинаково антианалогично к проектированию ПО. ПО, как и математика — язык выражения мыслей, а не модель из камня, бумаги или что-то, что будет потом реализовано в чем-то другом, материальном.
К программированию это не относится. Написать на языка ЮМЛ, а потом переписывать на другой язык не имеет смысла. Это не создание материального продукта. Но к сожалению, большинство так себе процесс и представляют. Сначала проектируем на чем-то «удобном для проектирования», а потом даем кому-то писать на страшном непонятном языке программирования. Строя дом или мост, конечно же, рефакторить не получится. Или когда схема появится, перепаивать ее дорого.
Но программа — это не пластилин, не кремний и не бетон. Она и есть описание, а не материальный объект.
Аргументы ничего не значат? Что такое объективно, что такое субъективно — это вроде должно объясняться логически.
Вроде этого:
Точные науки рождают представления об объективном мире (знания):
Объективный мир -> Субъект -> Представление об мире.
Не науки поступают так:
Объективный мир < — Субъект -> Представление об мире.
Стрелки — это информационные потоки. Субъективный вымысел называется творчеством.
Угадайте, какой рисунок в проектировании наперед?
Заказчик (объект) < — (угадаем что ему нужно) < — Проектировщик (субъект) -> Программа (делает непонятно что непонятно кому нужно)
Опыт описать кратко не получится. Любой проект, даже небольшой всегда тянет на книгу, потому что каждый день происходит что-то интересное.
Могу кинуть ссылку, не в целях рекламы, своей статьи, косвенно показывающей, как можно и почему выгодно проектировать эволюционно: Хлеб Маркуса и YAGNI
Даже если вы не фантазер, вы берете за основу процесс фантазирования.
А если так:
1. Требование -> тест
2. Проверям тесты -> падает последний. Убедились, что требование не реализованно.
3. Пишем код, запускаем тест, требование удовлетворено.
4. Рефакторинг кода, пока он не станет самым простым и естественным. И чтобы тесты не падаел.
5. Идем в пункт 1.
Если много требований, то берем по одному. Если требования слишком высокоуровневые, добавляем от себя подтребования и по тому же алгоритму.
А что предлагает проектирование наперед? Рефлексировать на тему красоты и гибкости? Где в проектировании наперед есть объективная составляющая? Критериев оценки там нет. (И поверьте опыту — водопад всегда затягивает проекты и получается говнокод в итоге. Жаль, что водопадная игла заставляет людей не видеть причину, а списывать на плохое планирование и стараться в следующий раз «планировать тщательнее»)
Вы видели когда-нибудь математика, который рисует схемы? (не геометрия )))
У вас неверная аналогия. Причем это одна из главных проблем нашей индустрии. У меня когда-то тоже была такая аналогия, знаю ее корни. Причина — наше образование, которое варьируется от плохого, то крайне ужасного. Начинающие программисты думают, что создают «конструкции». Надо по языку преподавателям надавать и вообще поменять термины, а то они с толку сбивают. «Управляющие конструкции» — привет императивным языкам. Следующий неправильный термин «архитектрор» (ну и «девелопер»). Только каски одеть — и вперед проектировать. Такие начинающие программисты или проектировщики представляют разработку, как построение дома. Отсюда и глюки.
Например, проектируя дом, программист хочет быть еще и фокусником — удивить гостей. Например, он сделает лишнюю гостевую комнату. Как будет доволен заказчик! Хотя он это и не требовал, но наш главный фантазер то знает, как оно бывает )))
А аналогия должна быть другая — программирование — лингвистическая вещь. Не путайте с гуманитарной. Математика — тоже лингвистическая вещь. Т.е. язык программирования — язык выражения мыслей. Язык математики — язык выражения сложных математических мыслей. Программист — не строитель. Программист — переводчик. Чем лучше он знает свой язык программирования и чем теснее общается с заказчиком, изучая его язык, тем точнее будет перевод.
А когда между заказчиком и программистом появляются лишние звенья, вроде аналитиков-проектировщиков, не знающих языка программирования — перевод заметно ухудшается. ЮМЛ — это тоже язык (правда убогий, хоть может быть ИНОГДА нагляднее). Если требования переводить сразу на ЮМЛ, а потом на язык программирования — получим двойной перевод. Представьте, что нужно перевести с китайского на русский что-то. Но переводят не прямо, а через промежуточный язык. При этом даже не английский, а например, чукотский, в котором отсутствуют многие понятия (не ради оскорбления национальностей). Тогда и получается код, вроде «Твой дом труба шаталь».
Кстати, вы интуитивно и представляете как строительство, поэтому мост и инженеров упоминаете.
Не только одной конторы опыт и не только мой. Основной труд: Кент Бек. Экстремальное программирование: разработка через тестирование. Ну и всех читать, понемногу, что есть эволюционное проектирование. Статьи Фаулера, книгу его «Рефакторинг: улучшение существующего кода». И т.д.
«При вас сказать UML — это высшей степени грех?»
А чего ж не грех. ЮМЛ, как диаграммы классов — это хорошая вещь для высокоуровневой документации (но даже для этого они не обязательны). Для кодирования и проектирования архиплохая вещь. Напомню один из главных принципов ООП (и не только ООП): инкапсуляция. Человеческий мозг так устроен, что умеет удерживать во внимании одновременно от 3 до 7 объектов (не ООП-объектов, а вообще). Инкапсуляцию придумали, чтобы на каждом уровне человек концентрировался на таком небольшом числе объектов, имеющих хорошие названия, которые говорят сами за себя, что за ними спрятано и позволяют не концентрироваться на том, что за ними. Диаграммы классов — это то, что делает диаметрально противоположное — кишки и говно — всё на картинке и не прячется.
«думать наперёд — это то, что нас из обизяны сделало»
Подмена понятий. То, что вы в проектировании наперед называете думать, я называю — необоснованно фантазировать. Точные науки отличаются от ненаук тем, что опираются на объективную информацию и делают из нее вывод, пытаясь снизить до минимума собственные предположения или выдумки. TDD и есть такой прямой научный способ проектировать. Опираться на приходящую информацию от заказчика, которая обычно приходит всегда. Заказчик меняет требования, что-то добавляет. Также TDD позволяет разрабатывать по кусочкам, концентрируясь то на одной, то на другой вещи. Т.е. даже если у вас есть сразу много (все) требования, вы не обязаны сразу их все спроектировать, не написав ни строчки. Требования вводятся в код понемногу, меняя архитектуру благодаря рефакторингу. Но главное — архитектура рождается обоснованно из требований, а не из фантазий.
А «креативные» личности, коими не являются математики, физики и т.д., любят фантазировать. Заказчик требует коня, дает полцарства, креативщик ему рисует в лучшем случае зебру, а в конце проекта получается осел
Если вы считаете, что программист — это джамшут и ему надо дать строгие указания — то так и будет. Будет очень серьезное превышение бюджета, даже если набрать дешевых джамшутов. Будет очень серьезное превышение сроков проекта. Будет много багов. Но, может быть, когда-то сможете завершить проект.
Личный совет, может не вам, а сомневающимся, курить TDD. Понять, что это такое — эволюционное проектирование. Почему так и каким образом архитектура рождается из кода.
Думать наперед, это равносильно «воображать» — удел гуманитариев. Приводящий к необоснованным решениям. Странно, что иногда даже при этом «водопадном» процессе мосты не падают.
Думать не надо, надо знать. Есть правила, набор методик, способы оценки. Проектирование в картинках — это чистое художество, упражнения в вымыслах. Сам процесс уже даунский, кто бы его не проводил. Рисунки делаются, но делаются в конце, когда уже что-то получилось и не изменится. Рисунки делаются иногда на совещаниях в начале, но на доске, фломастером или на бумажках от руки — но очень высокоуровневые и просто для обсуждения. Такие рисунки потом скорее всего выбрасываются. Главное проектирование происходит в процессе кодирования.
Или другими словами, программисты оживляют проект, делают то, что остальные нарисовали, спроектировали и так далее.
!!! Гнать проектировщиком-рисователей паганой метлой из индустрии!!! Когда уже люди мозгами дойдут, что не бывает хорошего кода по рисункам. Что не бывает хорошего программиста без того, чтобы он сам разбивал задачу и проектировал. Что говнокод рождается тогда, когда программисту раскладывают как что-то делать, а что, он не понимает. Что все рисунки убогие в сравнении с языком программирования. Что рисунки не дают понимания, какой говнокод из них получится. Что только код-говнокод показывает сам собой, какие в нем проблемы. Что проектируют не раз и навсегда, а рефакторят. Что программист — это человек умеющий читать и писать код, а рисунки — это удел САНТЕХНИКОВ в нашей индустрии. Сантехники захватили корыто и пытаются управлять программистами, но код не понимают и любят рисовать трубы и сливные бачки. Что тот, кто не понимает эволюционного проектирования (по коду), не умеет проектировать и наперед ВООБЩЕ. Что что что что. Таких утверждений можно на книгу набрать
Это значит, если мы хотим создать автоматизацию договорного отдела, или технической поддержки для обслуживания 10,000 клиентов, то нужна работа команды. В одиночку сделать такое трудно.
TЗ, пожалуйста. Очень сомневаюсь, что автоматизацию договорного отдела сделать в одиночку трудно. 10 000 клиентов — это может быть много, но обрабатываться может «одним, но очень гордым запросом» ))
Конечно, я вас не хочу оскорбить и не к вам относится «неграмотные студенты». Таких оптимизаторов Макконел студентами называл.
Вот я к ним и обращаюсь. Сразу в гнездо. Потому как на местах, где работаем, эта «оптимизация» захлестывает. И наверное надо их как-то обзывать, оскорблять и говорить, что их «профессионализм» — это «посредственность и бездарность». Потому что их понимание, как надо писать код, как раз основано на комплексах и взаимных упреках. Это психологическое что-то. Надо клин клином.
Оптимальнее будет с тестами. Устал объяснять в другом посте.
Кратко и более точно. Никогда (НИКОГДА) в проектировании не закладывают оптимальность. (Макконел, «Совершенный код»). Преждевременная оптимизация — наибольшее зло (Кнут).
Фаза оптимизации проекта находится в самом конце, после написания кода. И совсем не зря. Любая оптимизация, даже мелкая, в процессе получения первого кода — является преждевременной.
Дело в том, что цель оптимизации — найти глобальный максимум оптимизации. И это возможно, когда код написан полностью по DRY и YAGNI. Если нет дублирования кода и данных — оптимизация становится довольно тривиальной задачей. Когда код написан самым простым способом, он потенциально легко меняется в любом направлении. Не в смысле «настраивается», когда чрезмерную гибкость закладывают с помощью разных паттернов, а просто кода минимум и значит не вызывает больших проблем переписывание.
Когда код находится в таком состоянии, оптимизация происходит итерационно: замеры; определение самого узкого места; оптимизация. При этом стандартные методы оптимизации есть.
Если же человек оптимизировал заранее, то во-первых, код значительно хуже поддается изменениям, если вообще поддается. Во-вторых, картинка изменилась и он уже попал в какой-то бугорок — подъем стандартными методами оптимизации вряд ли даст глобальный максимум. В первом случае тоже нет гарантии, но во втором всё намного плачевнее.
Никто, никогда в здравом уме не проектирует, закладывая производительность. И как раз ТДД заставит написать код так, чтобы он был максимально простым. Это значит, что и оптимальность, если она нужна будет, вы сможете обеспечить по настоящему.
Главная ерунда, которая заставляет людей заранее оптимизировать — это отсутствие опыта в реальных проектах, требующих оптимальности. Если человек хоть раз делал замеры и оптимизировал, как надо, то вдруг появляется другое понимание. А именно: люди оптимизирующие заранее, пользуются «чутьем», которое основано на понимании «дорогой операции». Так вот, неграмотные студенты: дорогих операций нет самих по себе. Всегда есть совокупность факторов. И получается всегда некоторая сумма факторов. И вот, если некоторая операция выполняется день, а вторая секунду, то вторая может убить производительность, если выполняется миллионы раз, а первая 1 раз. День никак не критичен с потерей нескольких лет. Оптимизировать операцию, занимающую день — не смысла. А если эта оптимизация еще и вторую операцию и потом нельзя будет оптимизировать вторую — проект пропал.
Как только придет понимание, что «оптимизация — это процесс, основанный на замерах, а не написание оптимального кода» — вы сможете не париться по этому поводу, и если надо, писать настоящий оптимальный код. При этом, времени на оптимизацию будете тратить гораздо меньше. Потому как обычно, оптимизировать надо пару узких мест.
Макконел хорошую аналогию приводил: оптимизация заранее подобна экономии на спичках в то время, когда вы теряете миллионы.
В общем ТДД и оптимизация очень дружат на самом деле.
А желание оптимизировать всё и вся, выдает студентов (возможно вечных), при этом не объясняется логически. Просто люди убеждены, что это круто. И упрекают друг друга, если у кого-то код неоптимальный.
Тут скорее имеется в виду постоянное прохождение кодом тестов. Но например посередине имплементации какой-нибудь большой фичи тесты будут проходится, но реально фича работать не будет.
Это зависит от личной ответственности. Если вы пишете тесты ПОСЛЕ, то тогда часто они для галочки и пишутся. Потому как кажется, что код УЖЕ написан и работает.
Если же вы точно знаете требование заказчика, то выделить существенные вещи и написать тест вполне по силам программисту. Если же он не понимает назначение тестов и хочет, чтобы в глазах начальства и тесты были и просто проходили, то смысл эти тесты и писать тогда?
В любом случае вы правы, что тест не дает полную гарантию. Но это совершенно не значит, что тратить время на тесты бесполезно. Тесты при нормальном подходе дают высокую гарантию качества.
какая-то архитектура выйдет, да. Но будет ли это оптимальная архитектура? Может если продумать архитектуру заранее, вышло бы быстрее и\или оптимальнее? Гарантий вроде как нету
То же самое. Полных гарантий нету. Но без тестов, а с продумывание — гарантий нет вообще. Продумывание == выдумывание. Т.е. никакой объективности быть не может. Тесты дают возможность «не отрываться от земли», а писать ровно то, что нужно. Писать код, который не является чрезмерно гибким (привет астронавтам архитектуры). Писать код, который не является хардкодом (механический рефакторинг в ТДД заставляет выносить абстракции).
Мой опыт показывает — не будет быстрее и оптимальнее. Всегда при продумывании наперед проекты неимоверно затягивались, а код выдавал сюрпризы еще очень долго после завершения проекта. И наоборот. С ТДД написание кода шло совсем немного медленнее, но код становился неубиваемым и время на переписывание (при изменении требований) уменьшалось. И волшебным образом вдруг проекты перестали затягиваться по времени. А поддержка их становилась гораздо проще — практически багов не возникало потом.
Не только руководитель. Он же кем-то руководить должен. Нельзя взять и заставить изучить подчиненных.
Теоретики только рассказывают о Хаскеле, но не применяют их в массовых проектах, потому что сами в этих массовых проектах не очень-то участвуют. Чтобы пошло — нужно чтобы рядовые программисты параллельно изучали Хаскель. Также как для себя изучают Питон или F#.
И можно дать пинок в этом направлении — показать, как легко реализуются такие проекты на Хаскеле.
По опыту скажу — лучшие проекты (в срок и сверхнадежные) были, когда не было никаких менеджеров. Людей, правда, тоже мало: 1-3. Почему? Потому что хотя бы когда появляется менеджер, он может убить вопросом: «почему ты покрываешь тестами? Нам за это деньги не платят». Или «кто сказал, что покрытие тестами должно быть 100 процентов?».
Недавно показательная вещь случилась. Говорю: полдня надо еще, чтобы полностью покрыть тестами. Человек, который уж очень хочет забрать код, говорит: «не надо, мы тебе и так доверяем». В итоге нашли баг, который был как раз в том месте, не покрытом тестами. Но они потратили 2 дня на его поиски. (не ТДД, каюсь, но то был проект — взять готовый код, оптимизировать и рефакторить).
Мотивация у людей сильно растет в случае их личного ощущения причастности и участия в разработке. Всякие аджайлы этому помогают. Чтобы человек не отлынивал, можно, чтобы он сам участвовал в дележе задач. Задачи писать на доске, на стене, возле выхода. Всем видно, кто что делает. Взаимное ревью кода позволяет другим видеть, чем человек занимался, помогает распространять знания о системе (не должно быть — один заболел, от него зависящие бездельничают). ТДД (опять сказал это слово!) позволяет выполнять задачи равномерно, ощущая «на вес» каждый кусок кода — поэтому задачи становятся интересными. Появляется ощущение выполненной работы в любом части проекта.
Несколько хороших опытных программистов — и всё будет в порядке. Единственное, что это бывает в стране единорогов.
Если программисты ударяются в предварительную оптимизацию — факап — неопытные программисты. Если программисты рефакторят полгода — факап — неправильные программисты. Потому что рефакторинг — часть процесса, он должен быть незаметным и проводиться всё время. А если тормознули на полгода, значит говнокодили до этого долго и дошли до точки.
И вообще, эти ваши менеджерские игры мне не понятны. Менеджер не понимает (часто) ничего в программировании, поэтому не может влиять так как надо на процесс. Суть проблем он только узнает от других, решения принимает на основе предоставленной информации другими. Т.е. в этой «пищевой цепочке» он ничего не производит. В чем тогда опыт? В том, что награда за успешный проект, который он не делал, достается ему, но если проект неуспешный, который он не делал, то его «наказывают». Странно, очень странно.
Часто прототипирование делают на функциональных языках, где понятие «архитектура» слабо применимо.
Обычно прототип — это наспех слепленная каша из кода, которого минимум, лишь бы что-то оценить. При прототипировании нет никаких правил проектирования. Также и нет запрета на эволюционное проектирование. Я и прототипы в чуть более сложных проектах развиваю эволюционно. Сначала пишется самая существенная часть функционала в прототипе. Потом добавляю то, что менее существенное.
Я, например, сейчас делаю дома один проект. Математические вычисления, большие объемы данных. Заказчика нет, я сам себе заказчик. Юзер-стори тоже нет, даже гуи-интерфейса пока нет, т.к. гуи-интерфейс далеко не связан с сутью проекта. Нет сущностей.
Но ТДД прекрасно работает. Требование в ТДД — это требование к следующему шагу кодирования. Не обязательно требование заказчика.
Скажу даже больше: на выходных я провел за полдня рефакторинг, который затронул почти весь код. И понял, что без того покрытия тестами уже проект бы умер. Но с тестами вообще практически без никаких рисков такие масштабные изменения.
Конечно, юнит-тесты не являются показателем, что проект по ТДД разрабатывается. Но всё же в этом проекте я бы не смог без него разрабатывать.
Если проект такого плана, что архитектура не может родиться сама по себе из кода, то тогда делают прототипы. Выбирают подходящий. На этапе прототипирования не покрывают тестами а оценивают только, какой подход будет более подходящим. А потом переписывание на чистовик — с ТДД. И в этом нет никакого минуса. Если вы собираетесь писать тест, то лучше его написать до, чем после. Во первых, виднее, какого размера код на метод выделить (как его удобнее тестировать). Во вторых не сидите в дебаге так много, проверяя, что не так, если тест есть. В третьих не забудете тест написать и покрытие при ТДД обычно более полное.
Нужно соблюдать процесс. Не я в крайности бросаюсь, а скорее вы, когда думаете, что есть выбор только одного из двух: «проектирование наперед» <-> «костыли».
Рефакторинг в ТДД гарантированно убирает костыли. Как раз наоборот получается. При небольших итерациях программист каждый раз «за собой подметает», исключая любой костыль.
А бОльшую конкретику обсуждать не имею никакой возможности. Потому что объем текста будет гораздо больше статей.
А потом, просто аргументов в разговоре должно быть достаточно. Или хотя бы аналогий. Почему ТДД выгодно, уже несколько раз написал, под раз написал здесь под несколькими углами. А от вас не услышал ни одного аргумента, что выгодно проектировать наперед. Кроме того, что у вас есть положительный опыт. И вы после этого требуете от меня описания моего опыта, потому что не верите в мой опыт? Ну тогда я умею очень хорошо притворяться, что даже аргументы выдумываю на ходу логичные.
Но не суть важно. Проектирование мостов или электрических схем одинаково антианалогично к проектированию ПО. ПО, как и математика — язык выражения мыслей, а не модель из камня, бумаги или что-то, что будет потом реализовано в чем-то другом, материальном.
К программированию это не относится. Написать на языка ЮМЛ, а потом переписывать на другой язык не имеет смысла. Это не создание материального продукта. Но к сожалению, большинство так себе процесс и представляют. Сначала проектируем на чем-то «удобном для проектирования», а потом даем кому-то писать на страшном непонятном языке программирования. Строя дом или мост, конечно же, рефакторить не получится. Или когда схема появится, перепаивать ее дорого.
Но программа — это не пластилин, не кремний и не бетон. Она и есть описание, а не материальный объект.
Вроде этого:
Точные науки рождают представления об объективном мире (знания):
Объективный мир -> Субъект -> Представление об мире.
Не науки поступают так:
Объективный мир < — Субъект -> Представление об мире.
Стрелки — это информационные потоки. Субъективный вымысел называется творчеством.
Угадайте, какой рисунок в проектировании наперед?
Заказчик (объект) < — (угадаем что ему нужно) < — Проектировщик (субъект) -> Программа (делает непонятно что непонятно кому нужно)
Опыт описать кратко не получится. Любой проект, даже небольшой всегда тянет на книгу, потому что каждый день происходит что-то интересное.
Могу кинуть ссылку, не в целях рекламы, своей статьи, косвенно показывающей, как можно и почему выгодно проектировать эволюционно: Хлеб Маркуса и YAGNI
А если так:
1. Требование -> тест
2. Проверям тесты -> падает последний. Убедились, что требование не реализованно.
3. Пишем код, запускаем тест, требование удовлетворено.
4. Рефакторинг кода, пока он не станет самым простым и естественным. И чтобы тесты не падаел.
5. Идем в пункт 1.
Если много требований, то берем по одному. Если требования слишком высокоуровневые, добавляем от себя подтребования и по тому же алгоритму.
А что предлагает проектирование наперед? Рефлексировать на тему красоты и гибкости? Где в проектировании наперед есть объективная составляющая? Критериев оценки там нет. (И поверьте опыту — водопад всегда затягивает проекты и получается говнокод в итоге. Жаль, что водопадная игла заставляет людей не видеть причину, а списывать на плохое планирование и стараться в следующий раз «планировать тщательнее»)
У вас неверная аналогия. Причем это одна из главных проблем нашей индустрии. У меня когда-то тоже была такая аналогия, знаю ее корни. Причина — наше образование, которое варьируется от плохого, то крайне ужасного. Начинающие программисты думают, что создают «конструкции». Надо по языку преподавателям надавать и вообще поменять термины, а то они с толку сбивают. «Управляющие конструкции» — привет императивным языкам. Следующий неправильный термин «архитектрор» (ну и «девелопер»). Только каски одеть — и вперед проектировать. Такие начинающие программисты или проектировщики представляют разработку, как построение дома. Отсюда и глюки.
Например, проектируя дом, программист хочет быть еще и фокусником — удивить гостей. Например, он сделает лишнюю гостевую комнату. Как будет доволен заказчик! Хотя он это и не требовал, но наш главный фантазер то знает, как оно бывает )))
А аналогия должна быть другая — программирование — лингвистическая вещь. Не путайте с гуманитарной. Математика — тоже лингвистическая вещь. Т.е. язык программирования — язык выражения мыслей. Язык математики — язык выражения сложных математических мыслей. Программист — не строитель. Программист — переводчик. Чем лучше он знает свой язык программирования и чем теснее общается с заказчиком, изучая его язык, тем точнее будет перевод.
А когда между заказчиком и программистом появляются лишние звенья, вроде аналитиков-проектировщиков, не знающих языка программирования — перевод заметно ухудшается. ЮМЛ — это тоже язык (правда убогий, хоть может быть ИНОГДА нагляднее). Если требования переводить сразу на ЮМЛ, а потом на язык программирования — получим двойной перевод. Представьте, что нужно перевести с китайского на русский что-то. Но переводят не прямо, а через промежуточный язык. При этом даже не английский, а например, чукотский, в котором отсутствуют многие понятия (не ради оскорбления национальностей). Тогда и получается код, вроде «Твой дом труба шаталь».
Кстати, вы интуитивно и представляете как строительство, поэтому мост и инженеров упоминаете.
«При вас сказать UML — это высшей степени грех?»
А чего ж не грех. ЮМЛ, как диаграммы классов — это хорошая вещь для высокоуровневой документации (но даже для этого они не обязательны). Для кодирования и проектирования архиплохая вещь. Напомню один из главных принципов ООП (и не только ООП): инкапсуляция. Человеческий мозг так устроен, что умеет удерживать во внимании одновременно от 3 до 7 объектов (не ООП-объектов, а вообще). Инкапсуляцию придумали, чтобы на каждом уровне человек концентрировался на таком небольшом числе объектов, имеющих хорошие названия, которые говорят сами за себя, что за ними спрятано и позволяют не концентрироваться на том, что за ними. Диаграммы классов — это то, что делает диаметрально противоположное — кишки и говно — всё на картинке и не прячется.
«думать наперёд — это то, что нас из обизяны сделало»
Подмена понятий. То, что вы в проектировании наперед называете думать, я называю — необоснованно фантазировать. Точные науки отличаются от ненаук тем, что опираются на объективную информацию и делают из нее вывод, пытаясь снизить до минимума собственные предположения или выдумки. TDD и есть такой прямой научный способ проектировать. Опираться на приходящую информацию от заказчика, которая обычно приходит всегда. Заказчик меняет требования, что-то добавляет. Также TDD позволяет разрабатывать по кусочкам, концентрируясь то на одной, то на другой вещи. Т.е. даже если у вас есть сразу много (все) требования, вы не обязаны сразу их все спроектировать, не написав ни строчки. Требования вводятся в код понемногу, меняя архитектуру благодаря рефакторингу. Но главное — архитектура рождается обоснованно из требований, а не из фантазий.
А «креативные» личности, коими не являются математики, физики и т.д., любят фантазировать. Заказчик требует коня, дает полцарства, креативщик ему рисует в лучшем случае зебру, а в конце проекта получается осел
Личный совет, может не вам, а сомневающимся, курить TDD. Понять, что это такое — эволюционное проектирование. Почему так и каким образом архитектура рождается из кода.
Думать наперед, это равносильно «воображать» — удел гуманитариев. Приводящий к необоснованным решениям. Странно, что иногда даже при этом «водопадном» процессе мосты не падают.
Думать не надо, надо знать. Есть правила, набор методик, способы оценки. Проектирование в картинках — это чистое художество, упражнения в вымыслах. Сам процесс уже даунский, кто бы его не проводил. Рисунки делаются, но делаются в конце, когда уже что-то получилось и не изменится. Рисунки делаются иногда на совещаниях в начале, но на доске, фломастером или на бумажках от руки — но очень высокоуровневые и просто для обсуждения. Такие рисунки потом скорее всего выбрасываются. Главное проектирование происходит в процессе кодирования.
!!! Гнать проектировщиком-рисователей паганой метлой из индустрии!!! Когда уже люди мозгами дойдут, что не бывает хорошего кода по рисункам. Что не бывает хорошего программиста без того, чтобы он сам разбивал задачу и проектировал. Что говнокод рождается тогда, когда программисту раскладывают как что-то делать, а что, он не понимает. Что все рисунки убогие в сравнении с языком программирования. Что рисунки не дают понимания, какой говнокод из них получится. Что только код-говнокод показывает сам собой, какие в нем проблемы. Что проектируют не раз и навсегда, а рефакторят. Что программист — это человек умеющий читать и писать код, а рисунки — это удел САНТЕХНИКОВ в нашей индустрии. Сантехники захватили корыто и пытаются управлять программистами, но код не понимают и любят рисовать трубы и сливные бачки. Что тот, кто не понимает эволюционного проектирования (по коду), не умеет проектировать и наперед ВООБЩЕ. Что что что что. Таких утверждений можно на книгу набрать
TЗ, пожалуйста. Очень сомневаюсь, что автоматизацию договорного отдела сделать в одиночку трудно. 10 000 клиентов — это может быть много, но обрабатываться может «одним, но очень гордым запросом» ))
Вот я к ним и обращаюсь. Сразу в гнездо. Потому как на местах, где работаем, эта «оптимизация» захлестывает. И наверное надо их как-то обзывать, оскорблять и говорить, что их «профессионализм» — это «посредственность и бездарность». Потому что их понимание, как надо писать код, как раз основано на комплексах и взаимных упреках. Это психологическое что-то. Надо клин клином.
Кратко и более точно. Никогда (НИКОГДА) в проектировании не закладывают оптимальность. (Макконел, «Совершенный код»). Преждевременная оптимизация — наибольшее зло (Кнут).
Фаза оптимизации проекта находится в самом конце, после написания кода. И совсем не зря. Любая оптимизация, даже мелкая, в процессе получения первого кода — является преждевременной.
Дело в том, что цель оптимизации — найти глобальный максимум оптимизации. И это возможно, когда код написан полностью по DRY и YAGNI. Если нет дублирования кода и данных — оптимизация становится довольно тривиальной задачей. Когда код написан самым простым способом, он потенциально легко меняется в любом направлении. Не в смысле «настраивается», когда чрезмерную гибкость закладывают с помощью разных паттернов, а просто кода минимум и значит не вызывает больших проблем переписывание.
Когда код находится в таком состоянии, оптимизация происходит итерационно: замеры; определение самого узкого места; оптимизация. При этом стандартные методы оптимизации есть.
Если же человек оптимизировал заранее, то во-первых, код значительно хуже поддается изменениям, если вообще поддается. Во-вторых, картинка изменилась и он уже попал в какой-то бугорок — подъем стандартными методами оптимизации вряд ли даст глобальный максимум. В первом случае тоже нет гарантии, но во втором всё намного плачевнее.
Никто, никогда в здравом уме не проектирует, закладывая производительность. И как раз ТДД заставит написать код так, чтобы он был максимально простым. Это значит, что и оптимальность, если она нужна будет, вы сможете обеспечить по настоящему.
Главная ерунда, которая заставляет людей заранее оптимизировать — это отсутствие опыта в реальных проектах, требующих оптимальности. Если человек хоть раз делал замеры и оптимизировал, как надо, то вдруг появляется другое понимание. А именно: люди оптимизирующие заранее, пользуются «чутьем», которое основано на понимании «дорогой операции». Так вот, неграмотные студенты: дорогих операций нет самих по себе. Всегда есть совокупность факторов. И получается всегда некоторая сумма факторов. И вот, если некоторая операция выполняется день, а вторая секунду, то вторая может убить производительность, если выполняется миллионы раз, а первая 1 раз. День никак не критичен с потерей нескольких лет. Оптимизировать операцию, занимающую день — не смысла. А если эта оптимизация еще и вторую операцию и потом нельзя будет оптимизировать вторую — проект пропал.
Как только придет понимание, что «оптимизация — это процесс, основанный на замерах, а не написание оптимального кода» — вы сможете не париться по этому поводу, и если надо, писать настоящий оптимальный код. При этом, времени на оптимизацию будете тратить гораздо меньше. Потому как обычно, оптимизировать надо пару узких мест.
Макконел хорошую аналогию приводил: оптимизация заранее подобна экономии на спичках в то время, когда вы теряете миллионы.
В общем ТДД и оптимизация очень дружат на самом деле.
А желание оптимизировать всё и вся, выдает студентов (возможно вечных), при этом не объясняется логически. Просто люди убеждены, что это круто. И упрекают друг друга, если у кого-то код неоптимальный.
Это зависит от личной ответственности. Если вы пишете тесты ПОСЛЕ, то тогда часто они для галочки и пишутся. Потому как кажется, что код УЖЕ написан и работает.
Если же вы точно знаете требование заказчика, то выделить существенные вещи и написать тест вполне по силам программисту. Если же он не понимает назначение тестов и хочет, чтобы в глазах начальства и тесты были и просто проходили, то смысл эти тесты и писать тогда?
В любом случае вы правы, что тест не дает полную гарантию. Но это совершенно не значит, что тратить время на тесты бесполезно. Тесты при нормальном подходе дают высокую гарантию качества.
То же самое. Полных гарантий нету. Но без тестов, а с продумывание — гарантий нет вообще. Продумывание == выдумывание. Т.е. никакой объективности быть не может. Тесты дают возможность «не отрываться от земли», а писать ровно то, что нужно. Писать код, который не является чрезмерно гибким (привет астронавтам архитектуры). Писать код, который не является хардкодом (механический рефакторинг в ТДД заставляет выносить абстракции).
Мой опыт показывает — не будет быстрее и оптимальнее. Всегда при продумывании наперед проекты неимоверно затягивались, а код выдавал сюрпризы еще очень долго после завершения проекта. И наоборот. С ТДД написание кода шло совсем немного медленнее, но код становился неубиваемым и время на переписывание (при изменении требований) уменьшалось. И волшебным образом вдруг проекты перестали затягиваться по времени. А поддержка их становилась гораздо проще — практически багов не возникало потом.
Больше слухи ни о каких проектах не доходили.
Не только руководитель. Он же кем-то руководить должен. Нельзя взять и заставить изучить подчиненных.
Теоретики только рассказывают о Хаскеле, но не применяют их в массовых проектах, потому что сами в этих массовых проектах не очень-то участвуют. Чтобы пошло — нужно чтобы рядовые программисты параллельно изучали Хаскель. Также как для себя изучают Питон или F#.
И можно дать пинок в этом направлении — показать, как легко реализуются такие проекты на Хаскеле.