Не только люблю, но и всячески советую использовать этот подход. “Избегайте copy-paste любыми возможными способами!” – сколько раз я это слышал – столько-же раз умилялся. Если начать расспрашивать автора подобных заявлений об этих самых “всех возможных способах”, получите типичную жевачку про “паттерны проектирования” и инкапсуляцию.
Всё дело в том, что сразу писать программу паттернами проектирования не имеет никакого практического смысла.
Получите неоправданно сложную систему или выбросите всё к чертям и начнёте сначала. И инкапсулировать правильно, пока еще есть много неизвестных деталей, вы не сможете. Основым принципом при написании софта – да и вообще по жизни – у меня является YAGNI – You Aren't Gonna Need It. Когда я начинаю писать программу, я абсолютно не представляю, какой структурой классов закончится этот мой творческий акт через неделю или месяц.
Я три года писал свои программы в стиле test-driven development. По-честному. Сначала тест или сразу несколько тестов – потом код. Среднее покрытие кода в 75-80% – это то, что я мог гарантировать даже изначально. Это с учётом того, что кое-что тестами покрыть всё равно не получается, а кое-что будет покрыто на 100%. Я научился тестировать пользовательский интерфейс “из кода”, а не снаружи, и добился того, что мои программы после интеграции работали безошибочно; доработал под себя один хороший тестовый фреймворк в .NET, опубликовал несколько статей по test-driven development на blogs.gotdotnet.ru. И могу с уверенностью сказать, что именно эта методология сделала из меня хорошего дизайнера программного обеспечения. Первое, что я делал при знакомстве с новой средой разработки, это учился писать и выполнять тесты. И только потом брался за разработку продукта.
Я люблю test-driven development. И если вы новичок в разработке софта, я всячески рекомендую начать именно отсюда. Чтобы обосновать свою глубокую причастность к test-driven development и был написан предыдущий абзац. Но со временем я набил руку до такой степени, что перестал писать тесты где-то в отдельных файлах. Я стал писать тесты сразу в коде! Смысл test-driven development легко можно изложить в одном предложении: “Вы пишете тест таким образом, как вы хотите, чтобы потом ваш код можно было использовать”. То-же самое я стал делать прямо в своём коде.
Другими словами, я создавал какой-то новый класс, который должен был выполнять некоторую высокоуровневую задачу. Разумеется, что в таком случае нам понадабятся классы-помощники, или сервисы, если придерживаться англоязычной терминологии. Но их не было. Не важно. Это не мешало мне создавать экземпляры несуществующих типов и вызывать несуществующие методы и уже не где-то на бумаге, а прямо на клавиатуре создавать будущий публичный интерфейс сервисов!
Вы, естественно, можете удостовериться дополнительно, что ваша программа совершенно случайным образом не компилируется. Хоть для меня это более, чем очевидно, тем не менее, в test-driven development это отыгрывает очень важную роль. Тесты на проверку состояния мне стали не нужны. Благодаря простому и надёжному дизайну это легко просматривается уже из кода, а многие ситуации я могу просчитать и предугадать и в голове. Поэтому никакого неудобства от отсутствия проверки на состояния я не испытываю. В крайнем случае я делаю вывод в консоль и очень редко ставлю точку останова. Тем не менее, так я достиг качества кода, сравнимое с тем, что я получал при test-driven development, но избавился от написания отдельных тестов, т.к. сам код как-бы являлся тестом для самого себя. Вы должны работать только над тем кодом, который впоследствии окажется вкомпилированным в исполняемый файл, который вы отдаёте клиенту.
N.B. Я по совместительству являюсь еще и сейлзом проектов. И еще ни один клиент не раскрыл рот, когда я ему заявлял, что я ему гарантирую покрытие 90% для функционального кода. Я встречал разные эмоции – от игнорирования до равнодушия. Думаю, вы меня понимаете. Платят за конечный качественный результат. Я рассказываю, как достичь этого, не делая двойной или даже четверной работы. Вы можете как угодно обосновывать стоимость проекта, но вы должны оставаться конкурентноспособными, не жить в проголодь и работать по своему расчётному рейту или даже выше.
Только теперь, когда у вас есть план того, как должны выглядеть помощники, вы начинаете их реализацию. Реализацию, естественно, для начала не полноценную, а только так, чтобы программа компилировалась. Возвращаете указатель – возвращайте пока nil, а не “хороший” объект. Если функция должна быть void – объявите ее и все. Просто доведите код до состояния Build succeeded.
Главное для нас – это публичный интерфейс. Никакие внутренние детали нас касаться не должны. Они могут быть неаккуратными, фейковыми, быть обыкновенными заглушками или ужасно тормозить. Если где-то в каком-то месте программы вы чувствуете, что нужно скопи-пастить – берите и копи-пастите. Никакой инкапсуляцией на этом этапе заниматься противопоказано! Вы насоздаёте мелких классов и получите головную боль в итоге. Копи-пастите и копи-пастите, похожие куски кода в разных классах или методах доводите до идентичности. Возведите этот принцип в абсолют. Именно он позволяет мне строить элегантные объектно-ориентированные системы. Выполняйте эту процедуру столько, сколько необходимо для того, чтобы у вас в голове созрел дизайн следующего сервисного класса.
Еще одним бонусом, который вы получаете при использовании test-driven development – это возможность безболезненного рефакторинга. В нашем случае рефакторинг – это превращение идентичных кусков в отдельные классы. Да, так просто. Никаких там книжек толстенных по рефакторингу вам читать не нужно, чтобы добиться качественного кода. Просто запомните: рефакторинг – это очень просто. Это перемещение и объединение кусков кода. Правильно и без ошибок это гораздо быстрее сделать без тестов, чем с тестами. Ваш рефакторинг – это не на пол-дня, как у некоторых происходит. Вы пишете программу мелкими перебежками. Любая операция – простая. Вырезать из одного места, перенести в другое, удалить дубликаты, заменить на обращения к сервису. Любой класс – простой и осягаемый глазом, все связи и зависимости легко просматриваются. При таком подходе и голове на плечах отсутствие тестов сбросит с вас оковы (а это всё-таки оковы, кто-бы что не говорил) и вы сможете лепить код, как из глины, не озираясь на какие-то вторичные факторы и не нанося ущерба стабильности.
Я всегда думал, что книжки вроде “Паттерны проектирования” написаны для тех, кто не умеет писать программы. Ну согласитесь-же, что если вы просто как любой нормальный мужчина можете без труда, когда заблагорассудиться, заводить отношения с девушками, то вы не будете заниматься вот этой вот херней с пикапами, эриксоновскими гипнозами и рутинами. Паттерны – это рутины, для тех, кто не умеет программировать.
У хороших-же программистов паттерны выскакивают прямо из-под клавиатуры. Сами по себе. Сначала идёт код, потом паттерны, а не наоборот. Вы просто работаете в тональности “наделать как можно больше похожих кусков – и вытащить функционал в отдельный класс”. И все паттерны придут к вам сами по себе.
Это всё, что вам нужно знать о test-driven development и agile вообще, если вдруг вы захотите этим действительно заниматься и зарабатывать деньги, а не вступать в академические флеймы на rsdn.ru.
N.B. Я закончил свою форумную карьеру после того, как мой счётчик сообщений на gotdotnet.ru перевалил за 2500. После этого мне стало скучно участвовать в форумах и я стал писать статьи или вообще заниматься несвязанными с компьютером вещами. Приоритеты меняются со временем, но это позволило мне выработать свой взгляд на многие явления в жизни.
Всё остальное к вам придёт с практикой. Существует очень много вещей, которые нельзя изложить на бумаге, это нужно прочувствовать, осознать. Тем не менее, сейчас для закрепления материала, мы с вами напишем что-то в моём стиле. Под iPhone, т.к. это то, с чем я сейчас работаю больше всего.
(Продолжение в следующих сериях.)
комментарии (172)
А покуда все так и делают — то вроде всё нормально. Но жалуются заказчики, что никто ничего толком делать не умеет, жалуются разработчики, что заказчики не знают чего хотят. Но что поделаешь — отрасль такая. Ведь для небольших систем проектирование как этап не нужно ;)
Смысл в том, что при использовании рефакторинга изменяется роль предварительного проектирования. Если не рассчитывать на рефакторинг, то ощущается необходимость как можно лучше провести предварительное проектирование. Возникает чувство, что любые изменения проекта в будущем, если они потребуются, окажутся слишком дорогостоящими. Поэтому в предварительное проектирование вкладывается больше времени и усилий — во избежание таких изменений впоследствии.
С применением рефакторинга акценты смещаются. Предварительное проектирование сохраняется, но теперь оно не имеет целью найти единственно правильное решение. Все, что от него требуется — это найти приемлемое решение. По мере реализации решения, с углублением понимания задачи становится ясно, что наилучшее решение отличается от того, которое было принято первоначально. Но в этом нет ничего страшного, если в процессе участвует рефакторинг, потому что модификация не обходится слишком дорого.
Очевидно, что это произойдет раньше, чем если бы сначала все было детально запроектировано, потом реализовано, потом оттестировано и было бы показано заказчику, который внес бы небольшие изменения, которые бы поменяли архитектуру и т. д.
Также очевидно, что это экономит время, деньги и нервы как заказчика, так и разработчика.
Что тут плохого?
В моём понимании прототип — часть проектирования, поэтому выбор «прототип или проектирование» вообще не имеет смысла.
А понятие «не такой уж» и «такой уж» слишком субъективны, чтобы можно было что-то возразить. Если из-за плохого проектирования время разработки увеличилось на 2 дня — это много или мало? А на 1000 проектов по 2 дня?
В моем понимании проектирование — выработка свойств системы на основе анализа постановки задачи.
Этот самый процесс может быть выделен в отдельный этап (как, например, в классическом «водопаде»), а может быть и не выделен, а происходить регулярно, параллельно с процессом разработки (как, например, в случае agile-методологий).
Ну, а если время разработки увеличилось на 2 дня, но сократился месяц «хорошего» проектирования? А на 1000 проектов? В том то и дело, что все субъективно.
BTW, замечу (на всякий случай) что разговор идет не о пользе/вреде проектирования вообще, а о целесообразности выделения детального проектирования системы в отдельный этап на небольших (в пределах 2-3 человекомесяцев) проектах.
Истинная правда!!! Даже не знаю, что такое паттерны программирования, хотя нет, знаю синглтон :) Но дело не в этом. Помню, когда мой коллега спрашивал меня о паттернах, я просто пожимал плечами, а когда он начал описывать какие-то из них, я сразу узнавал какие-то подходы и понимал о чем речь.
Очень верное сравнение с девушками. Паттерны описаны для неумеющих программировать. Ибо, логику не пропьешь. Программа должна быть изначально простой, что бы компилироваться в мозгу. А дальше можно заворачивать всё в любые обертки и т.п.
Огромный респект автору. Жду от Вас статей по iPhone программингу.
Паттерны написаны для того, чтобы не изобретать велосипед. Если программист с мозгами, то он может сразу понять при написании класса какой паттерн ему тут может пригодиться. Тот, кто их не знает совсем будет писать какой-то свой велосипед, и, возможно, как вы говорите придёт к тому же паттерну. Но это лишнее время.
Я, например, не читал ничего о паттернах, но за почти 15 лет программирования я многими из них пользовался, т.к. они «сами пришли» в голову и оказались лучшим решением той, или иной задачи.
Вы правильно делаете, что доверяете себе, а не тупо выбираете паттерн из книжки и пытаетесь его всунуть в код, это и есть, насколько я знаю, традиционный подход к использованию паттернов. Наверное, все, кто читает книжки про паттерны, понимают, что половину и так знали до этого. Но про них просто полезно почитать, чтобы свой «словарь» расширить, да и может это знание помочь избежать каких-нибудь неочевидных граблей.
Во-вторых, общая терминология облегчает общение с другими. Можно не говорить «это класс X реализует все методы интерфейса Y, но они ничего не делают», а написать «X — это NullObject для Y»
если код написан с использованием паттернов и общепринятых подходов, то его легко читать.
Не стоит гордится тем, что вы «понимали о чём речь». ясное дело, что вы понимали — все паттерны очень просты и понятны. на то они и шаблонны.
знание паттернов, uml, мат. терминов… и прочего-прочего очень облегчает общение. особенно с новыми людьми.
через год приходит четвертый и его надо ввести в курс дела.
— а это что за хуй тут нарисован?
— ды эт мы с пацанами… ну в общем это…
— а почему тут 3 класса в кружочек а один в квадрат?
— потом что этот класс особенный он…
— такс… тут 2 класса в квадрате… они типа того «особенного»?
— эм… нет… тут не так… тут имелось ввиду… м… Мишка приедет из отпуска — у него с прошу.
— а что делает этот кусок кода?
— он делает…
— а этот?
— м… тоже самое.
— а почему 2 одинаковые задачи делают 2 разных куска кода?
— ну я сперва написал этот… а потом я с девушкой со своей поссорился… и как-то в другой раз решил по другому написать… ну это хенрь… тут ещё есть в другом месте другая реализация этого же алгоритма — вот там классно!.. только я не помню какая из 3х сейчас используется…
— я тут у вас ошибку нашёл. в процедуре…
— плохо… очень плохо…
— ды всё ок. я исправил…
— плохо… у нас в 14 местах этот код используется… чёрт… значит и там ошибки.
— не страшно, скопипастим туда исправленный вариант.
— эм… в некоторых из этих 14 изменения внес небольшие… где-то на бумажке было записано в какие… или на доске… давай-ка ты лучше пока верни обратно а мы потом перепишем заново все…
ещё раз повторюсь, что вы неверно понимаете предназначение паттернов.
паттерны нужны для того чтобы научить вас как делать, а чтобы вы делали так, как все остальные.
паттерны нужны не для того чтобы научить вас как делать, а чтобы вы делали так как все остальные.
А изо всех сил сводить задачу к набору паттернов (чтоб все стандартно было) не стоит.
разумеется, начинающих программистов паттерны я учат как делать… а те кто уже много пописал и сами могут легко придумать решение. вот автор поста, к примеру.
но когда сталкиваешься одной и той же задачей несколько раз… нельзя её делать так, как вздумалось сегодня. если взять за правило использование паттернов то вы по названию паттерна сразу понимаете что делает код.
не спорю, можно и без них… но это всё равно что объяснить что-то собеседнику не набором наспех сгенереных фраз, а привести известную цитату, пословицу.
Вместо копи-пасте предпочитаю код, требующий повторения в другом месте, завернуть в функцию или обьект — так меньше приходиться двигать пальцами и мышкой, а заодно очевидны входы и выходы.
Про код в голове — я пишу в месяц дофига кода, и просто не помню деталей что были две недели назад.
Если же «рефакторим здесь и сейчас» то копи-паст в принципе не нужен. Ну то есть совсем. Потому что кусок кода обернуть — одна кнопка, вставить созданный класс или функцию в другом месте — другая. Ни копи ни паст тут рядом не лежал.
Давно уже придуманы принципы, следуя которым нельзя ухудшить архитектуру или «упустить шанс» её улучшить. Описаны в разных книгах, больше всего, по-моему, у МакКоннелла в «Совершенном коде».
Вот это и есть весь смысл TDD? Смысл TDD в написании тестов определённым образом? Ну нет. Эта фраза совсем не означает, что вы разбираетесь в TDD (сам факт чего я не отрицаю).
нет не упущу. Я вообще стараюсь планировать общую архитектуру заранее и при больших изменениях приходиться ее пересматривать. А то что вылезает по мере имплементации — так фишечки, иногда вредные. Следовать же тем стихийным озарениям в локальном контексте — верный путь к потере целостности приложения.
Для меня же понятная и дешевая возможность изменить — деньги за меньшее время. Практика показала что время потраченное на обдумывание заранее, на общий рефакторинг в случае крупных изменений — окупаются в несколько раз.
code.google.com/p/s7ratingview/
code.google.com/p/s7graphview/
Наслаждайтесь!
Видимо тут нужен реально большой опыт, чтобы в голове продумывать то, как вы хотите использовать будущий класс. У меня из-за этого только каша получалась и приходилось возвращаться к бумаге =)
Вообще говоря, даже создатели паттернов говорили о том, что концепция витала в воздухе. Плюс была дискуссия, что любой приличный программист сам доходит до таких вещей со временем, когда появляется надобность.
Другое дело, что программистам надо как-то общаться; фразы типа «ну тут типа ссылка на другой класс, у которого среди как бы наследников...» удобно, черт возьми, заменять на «Мост». Или Адаптер. Или Фасад. Или Синглтон. Или Завод. Хитросплетение классов превращается в одно простое слово. Плюс можно обмениваться опытом при различных реализациях шаблонов проектирования. Ну и прочие радости, которые привносит в жизнь умение общаться в пределах очень специальной области.
А то тут тролли кругом… такого понапишут.
В этом что-то есть, конечно. Но не слишком много.
И уж ТЕМ БОЛЕЕ странным звучит утверждение, что паттерны — это для стыковки. Мне казалось, что это интерфейсы между подсистемами для стыковки.
вы действительно с работой напарников общаетесь исключительно через XML-RPC? Прям все проекты реализуются в распределенной среде? Или теперь для iPhone так пишут?
Это, несомненно, правильно. Но это если сравнивать с этапом разработки по TDD. А если учитывать и этап поддержки, то программисты, которые занимаются поддержкой, скажут автору огромное «спасибо» за код с копипастом и без тестов. Даже если не задумываться о поддержке, если вдруг какому-то другому человеку понадобится внести изменения в код, написанный автором, у него (или у проекта) возникнут проблемы.
Даже если не обращать внимание на то, что одна фраза противоречит другой, паттерны — это не та штука, которую «выучил и начал использовать». Формализация паттернов служит, в основном, таким целям:
* Увидеть как определённые типы механизмов в ООП реализуются наилучшим образом, какие есть в этих механизмах подводные камни, плюсы и минусы.
* Выработать общую терминологию, благодаря которой проектирование идёт быстрее. Это позволяет говорить друг другу «тут можно использовать композит» вместо «можно сделать такую функцию, в которую передаём объект того же базового класса, что класс содержащий функцию чтобы он прицепился к контейнеру и ...»
Это касается только своего собственного кода, написанного меньше недели назад, а если точнее — то только разработки с параллельным рефакторингом. Если нужно отрефакторить чужой код, написанный с применением других методологий (или вообще без оных), разными людьми в разное время — без тестов можно только пожелать побольше удачи.
В общем, если вы разрабатываете программы сами, без команды, не собираетесь заниматься их поддержкой в дальнейшем (и не страшно испортить карму проклятиями от тех, кто поддержкой заниматься таки будет), отлично умеете проектировать и знаете правильные принципы — то описанный подход для вас. Только непонятно, почему вы всё ещё разрабатываете программы сами, без команды и разрабатываете такие программы, которые не планируют развиваться :)
Рефакторинг, который инструмент может сделать формально и 100% точно, думаю, можно делать без тестов.
Вообще требует измерения — сколько потрачено время на написания тестов сколько на ручное тестирование и исправление ошибок.
А измерения уже много раз проводились. Западные книгописатели любят на всякие разные измерения ссылаться. Только измерения проводились в одних условиях, а проект делается в других, поэтому тут поможет только здравый смысл и опыт.
Докажите, пожалуйста, если не трудно
Вы утверждаете, что если я перечитаю, то пойму, что копипаст выбрасывается. А теперь утверждаете, что в тексте этого нет, нужно ждать следующую часть. Так зачем же тогда было перечитывать? Тьфу…
> куски кода в разных классах или методах доводите до идентичности… Выполняйте эту процедуру столько, сколько необходимо для того, чтобы у вас в голове созрел дизайн следующего сервисного класса.
Но все такие разговоры (если опять сослаться на Макконнела) проиходят лишь оттого, что софтверная инженерия ещё очень молода. Макконнел (для меня очень даже авторитет) иногда доходит до крайностей, предлагая получать лицензию разработчика — как врачу или, скажем, мостостроителю. И ваши доводы будут звучать совсем забавно, если мы приведём аналогию с более устоявшейся областью, с тем же строительством.
«Кирпичи», «панели», «балки» — это всё для лузеров! Нормальный архитектор сам придумывает то, что ему надо.
— А вот смотри, я изобрёл твёрдый параллелепипед, из него можно стену сложить, а то и всю собачью будку!
— Дак это же паттерн «кирпич»!
— Причём тут паттерн? Я сам придумал, и так удобнее!
Мне кажется, что все-таки идея стандартизации компонентов очень правильна, и критиковать ее как-то… глупо что ли.
Также не совсем понятен смысл всего текста: то расписываются прелести TDD (и далее следует призыв отказаться от него), то рассказывается о способе разработки архитектуры «сверху вниз» (который тоже не нов).
Паттерны проектирования нужны не для того, чтоб при решении задачи перерывать их список и пытаться найти наиболее подходящую комбинацию. Нужны они только в плане обучения (как у художников — гипсовые фигуры), их надо знать (не по названию, а по смыслу), и где надо — не изобретать велосипед.
Отказ от тдд и сохранение возможности безболезненного рефакторинга возможно, если рефакторингом занимается человек, который проектировал систему (ну или минимум знает ее досконально).
BTW, у вас во флешка на 7touchgroup.com/ баг (?) — попробуйте попереводить мышку с about на services и обратно.
эта фраза рассматривается большинством нормальных программистов как
Люблю хуячить топором, потому что помогает делать элегантные миниатюрные фигурки
под копипастом обычно понимаются одинаковые или почти одинаковые куски кода.
Очень часто (в разных областях — % разный) бывает так, что 15 строк абстрактного не нужны и хватит 10 строк «тупого». Вот тут-то и кроется выгода. Наш код в итоге проще (а значит его проще поддерживать втч), а то, для чего нужны дополнительные уровни абстракции — эти уровни абстракции получают.
Про строчки — это не буквально, конечно. Можно вместо «строчки» подставить что-нибудь в духе «усилия», или еще что-то.
вот я написал 10 строчек глупого кода, написал еще 10 глупого кода, но все еще не понял, как лучше сделать умный. Я могу сделать ЧТО-ТО, что устранит дублирование кода, но это не устранит причину дублирования, и в 3й раз мне придется опять писать глупый код. Поэтому я не устраняю дублирование и пишу 3й раз 10 строчек глупого кода, которые уже помогают мне понять, как сделать код умным. Если с такой ситуацией не сталкивались, — вы очень умный, вам очень везет, или архитектурные проблемы, встающие перед вами, — несложные.
стараться делать одинаковые куски кода чтобы потом их свернуть в 1? давайте сразу напишем один?
у меня за всю жизнь было 1-2 раза что 2 куска кода становились всё больше и больше похожими и я их схлопывал в один. и произошло это потому что я изначально поленился такой вариант предусмотреть.
одинаковые (в будущем) куски кода видны сразу. на самых ранних этапах проектирования можно сразу прикинуть где и что будет повторяться…
а если у вас 2 совершенно разных класса… и у них какие-то 2 процедуры очень похожи друг на друга, но логический не связаны. то тут не нужно ни копипастить, ни пытаться выделить в один.
Насчет предусмотреть. Идея-то вот в чем. Можно предусмотреть, что код будет похож, и вынести его в какой-то отдельный блок. А можно предусмотреть, что будет похож, и попробовать на практике, чем именно он будет отличаться, чтобы потом вынести в отдельный блок уже на более высоком уровне абстракции.
Ну это я уже 3й раз одно и то же пишу чего-то :)
P.S. Если честно, не понял причины такого накала страстей тут в комментариях, чего все так грязью поливают друг на друга)
Спорно тут то, что автор, не делая оговорок о масштабах и особенностях проектов, к которым это применимо, и не сообщая о возможных подводных камнях, призывает следовать данной методике. А самый существенный минус у нее в данном варианте — сложность сопровождения и модификации полученного кода.
— отказываемся от написания юнит-тестов
— разрабатываем сверху вниз, продумывая архитектуру на этапе написания кода
— в качестве тестов на этапе продумывания интерфейса выступает компилятор/линкер
— в процессе разработки приложения не заморачиваемся архитектурными изысками, и пишем «как пишется», по возможности стараясь реализовывать похожие алгоритмы одинаково.
— при удобном случае одинаковые куски оборачиваем в классы/методы
— далее тесты становятся не нужны, т.к. мы помним архитектуру системы, а все ее компоненты реализуют элементарные операции, в тестировании не нуждающиеся.
Я правильно понял? Если так, то тут минимум забыли еще один важный этап — сопровождение, на котором написанные тесты и документированная архитектура ой как пригодятся.
Масштабы проекта тоже важны, т.к. что хорошо для пары-тройки человекомесяцов, не очень подходит для пяти человеко-лет и сильным распараллеливанием работ. Объяснять «почему» нужно?
Тесты — да, с ними надо будет разбираться. Но зато они _моментально_ отвечают на вопрос: а если я вот этот метод заставлю работать несколько иначе, что у нас сломается? А это очень ценно на этапе сопровождения.
Хотя еще раз повторюсь, на отдельных задачах и даже маленьких проектах на одного-двух человек без сопровождения и без проблем с кадрами такой подход вполне оправдывает себя.
Вот только не надо мне говорить, что другой девелопер должен эмпирическим методом проискать такой же код по всему проекту, т.к. на практике даже не понятно, что именно вообще искать надо (например когда фикс бага затрагивает несколько мест).
Я работаю в Direct EDI, наша система документооборота разрабатывается с 2002го года и один из документов для разных клиентов (упрощаю) делался именно копированием кода. Тогда никто особо не задумывался. В результате через 7 лет у нас есть порядка 400 вариаций на тему, которые какбы и похожи, но для каждого клиента немного свои. На суппорт этой каши уходит нереально много часов, и соответственно денег. Недавно был прорыв — запустили один модуль, на который будем постепенно переводить все эти копии с кастомизацией не на уровне кода, а на уровне файлов настроек. Суппорт настроечных файлов обходится в 10-20 раз меньше по времени. То же было бы и в случае наследования кода.
а как там это будет работать потом… и кто это будет дописывать/разгребать/отлаживать… это всё пустое, и не стоит даже забивать голову такой ерундой.
вы описываете идеальный ход событий. типа:
— как написать программу без ошибок?
— написать 1 строчку без ошибок, прибавить к ней ещё одну строчку без ошибок… повторить несколько тысяч раз
1 — к вам пришел новый программист
2 — от вас ушёл старый, не доделав до конца свою часть
вы написали пост… ну просто классика троллинга. и какого эффекта вы ожидали?
З.Ы.
и где вы у меня брань нашли, кстати? О_о
там только один безобидный «хуй», описывающий фигуру составленную из овала и двух маленьких кружков.
Более того, есть проекты, где не работает отказ от написания юнит-тестов, т.к. опять же есть поддержка (которой занимаются совсем другие люди обычно).
И если в случае (допустим) с игрушкой под консоли/мобильники жизненный цикл приложения заканчивается с печатью диска/отправкой операторам, то в корпоративных приложениях печать диска и внедрение решения — это далекая от завершения модификации продукта стадия.
Т. е. зачастую софт недостаточно написать и оттестировать, а его необходимо модифицировать множество раз на протяжении длительного времени (и силами разных разработчиков). Таким образом, один и тот же компонент будут изменять и доводить до совершенства разные люди и неограниченное количество раз.
А если компонент используется десятком других компонентов, то при его модификации (по вашей методике, т.е. забив на написание тестов) придется детально изучать работу этих компонентов (а то и большего количества, т.к. каждый из них тоже может использоваться другими). А вот если есть тесты — то все сильно проще.
Таким образом, описанный метод подходит при разработке сравнительно небольших систем, которые либо разрабатываются одним человеком, либо хорошо бьются на сравнительно небольшие куски, взаимодействие между которыми очевидно, и каждый такой кусок разрабатывается отдельным человеком (ну, например, графика, звук, физика, игровая механика, инструментарий в случае игрушек), не имеющих длительного периода сопровождения. Например, игры, приложения для мобильных платформ, небольшие сайты (с натягом, т.к. их сопровождать хотят обычно), ну и другие подобные.
Это вообще шикарно, нужно поделится с сотрудниками. Зачем вообще книги!? Сжечь всё на костре, доверится первобытным инстинктам и писать крутой спагетти код с душком, так?
А вы не верьте. Проверяйте. По google.com можете eisernWolf пробить. Так обо мне можно узнать всё, включая номер мобильного телефона и адрес по прописке. :)
Именно посредством мыслей статьи и пишутся. А сформированным тут ничего пока быть не может. Это всего лишь первая статьи из нескольких.
жуть…
Кажется код одного из ваших последователей я рефакторю уже второй месяц. Убил бы…
Сбивают с толку:
а) заголовок (copy-paste традиционно имеет несколько другой смысл, нежели описываемый подход)
б) лирика, не имеющая отношения к основной мысли (история взаимоотношений с TDD тут несколько притянута)
в) недостаточно четко выраженная сама основная мысль (не сделан упор на то, как именно используется копипаста).
Как то в комментарии выше в двух строках понятней у вас получилось, может, и не нужно больше строк? ;-)
А мы пока будем читать самоорганизующийся (со временем) поток сознания. Ибо такие вещи как «композиция», «план», «дидактика» автору претят.
Статья написана нечетко и ее понимают только те, кому эта статья в общем и не нужна :)
А насчет копипасты, вы разве себя никогда не проклинали за неё в те моменты, когда приходилось в каждом из копипащенных кусков что либо? Я вот из за этого боюсь копипасты и применяю её только в каких то тестовых кусках, которые всёравно ждёт судьба быть выпилеными. И ещё что касается усложнения структуры, лучше несколько маленьких, но простых и понятных блоков, чем один большой монолит, умеющий всё. Поэтому часто казалось бы увеличение числа обьектов ведет к более понятной и логичной структуре, хотя логика иногда пытается обратное доказать, мол чем больше обьектов тем сложнее в них разобраться. Да вот ещё, хорошими программистами сразу же не становятся, и для обучения данный подход прямо скажем опасен, ну не будут выскакивать из под клавиатуры паттерны программирования, для этого нужно многое осознать и понять.
Но конечно если ты в меру опытен и пишешь что-то для себя, то можно и поэкспериментировать, вдруг получится разработать нечто новое и хорошее
Могу только пожелать вам не жить в домах, построенных без проекта, не ездить в авто, сделанных без проекта и вообще пользоваться результатами труда средневековых ремесленников, а не профи. Зато у них акт творения, а не какие-то там скучные расчёты сопромата и диаграммки. Акт творения — наше всё!
Всё, после этого читать не стал, ибо понял, что автор простой кодер без навыков проектирования. Сам лично не сажусь даже писать код если не представляю структуру и какие классы, библиотеки и связи между ними у меня будут.
И ты можешь сказать другому программисту — вот здесь такой паттерн
С новыми же языками программирования смысл многих паттернов отпадает, потому что они встроены в язык
Другие паттерны вообще специфические и редко используются
Рефакторинг проводить легче, если знать паттерны. А с тем, что паттерны использовать с самого большого смысла начала нет — согласен на 100%
Только вот житель индейского племени тоже умеет общатся с противоположным полом, на своих индейских понятиях.
И по приезду в цивилизованную страну он не возымеет успеха у слабого пола.
А если его местный, цевелезованный друг предложит познакомится с карсивой дамой, тот может не правильно понять и доставит эту даму ему в зажаренном виде.
Такой подход жив, пока вы находитесь в однородной среде, подбных вам людей, с одинаковой культурой.
И во всём нужно чувство меры. Вы не будете пол года проектировать, делать сложные инженерные расчёты, при строительстве будки или сарая (хотя для сарая скорее всего план накидаете).
Еще чаще приходится комбинировать оба подхода.
Только не совсем ясно, почему именно копипаст стал «лицом» идеи проектирования снизу вверх.
Да, думаю рановато мне писать что-то конструктивное, раз я не разбираюсь в элементарнейших вещах, таких как всемогущество копипаста.
И оставьте уже этот TDD и слова по типу «вы поймете, что я прав, когда у вас будет много опыта», «я практикую TDD уже три года» и т.д., потому как подобное высокомерие не имеет ничего общего с нормальной разработкой :)
Насчёт больших корпоративных махин — ничего, что я пишу в разрезе разработки под iPhone? Какая тут к чёрту корпоративная махина? Я не люблю универсализма и не собираюсь рассматривать какие-то абстрактные случаи. Есть проблема — вот вам решение. Причём тут корпоративные махины? Я пас…
> Насчёт больших корпоративных махин — ничего, что я пишу в разрезе разработки под iPhone?
Ничего, что iPhone упомянут в последним предложении данной статьи? В своих собственных программах, или программах написанных на заказ для маленьких заказчиков вы вправе писать как угодно, однако не стоит предлагать такой метод, как аксиому.
Я тоже так думал. Но решил написать статью, чтобы проверить. Ситуация оказалась противоположной.
>>По поводу высокомерия, посчитайте количество я в вашем рассказе :)
Высокомерие — это не то, на какое место вы ставите себя. Это то, на какое место вы ставите других людей.
>>Ничего, что iPhone упомянут в последним предложении данной статьи?
Статья и сейчас, и всегда находилась в блоге про iPhone. Сделано это было не случайно.
>>не стоит предлагать такой метод, как аксиому.
На поверхности говорите лежит? То, про что я рассказал — это всего лишь одна из практик test-driven development, описанная в книге Кента Бека. :) Там где-то ближе к концу книжки, посмотрите. Но при этом я изложил свой взгляд на вещи, который сложился не в результате заучивания большого количества книг, но в результате большого количества практики. Именно поэтому, когда вы чувствуете код, книги по паттернам можно отложить, а рефакторинг из чего-то научного превращается в повседневное и естественное. Но об этом статья. А вы говорите — «на поверхности». :) Не пришлось бы мне тогда еще самому себе критику в комментах писать, чтобы разжевать для доходчивости.
Да, и у хороших конструкторов механические транспортные средства с двумя колесами выскакивают сами по себе…