войти зарегистрироваться

Почему я люблю copy-paste при написании кода?

Не только люблю, но и всячески советую использовать этот подход. “Избегайте 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)

  • интересный взгляд, но при чем тут макос и айфон?
    • В следующих частях будет с уклоном на дизайн кода в Interface Builder. Тут уже просили. И я хотел-бы, чтобы вся «подшивка» была в одном блоге.
      • Это интересный вопрос. Ждем.
    • Там же где и взрывающийся вертолет…
      • У меня возник в точности такой же вопрос… По существу дела, я согласен, что в случае сложных интерфейсов практически невозможно построить архитектуру с нуля и не изменять ее походу дальнейшей разработки, так как меняются требования, наборы фич и тд… Приходится придумывать обходы или дорабатывать интерфейс, что довольно проблематично в смысле обратной совместимости.
  • Проектирование до начала написание нынче не в моде похоже…
    • Одно другому не мешает. В комменте ниже я очень поддерживаю автора, но тоже могу 2 недели ходить обмозговывать архитектуру без написания единой строчки кода…
    • Ну, проектирование, как самостоятельный этап, не для всякой задачи нужно — относительно маленькую и простую систему можно проектировать по ходу дела, и там описанный автором подход вполне себе применим (да и похожим образом такие проекты и делаются в большинстве случаев). И если развития продукта не планируется, и никто из команды не заболеет и не уволится, то ничего страшного не будет.
      • Нужно — почти для всякой, необходимо — не для всех. На маленьких проектах можно не заметить нужности проектирования. Ну, подумаешь, вылезла вещь, которую не спроектировали и теперь нужно переписывать часть системы. Ну, посидел программист пару лишних дней над проектом — ничего страшного, вроде.

        А покуда все так и делают — то вроде всё нормально. Но жалуются заказчики, что никто ничего толком делать не умеет, жалуются разработчики, что заказчики не знают чего хотят. Но что поделаешь — отрасль такая. Ведь для небольших систем проектирование как этап не нужно ;)
        • нравится мне, что по этому поводу Фаулер пишет:

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

          С применением рефакторинга акценты смещаются. Предварительное проектирование сохраняется, но теперь оно не имеет целью найти единственно правильное решение. Все, что от него требуется — это найти приемлемое решение. По мере реализации решения, с углублением понимания задачи становится ясно, что наилучшее решение отличается от того, которое было принято первоначально. Но в этом нет ничего страшного, если в процессе участвует рефакторинг, потому что модификация не обходится слишком дорого.
          • Уже лет 20 все кто ни попадя пишет, что не нужно заранее проектировать много деталей реализации. Фаулер в этом совсем не исключение. Есть много способов уменьшить стоимость модификаций помимо рефакторинга. Цитата правильная, но почему именно в ответ на мой комментарий? Я про рефакторинг ничего не писал, а про проектирование в этой цитате нет новых идей.
            • это было скорее в ответ на всю ветку, а не на конкретный комментарий.
        • Ну, есть проекты, в которых изменение архитектуры — не такой уж затратный момент. В маленьких проектах даже лучше делать сразу некий прототип с минимальным проектированием (можно и по ходу разработки), с которым у заказчика будет возможность поиграться и, возможно, изменить требования, которые уже в свою очередь могут серьезно поменять получившуюся архитектуру.

          Очевидно, что это произойдет раньше, чем если бы сначала все было детально запроектировано, потом реализовано, потом оттестировано и было бы показано заказчику, который внес бы небольшие изменения, которые бы поменяли архитектуру и т. д.

          Также очевидно, что это экономит время, деньги и нервы как заказчика, так и разработчика.

          Что тут плохого?
          • Не понятно, что вы имеете в виду под проектированием.

            В моём понимании прототип — часть проектирования, поэтому выбор «прототип или проектирование» вообще не имеет смысла.

            А понятие «не такой уж» и «такой уж» слишком субъективны, чтобы можно было что-то возразить. Если из-за плохого проектирования время разработки увеличилось на 2 дня — это много или мало? А на 1000 проектов по 2 дня?
            • Не понятно, что вы имеете в виду под проектированием. В моём понимании прототип — часть проектирования, поэтому выбор «прототип или проектирование» вообще не имеет смысла.

              В моем понимании проектирование — выработка свойств системы на основе анализа постановки задачи.

              Этот самый процесс может быть выделен в отдельный этап (как, например, в классическом «водопаде»), а может быть и не выделен, а происходить регулярно, параллельно с процессом разработки (как, например, в случае agile-методологий).

              А понятие «не такой уж» и «такой уж» слишком субъективны, чтобы можно было что-то возразить. Если из-за плохого проектирования время разработки увеличилось на 2 дня — это много или мало? А на 1000 проектов по 2 дня?

              Ну, а если время разработки увеличилось на 2 дня, но сократился месяц «хорошего» проектирования? А на 1000 проектов? В том то и дело, что все субъективно.

              BTW, замечу (на всякий случай) что разговор идет не о пользе/вреде проектирования вообще, а о целесообразности выделения детального проектирования системы в отдельный этап на небольших (в пределах 2-3 человекомесяцев) проектах.
  • >> У хороших-же программистов паттерны выскакивают прямо из-под клавиатуры. Сами по себе. Сначала идёт код, потом паттерны, а не наоборот. Вы просто работаете в тональности “наделать как можно больше похожих кусков – и вытащить функционал в отдельный класс”. И все паттерны придут к вам сами по себе.

    Истинная правда!!! Даже не знаю, что такое паттерны программирования, хотя нет, знаю синглтон :) Но дело не в этом. Помню, когда мой коллега спрашивал меня о паттернах, я просто пожимал плечами, а когда он начал описывать какие-то из них, я сразу узнавал какие-то подходы и понимал о чем речь.

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

    Огромный респект автору. Жду от Вас статей по iPhone программингу.
    • >Паттерны описаны для неумеющих программировать.
      Паттерны написаны для того, чтобы не изобретать велосипед. Если программист с мозгами, то он может сразу понять при написании класса какой паттерн ему тут может пригодиться. Тот, кто их не знает совсем будет писать какой-то свой велосипед, и, возможно, как вы говорите придёт к тому же паттерну. Но это лишнее время.
      • Я говорю о том, что можно пользоваться инструментом, даже не зная, как он называется.
        Я, например, не читал ничего о паттернах, но за почти 15 лет программирования я многими из них пользовался, т.к. они «сами пришли» в голову и оказались лучшим решением той, или иной задачи.
        • А если бы вы прочитали — было бы хуже?
          • Зачем читать то, что уже знаешь? Никакая книга не заменит познания на собственном опыте.
            • Ну вряд ли вы знаете все. Почитайте о тех, что не знаете. Ведь люди, которые их придумали и описали прошли вашим путём. Почему бы не взять их опыт? Конечно, он не заменит собственного, но зато вы будете знать где и какой паттерн можно применить на стадии проектирования.
            • а как узнать, что это уже знаешь, пока не прочитаешь?)

              Вы правильно делаете, что доверяете себе, а не тупо выбираете паттерн из книжки и пытаетесь его всунуть в код, это и есть, насколько я знаю, традиционный подход к использованию паттернов. Наверное, все, кто читает книжки про паттерны, понимают, что половину и так знали до этого. Но про них просто полезно почитать, чтобы свой «словарь» расширить, да и может это знание помочь избежать каких-нибудь неочевидных граблей.
              • Зачем насильно подгонять примеры из книжки? Когда знаешь паттерны, то, обозревая задачу, сразу видишь комбинации паттернов. Возможно даже несколько вариантов. Выбираешь тот что нужен. Паттерны не просто так придуманы: многие из них гибкие и могут переходить один в другой при масштабировании.
                • Даже не столько придуманы, сколько классифицированы. Паттерны существуют столько же, сколько и программирование. В головах программистов.
            • Во-первых, может быть есть что-то что вы не знаете
              Во-вторых, общая терминология облегчает общение с другими. Можно не говорить «это класс X реализует все методы интерфейса Y, но они ничего не делают», а написать «X — это NullObject для Y»
    • паттерны не для «неумеющих программировать», а для желающих программировать грамотно.

      если код написан с использованием паттернов и общепринятых подходов, то его легко читать.

      Не стоит гордится тем, что вы «понимали о чём речь». ясное дело, что вы понимали — все паттерны очень просты и понятны. на то они и шаблонны.

      знание паттернов, uml, мат. терминов… и прочего-прочего очень облегчает общение. особенно с новыми людьми.
      • Что такое UML опять-таки? Почему нельзя просто рисовать такие схемы, которые вам нравятся и общепонятны? Зачем всегда привязываться к какой-то практике? Я нарисую схему со стрелками и кружочками — и все поймут, о чём я. И мне абсолютно без разницы, соответствует ли это UML нотации или нет. То-же самое и с паттернами. Если вы сами не можете без книжки формализовывать код в паттерны, знание оных не поможет. Я к этому веду.
        • вы сидите втроем со своими друзьями и рисуете кружки, квадратики и стрелочки, и всё вам понятно и просто.
          через год приходит четвертый и его надо ввести в курс дела.

          — а это что за хуй тут нарисован?
          — ды эт мы с пацанами… ну в общем это…

          — а почему тут 3 класса в кружочек а один в квадрат?
          — потом что этот класс особенный он…

          — такс… тут 2 класса в квадрате… они типа того «особенного»?
          — эм… нет… тут не так… тут имелось ввиду… м… Мишка приедет из отпуска — у него с прошу.

          — а что делает этот кусок кода?
          — он делает…
          — а этот?
          — м… тоже самое.
          — а почему 2 одинаковые задачи делают 2 разных куска кода?
          — ну я сперва написал этот… а потом я с девушкой со своей поссорился… и как-то в другой раз решил по другому написать… ну это хенрь… тут ещё есть в другом месте другая реализация этого же алгоритма — вот там классно!.. только я не помню какая из 3х сейчас используется…

          — я тут у вас ошибку нашёл. в процедуре…
          — плохо… очень плохо…
          — ды всё ок. я исправил…
          — плохо… у нас в 14 местах этот код используется… чёрт… значит и там ошибки.
          — не страшно, скопипастим туда исправленный вариант.
          — эм… в некоторых из этих 14 изменения внес небольшие… где-то на бумажке было записано в какие… или на доске… давай-ка ты лучше пока верни обратно а мы потом перепишем заново все…
        • Если вы сами не можете без книжки формализовывать код в паттерны


          ещё раз повторюсь, что вы неверно понимаете предназначение паттернов.
          паттерны нужны для того чтобы научить вас как делать, а чтобы вы делали так, как все остальные.
          • сорри… «не» пропустил :))
            паттерны нужны не для того чтобы научить вас как делать, а чтобы вы делали так как все остальные.
            • Не согласен. Знакомство с паттернами как раз учит тому, как делать — как реализовать то или иное необходимое поведение наиболее удобным способом.

              А изо всех сил сводить задачу к набору паттернов (чтоб все стандартно было) не стоит.
              • неа. паттерны придумывались как раз для того чтобы не нужно было изобретать велосипед каждый раз.

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

                но когда сталкиваешься одной и той же задачей несколько раз… нельзя её делать так, как вздумалось сегодня. если взять за правило использование паттернов то вы по названию паттерна сразу понимаете что делает код.
              • паттерны это культура программирования.
                не спорю, можно и без них… но это всё равно что объяснить что-то собеседнику не набором наспех сгенереных фраз, а привести известную цитату, пословицу.
    • Патерны описаны, что бы вам было с коллегой быстрее общаться, не рассказывать, что: «паттерн визитор — это такая штука, которая… (5 минут растекания мыслью по древу)». Паттерн — это шорткат, за которым стоит стиль, композиция, куски кода и так далее. Знание паттернов, конечно же, не панацея, просто зная их вы будете общаться более эфективно.
  • А сколько времени вы работали по TDD, прежде чем перешли на интеграцию тестов сразу в код? Другими словами сколько времени ушло на осознание того, что можно делать иначе практически тоже самое?
    • Познакомился с TDD наверное в 2004-м или 2005-м. Плотно с ним работал с 2006 по 2008. Т.е. три года потребовалось. :)
      • а примеры тестов в коде можно? что-то я не очень понял, о чём речь
        • Покажу в следующих частях. Описание того, что я имею ввиду, есть в тексте статьи, когда я говорю про использование несуществующих на данный момент еще типов.
  • Хех, если ваш код такая же каша как и этот текст, то я не завидую вашим коллегам.

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

    Про код в голове — я пишу в месяц дофига кода, и просто не помню деталей что были две недели назад.
    • Честно говоря я вообще не представляю как предложенный автором вариант можно реализовывать в командной работе, когда даже в разработке одного класса может принимать участие несколько человек. Далеко тут без проектирования не уедешь.
      • Один класс несколько человек пишут? Что-то у вас не то в команде. Разбейте систему на компоненты и разрабатывайте компоненты, а не классы. Классы — это уже вторично.
        • Компонент состоит из нескольких классов. Работу над компонентом начинает один человек, а заканчивает другой. Так что всё нормально, и получается, что над одними и теме же классами работают несколько человек.
    • Вы поняли, что копи-паст оставляем, а я его не оставляю, а использую для выделения в классы. Помнить, что вы писали месяц назад не обязательно. Вы производите рефакторинг здесь и сейчас. Плюс комменты никто не отменял.
      • Если где-то в каком-то месте программы вы чувствуете, что нужно скопи-пастить – берите и копи-пастите. Никакой инкапсуляцией на этом этапе заниматься противопоказано! Вы насоздаёте мелких классов и получите головную боль в итоге. Копи-пастите и копи-пастите, похожие куски кода в разных классах или методах доводите до идентичности.
        Где тут здесь и сейчас? Я вообще не вижу смысла копи-пастить, тем более делать из этого идеологию или писать об этом статью.

        Если же «рефакторим здесь и сейчас» то копи-паст в принципе не нужен. Ну то есть совсем. Потому что кусок кода обернуть — одна кнопка, вставить созданный класс или функцию в другом месте — другая. Ни копи ни паст тут рядом не лежал.
        • Цитата имеет свойство заканчиваться, в результате чего теряется контекст. Я же упоминаю по тексту о том, как потом идентичный код можно легко выделать в сервисы? Если вы начнёте совсем сразу всё выделять в отдельные методы-классы, вы рискуете упустить шанс создания более общих классов, а значит более качественной инкапсуляции! Для вас это очевидно?
          • На выделении методов и классов рефакторинг не заканчивается. Точно так же методы и классы при необходимости выделяются в более общие классы/шаблоны/библиотеки. И я не вижу смысла откладывать рефакторинг на потом, кроме лени. Каждая операция рефакторинга сама по себе проста и очевидна при некотором опыте. Сделать её «потом, когда придёт озарение о более общем классе» не проще, чем «сейчас и потом, если понадобится».

            Давно уже придуманы принципы, следуя которым нельзя ухудшить архитектуру или «упустить шанс» её улучшить. Описаны в разных книгах, больше всего, по-моему, у МакКоннелла в «Совершенном коде».
            • Вы ссылаетесь на книгу в качестве доказательства, смысл которой передать не можете. А я могу в одном предложении расписать суть каждой применяемой мной технологии. Посмотрите для примера моё определение TDD. Это говорит о том, что я разбираюсь в том, о чём пишу. А МакКоннелла я читал еще в школе. Ничего сверхъестественного и инсайтного там нет. Инсайты даёт практика, а не книжки.
              • Да какое ж это доказательство. Книгу я привёл в качестве ссылки. А смысл её сложно передать в комментарии к топику на хабре, поскольку в ней его много.

                Вы пишете тест таким образом, как вы хотите, чтобы потом ваш код можно было использовать

                Вот это и есть весь смысл TDD? Смысл TDD в написании тестов определённым образом? Ну нет. Эта фраза совсем не означает, что вы разбираетесь в TDD (сам факт чего я не отрицаю).
          • «более качественной инкапсуляции!» — порадовало :)

            нет не упущу. Я вообще стараюсь планировать общую архитектуру заранее и при больших изменениях приходиться ее пересматривать. А то что вылезает по мере имплементации — так фишечки, иногда вредные. Следовать же тем стихийным озарениям в локальном контексте — верный путь к потере целостности приложения.
            Для меня же понятная и дешевая возможность изменить — деньги за меньшее время. Практика показала что время потраченное на обдумывание заранее, на общий рефакторинг в случае крупных изменений — окупаются в несколько раз.
    • я так понимаю автор подразумевает что-то вроде экстремального программирования чтоли, незнаю как точно назвать. Сначала пишется код, где надо, копипастится, чтобы быстрее было, а потом продумывается красивая структура, и дубли заворачиваются в функции или классы. Я сам так делаю, иногда удобно, особенно в тех случаях, когда конечная цель не совсем ясна, когда например ТЗ меняется часто или допустим дали на разработку небольшую программу, а потом её просят усложнить, но заранее об этом известно небыло. В таких случаях гораздо проще убрать копипаст, чем менять архитектуру.
  • а автору не сложно продемонстрировать страждущим какой-нибудь достаточно большой кусок кода, написанный по такой методе? думаю не мне одному было бы любопытно взглянуть. :)
  • Только начинаю более-менее серьёзно программировать, но этот подход уже использовал, как-то само по себе пришло…
    Видимо тут нужен реально большой опыт, чтобы в голове продумывать то, как вы хотите использовать будущий класс. У меня из-за этого только каша получалась и приходилось возвращаться к бумаге =)
    • А ещё лучше не на бумаге, а в специализированных диаграммах, например UML. Хотя самые первые наброски — это доска и цветные маркеры. =)
  • А как же «Don't Repeat Yourself»?
    • В коде, который вы отдаёте клиенту в качестве релиза это будет. В процессе написания — далеко необязательно.
      • А как без этого? разбираться в своих копипастах, править одно и тоже в разных местах?
        • Так вы же не месяц копипастите. :) В статье: «код пишется мелкими перебежками». Это всё происходит многократно даже в течение часа!
        • Это то-же самое TDD (если вы с ним хорошо знакомы), только без отдельных тестов. Можете это так воспринимать. Я пришел к TDD, развился на нём и никуда не ушёл. Я пишу код точно также, используя те-же самые методологии, что описаны у Кента Бека. Но только всё это я делаю прямо у себя в коде.
  • По-моему так автор под соусом copy-paste подал вполне обычный и современный подход к программированию, основанный на паттернах, тестировании, рефакторинге)
    • Если учитывать ту школу, которую я прошёл, вряд-ли я мог бы прийти к чему-то совсем уж «другому». Но то, что можно писать «тесты» прямо в коде — это было для меня инсайтом, о котором я и изложил тут.
      • По-моему ужасный инсайт
  • Автор не понимает сути паттернов. Либо никогда не работал большими командами.

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

    Другое дело, что программистам надо как-то общаться; фразы типа «ну тут типа ссылка на другой класс, у которого среди как бы наследников...» удобно, черт возьми, заменять на «Мост». Или Адаптер. Или Фасад. Или Синглтон. Или Завод. Хитросплетение классов превращается в одно простое слово. Плюс можно обмениваться опытом при различных реализациях шаблонов проектирования. Ну и прочие радости, которые привносит в жизнь умение общаться в пределах очень специальной области.

    • раскрыть комментарий
      • А протоко(а)лы у вас откуда берутся? Проектируются, небось. Как говорят умные люди и подтверждает практика, именно на взаимодействиях этих самых узлов бОльшая часть ошибок и происходит. Неплохо, когда хотя бы часть этих ошибок не появляется из-за того, что два человека одинаково понимают, о чём идёт речь (это про использование паттернов).
        • Протоколы берутся из спецификаций. Как вы, наверное, знаете, существует, например, XML-RPC. Как они «получаются» — не суть важно. Не знаю, что там говорят какие-то абстрактные умные люди, но если работа по протоколу давно откатана, то не вижу проблем для нестыковок. Причём у нас в команде был опыт реализации и своих протоколов под разные платформы, big-endian, little-endian и другие мелочи. Всё учитывалось. Только как это относится к статье? Ах-да, паттерны я не отрицаю, я говорю про то, что они сильно-сильно вторичны. Не стоит думать, что если вы знаете названия десяти паттернов, это как-то сделает ваш код лучше. Ну и другие мои комменты тут тоже почитайте, если интересна моя т.зр.
          • Мне страшно представить проект, в котором код двух разных программистов общается между собой исключительно через xmlrpc или подобные по назначению протоколы. В любом случае, наличие этого протокола не отменяет необходимости проектировать взаимодействие компонентов.
            • Вот уцепятся за одно слово и начинают флейм раскручивать… Ну не понимаешь сути — так и скажи или переспроси, если интересно. Зачем мне навязывать свою точку зрения? Если бы мне она была интересна, я бы спросил.
              • Не стоило постить на хабре, если не интересна точка зрения других.
                А то тут тролли кругом… такого понапишут.
                • Асветой занимаюсь. Или как это по-русски… О! Просвещением! :)
                  • Ща за недостаток аскезы заминусуют))
          • Кстати, не так давно в западной программерской блогосфере разгорелась дискуссия по похожему поводу. Один довольно известный программист писал про такой подход. Без тестов, без паттернов, без С++ и мультитрединг — любых усложняющих инструментов.

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

        И уж ТЕМ БОЛЕЕ странным звучит утверждение, что паттерны — это для стыковки. Мне казалось, что это интерфейсы между подсистемами для стыковки.

        вы действительно с работой напарников общаетесь исключительно через XML-RPC? Прям все проекты реализуются в распределенной среде? Или теперь для iPhone так пишут?
  • Без тестов достигается то же качество кода, что и с тестами, только быстрее.


    Это, несомненно, правильно. Но это если сравнивать с этапом разработки по TDD. А если учитывать и этап поддержки, то программисты, которые занимаются поддержкой, скажут автору огромное «спасибо» за код с копипастом и без тестов. Даже если не задумываться о поддержке, если вдруг какому-то другому человеку понадобится внести изменения в код, написанный автором, у него (или у проекта) возникнут проблемы.

    Паттерны – это рутины, для тех, кто не умеет программировать. У хороших-же программистов паттерны выскакивают прямо из-под клавиатуры.


    Даже если не обращать внимание на то, что одна фраза противоречит другой, паттерны — это не та штука, которую «выучил и начал использовать». Формализация паттернов служит, в основном, таким целям:
    * Увидеть как определённые типы механизмов в ООП реализуются наилучшим образом, какие есть в этих механизмах подводные камни, плюсы и минусы.
    * Выработать общую терминологию, благодаря которой проектирование идёт быстрее. Это позволяет говорить друг другу «тут можно использовать композит» вместо «можно сделать такую функцию, в которую передаём объект того же базового класса, что класс содержащий функцию чтобы он прицепился к контейнеру и ...»

    рефакторинг – это очень просто. Правильно и без ошибок это гораздо быстрее сделать без тестов, чем с тестами.

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

    В общем, если вы разрабатываете программы сами, без команды, не собираетесь заниматься их поддержкой в дальнейшем (и не страшно испортить карму проклятиями от тех, кто поддержкой заниматься таки будет), отлично умеете проектировать и знаете правильные принципы — то описанный подход для вас. Только непонятно, почему вы всё ещё разрабатываете программы сами, без команды и разрабатываете такие программы, которые не планируют развиваться :)
    • Я бы сказал, что точно есть ситуации, когда с тестами быстрее чем без тестов. Например, если интерфейс маленький и тесты простые, а реализация большая и сложная. Или, например, когда надо оптимизировать большой кусок — делаешь не вполне тривиальные преобразования и надо убедиться, что функционал не изменился а только ускорился (хотя это уже не рефакторинг).

      Рефакторинг, который инструмент может сделать формально и 100% точно, думаю, можно делать без тестов.

      Вообще требует измерения — сколько потрачено время на написания тестов сколько на ручное тестирование и исправление ошибок.
      • Я бы не только сказал, но и доказать могу, что есть ситуации, когда без тестов быстрее :)

        А измерения уже много раз проводились. Западные книгописатели любят на всякие разные измерения ссылаться. Только измерения проводились в одних условиях, а проект делается в других, поэтому тут поможет только здравый смысл и опыт.
        • Я бы не только сказал, но и доказать могу, что есть ситуации, когда без тестов быстрее :)

          Докажите, пожалуйста, если не трудно
          • Например, ситуация полностью противоположна описанной вами, а именно «интерфейс большой и тесты сложные, а реализация маленькая и простая». Ну, что в голову первое приходит. Скажем, тестировать внешний вид визуализатора для музыки, чтобы все варианты анимации соответствовали задуманному алгоритму. Тесты писать вы будете очень долго, а толку от них будет мало, да и разработку они вряд ли ускорят. Проще на результат глазами посмотреть :)
    • Дело в том, что в статье рассказывается про то, как использовать копи-паст в моменте для дизайна иерархии классов. Вы не оставляете копи-паст навсегда. Перечитайте еще раз, пожалуйста.
      • В статье рассказывается про вред тестов, паттернов проектирования и отсутствие вреда копипаста. Мой комментарий — про вред копипаста, пользу паттернов и тестов. Вне зависимост от момента. Перечитайте ;)
        • В статье рассказыется совсем о другом. Совсем. Паттерны полезны, но не стоит их выдвигать на передовую при проектировании. Сначала поймите, что вам надо. Для этого нужно написать немного кода. Увидьте паттерн — реализуйте. Тесты полезны, как я могу утверждать что-то еще, если блин, с 2005-го года в этой теме? Копи-паст используется только как инструмент, который вы потом выбрасываете. Перечитайте.
          • Вот не могу я в статье найти механизма выбрасывания копипаста, хоть как всматриваюсь и перечитываю. В комментариях — вижу фразу «копипаст потом выбрасывается», а когда «потом» и как именно — не вижу.
            • Наверное, тогда следовало бы дождать продолжения обещанного? Или это несправедливо было с моей стороны оборвать мысль? :)
              • Но как это.
                Вы утверждаете, что если я перечитаю, то пойму, что копипаст выбрасывается. А теперь утверждаете, что в тексте этого нет, нужно ждать следующую часть. Так зачем же тогда было перечитывать? Тьфу…
            • вот этот механизм:

              > куски кода в разных классах или методах доводите до идентичности… Выполняйте эту процедуру столько, сколько необходимо для того, чтобы у вас в голове созрел дизайн следующего сервисного класса.
  • А MVС — это тоже паттерн. И что же нам теперь делать? :)
    • придется не использовать аббревиатуру а показывать на пальцах и мычать :)
    • Использовать! Я, наверное, уж слишком сутрировал. :) Не стоит воспринимать совсем уж буквально. Да, мы, бывает обсуждаем алгоритмы возле белой доски, разбираем по паттернам. Но это всего лишь прикидки. В статье я говорю о том, что стоит идти от практики к формализации, а не от формализации к практике. Улавливаете? :)
      • Пролистнув две трети комментариев, уже и я не выдержал :) Да улавливаем мы всё, улавливаем, только ваш «креативный» подход далеко не всем нравится, и далеко не всегда хорош. Вероятно, в вашей специфике всё это работает, и вам в кайф изобретать собственные узлы и стыковать как хочется.

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

        «Кирпичи», «панели», «балки» — это всё для лузеров! Нормальный архитектор сам придумывает то, что ему надо.
        — А вот смотри, я изобрёл твёрдый параллелепипед, из него можно стену сложить, а то и всю собачью будку!
        — Дак это же паттерн «кирпич»!
        — Причём тут паттерн? Я сам придумал, и так удобнее!

        Мне кажется, что все-таки идея стандартизации компонентов очень правильна, и критиковать ее как-то… глупо что ли.
        • Идея компонентов — бесспорно. Идея их стандартизации под большим вопросом. В пределах чего стандарты? Паттерны — это не стандарты. Это парадигмы, которые никак не мешают придумывать плохие стандарты.
          • ОК, повторю свою аналогию более внятно. Паттерны — это кирпичи. Кирпичи — это стандарты? Конечно, да — есть некоторое количество разновидностей кирпичей, и все дома строят из них. Не слышу громких лозунгов «даёшь кастомизированный кирпич под каждую стройку». При этом из хороших кирпичей действительно можно сделать паршивое здание, но не будем валить всё на кирпичи.
  • Нифига не въехал в связь заголовка с текстом.

    Также не совсем понятен смысл всего текста: то расписываются прелести TDD (и далее следует призыв отказаться от него), то рассказывается о способе разработки архитектуры «сверху вниз» (который тоже не нов).

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

    Отказ от тдд и сохранение возможности безболезненного рефакторинга возможно, если рефакторингом занимается человек, который проектировал систему (ну или минимум знает ее досконально).

    BTW, у вас во флешка на 7touchgroup.com/ баг (?) — попробуйте попереводить мышку с about на services и обратно.
    • Сайт будет заменен. Люблю копи-паст, потому что помогает проектировать элегантные объектно-ориентированные системы. Копи-паст не оставляем, а используем как инструмент. Вот и весь смысл статьи. В одном предложении.
      • Люблю копи-паст, потому что помогает проектировать элегантные объектно-ориентированные системы

        эта фраза рассматривается большинством нормальных программистов как

        Люблю хуячить топором, потому что помогает делать элегантные миниатюрные фигурки
        • А как Вы поняли эту фразу про «люблю копи-паст», если не секрет?
          • вот у меня большие подозрения, что я и не только я поняли её не так, как хотел автор.
            под копипастом обычно понимаются одинаковые или почти одинаковые куски кода.
            • Ну в общем правильно. Автор делает одинаковые или почти одинаковые куски кода. Зачем он это делает? Чтобы увидеть, где они. Зачем старается делать именно одинаковые куски кода («похожие куски кода в разных классах или методах доводите до идентичности»)? Чтобы выделить общее. Когда становится понятно, какой именно код является общим и где именно он используется, весь копипаст выкидывается и пишется класс, который в себя включает необходимый функционал. Мы, по сути, обычно занимаемся тем же, только в голове — прикидываем, какой код где повторяется, у нас в голове этот копипаст. У подхода с реальным написанием такого кода есть как плюсы, так и минусы. Главный плюс — архитектурные решения можно немного откладывать до того времени, когда информации для нахождения удачной архитектуры будет больше, ну и меньше всего в голове держать нужно. Минусы, конечно, тоже есть — думаю, больше писанины на определенных этапах, что может как компенсироваться более удачной архитектурой, так и нет (за время, потраченное на доведение копипасты до идентичности, можно бы отрефакторить первоначальный не самый лучший «сервисный класс» с учетом выявленных новых требований).
              • Пишем, вообщем, «тупой» код до тех пор, пока закономерность не выявится, и после этого рефакторим, а не пытаемся эту закономерность предугадать заранее (что, конечно, сделать можно, но для этого в голове держать нужно больше всего).
                • пишем тупой код пока он во что-то ни сложится и тогда, увидав как оно должно быть — перепишем заново? вы стебётесь?
                  • maxatwork правильно написал про масштабы. Я ничуть не стебусь. Написать 10 строчек «глупого» кода на питоне, потом еще 10 строк в другом месте и понять, что вот оно, вырисовалось, убить эти 20 строчек и написать вместо них 15 строк более абстрактного кода — что в этом такого?

                    Очень часто (в разных областях — % разный) бывает так, что 15 строк абстрактного не нужны и хватит 10 строк «тупого». Вот тут-то и кроется выгода. Наш код в итоге проще (а значит его проще поддерживать втч), а то, для чего нужны дополнительные уровни абстракции — эти уровни абстракции получают.

                    Про строчки — это не буквально, конечно. Можно вместо «строчки» подставить что-нибудь в духе «усилия», или еще что-то.
                  • ну и другая выгода, в какой там раз другими словами :)

                    вот я написал 10 строчек глупого кода, написал еще 10 глупого кода, но все еще не понял, как лучше сделать умный. Я могу сделать ЧТО-ТО, что устранит дублирование кода, но это не устранит причину дублирования, и в 3й раз мне придется опять писать глупый код. Поэтому я не устраняю дублирование и пишу 3й раз 10 строчек глупого кода, которые уже помогают мне понять, как сделать код умным. Если с такой ситуацией не сталкивались, — вы очень умный, вам очень везет, или архитектурные проблемы, встающие перед вами, — несложные.
                • Молодец!
              • по-моему маразм.
                стараться делать одинаковые куски кода чтобы потом их свернуть в 1? давайте сразу напишем один?
                у меня за всю жизнь было 1-2 раза что 2 куска кода становились всё больше и больше похожими и я их схлопывал в один. и произошло это потому что я изначально поленился такой вариант предусмотреть.

                одинаковые (в будущем) куски кода видны сразу. на самых ранних этапах проектирования можно сразу прикинуть где и что будет повторяться…

                а если у вас 2 совершенно разных класса… и у них какие-то 2 процедуры очень похожи друг на друга, но логический не связаны. то тут не нужно ни копипастить, ни пытаться выделить в один.
                • Это такой прием просто, вот автору так удобнее — именно написать код и не держать его в голове. Вам — удобнее держать в голове и не писать по нескольку раз. Это же не значит, что один способ плох, а другой хорош.

                  Насчет предусмотреть. Идея-то вот в чем. Можно предусмотреть, что код будет похож, и вынести его в какой-то отдельный блок. А можно предусмотреть, что будет похож, и попробовать на практике, чем именно он будет отличаться, чтобы потом вынести в отдельный блок уже на более высоком уровне абстракции.

                  Ну это я уже 3й раз одно и то же пишу чего-то :)

                  P.S. Если честно, не понял причины такого накала страстей тут в комментариях, чего все так грязью поливают друг на друга)
                  • Все бы хорошо, смущает призыв отказаться от юнит-тестов, например, и подача этого как некой новой методологии проектирования и разработки. Но я это тоже третий (или больше?) раз пишу.
                    • Я всегда использовал юнит-тесты больше для ООП-дизайна, чем для чего-то еще. А сейчас у меня сам код некоторое время является тестом для других частей кода, а потом это всё рефакторится, и весь код становится полноценным, хотя некоторые элементы на состояние могут и остаться. Ассерты например. Я могу всё то-же самое, что раньше делал в тестах, теперь делать в коде. Ну а аксептанс-тесты можете написать, если назрела необходимость. Хотя у меня давненько что-то такого не было.
                    • Способ тестирования вызывает некоторые сомнения. Но в этой ветке дискуссии я лично обсуждал только копипаст.
              • Это я уловил (несколько раз вдумчиво прочитав статью с начала до конца). Сам принцип далеко не нов, вполне себе обычная разработка «сверху вниз» с проектированием «по ходу дела» и забиванием на написание тестов. Где и как отражается архитектура (в коде или на диаграммах) — не принципиально.

                Спорно тут то, что автор, не делая оговорок о масштабах и особенностях проектов, к которым это применимо, и не сообщая о возможных подводных камнях, призывает следовать данной методике. А самый существенный минус у нее в данном варианте — сложность сопровождения и модификации полученного кода.
                • про масштабы очень верное замечание.
                • А в чём сложность? По масштабам проектов — от одного до пары-тройки человеко-месяцев на кодирование. Масштабы не имеют особого значения, если вы умеете экстраполировать свои навыки. Я писал и полугодовые либы, когда работал с WinForms. Ничем не сложнее, чем проект на пару недель.
                  • хм, почему-то прочитал "(масштабы) и (особенности проектов)" вместо "(масштабы и особенности) проектов". Масштабы проектов тут и правда не при чем.
                  • Еще раз, основные мысли статьи:
                    — отказываемся от написания юнит-тестов
                    — разрабатываем сверху вниз, продумывая архитектуру на этапе написания кода
                    — в качестве тестов на этапе продумывания интерфейса выступает компилятор/линкер
                    — в процессе разработки приложения не заморачиваемся архитектурными изысками, и пишем «как пишется», по возможности стараясь реализовывать похожие алгоритмы одинаково.
                    — при удобном случае одинаковые куски оборачиваем в классы/методы
                    — далее тесты становятся не нужны, т.к. мы помним архитектуру системы, а все ее компоненты реализуют элементарные операции, в тестировании не нуждающиеся.

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

                    Масштабы проекта тоже важны, т.к. что хорошо для пары-тройки человекомесяцов, не очень подходит для пяти человеко-лет и сильным распараллеливанием работ. Объяснять «почему» нужно?
                    • Всё правильно вы поняли. Документировать архитектуру никто не мешает. Документируйте! Если считаете, что вам это поможет в дальнейшем. Довольно хорошо в iPhone архитектура приложения представляется графически в Interface Builder. Так что необходимость еще какой-то формализации тут под большим вопросом. А в тестах всё равно нужно будет разбираться, как и в основном коде. Да еще понимать, что хотел сказать вот этим тестом программист и выстраивать нехилые такие связи между тестами и кодом. Насчёт пяти-летних проектов ничего не скажу, я не имел дело с такими и в принципе они меня мало интересуют.
                      • К сожалению, не работал с InterfaceBuilder, но подозреваю, что как и все современные среды, представлять архитектуру он умеет в виде диаграммы классов (что является только частью документации), и то только настолько, насколько написано кода. Так что вначале разработки охватить весь проект целиком не сможем, а значит, не сможем понять, как можно распараллелить разработку, что можно отдать на аутсорс, в общем, не получится эффективно использовать имеющиеся ресурсы (если их больше одного-двух программистов).

                        Тесты — да, с ними надо будет разбираться. Но зато они _моментально_ отвечают на вопрос: а если я вот этот метод заставлю работать несколько иначе, что у нас сломается? А это очень ценно на этапе сопровождения.

                        Хотя еще раз повторюсь, на отдельных задачах и даже маленьких проектах на одного-двух человек без сопровождения и без проблем с кадрами такой подход вполне оправдывает себя.
                        • Вы читали Джона Роббинса? Почитайте. У меня есть всё для успешного сопровождения. Просто в статье об этом мало рассказано. Многие проекты мы успешно саппортим и добавляем новые фишки. Можно обеспечить комфортную среду для саппорта и без кипы бумаги. Для меня всегда было очевидно, что это всего лишь еще одна форма рассказать, что же происходит в коде. А код должен быть написан так, чтобы он и без документации легко читался. Запустил Interface Builder — посмотрел связи компонентов — всё, можно начинать докручивать.
        • Аххахах! Комент — в избранное :)
  • Класс, а как же быть, с основным костылём copy-paste, когда в раскопированном 20 раз куске кода оказывается баг, который правит другой девелопер ровно в том месте где он нашёлся?
    Вот только не надо мне говорить, что другой девелопер должен эмпирическим методом проискать такой же код по всему проекту, т.к. на практике даже не понятно, что именно вообще искать надо (например когда фикс бага затрагивает несколько мест).

    Я работаю в Direct EDI, наша система документооборота разрабатывается с 2002го года и один из документов для разных клиентов (упрощаю) делался именно копированием кода. Тогда никто особо не задумывался. В результате через 7 лет у нас есть порядка 400 вариаций на тему, которые какбы и похожи, но для каждого клиента немного свои. На суппорт этой каши уходит нереально много часов, и соответственно денег. Недавно был прорыв — запустили один модуль, на который будем постепенно переводить все эти копии с кастомизацией не на уровне кода, а на уровне файлов настроек. Суппорт настроечных файлов обходится в 10-20 раз меньше по времени. То же было бы и в случае наследования кода.
    • как я понял из статьи, главное это творческий акт
      а как там это будет работать потом… и кто это будет дописывать/разгребать/отлаживать… это всё пустое, и не стоит даже забивать голову такой ерундой.
      • У вас какая-то интересная система разработки. У нас каждый разработчик пишет отдельный компонент и доводит его до совершенства. Никто не пишет один и тот же компонент два раза. Вы видели, чтобы два токаря точили один и тот-же болт попеременно или как-то вместе? А творческий акт — это действительно самое главное. :)
        • а ваши разработчики мрут? уходят в отпуск? увольняются? а новые к вам приходят? а вы помните то, что писали год назад?..

          вы описываете идеальный ход событий. типа:
          — как написать программу без ошибок?
          — написать 1 строчку без ошибок, прибавить к ней ещё одну строчку без ошибок… повторить несколько тысяч раз
          • Вы и тут, и выше напрашиваетесь на флейм, а я флеймить не хочу. Вы либо вникаете в смысл и задаёте вопросы, либо я не продолжаю дискуссию в таком формате. Тем более с бранью.
            • я до вас пытаюсь донести 2 вполне обычные ситуации:
              1 — к вам пришел новый программист
              2 — от вас ушёл старый, не доделав до конца свою часть

              вы написали пост… ну просто классика троллинга. и какого эффекта вы ожидали?

              З.Ы.
              и где вы у меня брань нашли, кстати? О_о
              там только один безобидный «хуй», описывающий фигуру составленную из овала и двух маленьких кружков.
        • А это смотря какая система, и какие там компоненты. Например, есть проекты, где стадия начального проектирования (на бумаге) таки важна и необходима — там, где важно в относительно короткие сроки (по сравнению со сроками на весь проект) определиться с примерной архитектурой и распараллелить разработку.

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

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

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

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

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

    Никаких там книжек толстенных по рефакторингу вам читать не нужно, чтобы добиться качественного кода. Просто запомните: рефакторинг – это очень просто.

    Это вообще шикарно, нужно поделится с сотрудниками. Зачем вообще книги!? Сжечь всё на костре, доверится первобытным инстинктам и писать крутой спагетти код с душком, так?
    • О каком, простите, коде с душком идёт речь? Копи-паст не оставляем, а используем!
      • Я надеюсь, что ваша статья продуманная провокация, иначе с таким неадекватным взглядом нам процессы программирования тяжело вообще как-то со обладать, что-ли =)
        • Мои взгляды на разработку — компонентные. Сформированы наблюдательностью, познаниями не только в программировании, но и в других сферах производства, в том числе станкостроительной. Так вот, очень многие путают командную разработку и командное написание классов. Почитайте остальные мои комменты тут.
          • Да, уже не без удовольствия прочитал. В связи с этим и выражаю свои опасения по поводу адекватности происходящего.
    • >>Как-то тяжело поверить, что вы серьезно увлекаетесь написанием статей.
      А вы не верьте. Проверяйте. По google.com можете eisernWolf пробить. Так обо мне можно узнать всё, включая номер мобильного телефона и адрес по прописке. :)
    • >>содержание больше похоже на поток мыслей, чем на сформированный полезный для людей продукт.

      Именно посредством мыслей статьи и пишутся. А сформированным тут ничего пока быть не может. Это всего лишь первая статьи из нескольких.
  • Грабь! Убивай! Копипасть!
    жуть…
  • Я псих, я дурак, люблю копипаст. Оторвите мне руки!
  • Копи-пастите и копи-пастите, похожие куски кода в разных классах или методах доводите до идентичности. Возведите этот принцип в абсолют. Именно он позволяет мне строить элегантные объектно-ориентированные системы.

    Кажется код одного из ваших последователей я рефакторю уже второй месяц. Убил бы…
    • От меня код всегда уходит в чистом состоянии, без багов, ликов и тем более копи-паста, который всего лишь инструмент! Вы смысл-то не уловили совсем.
      • По-видимому тут мало кто уловил ваш скрытый смысл. Что говорит о том, что статью нужно как-то переоформить, что-бы он стал более очевиден читателям.
        • Или читателям поднимать свой уровень, когда статья станет понятной. Не так ли? :) Существуют многие вещи, которые я сначала не понимал, понимал не так, и думал, что автор мудак. А по прошествии лет, брал ту-же самую книжку, перечитывал — и всё становилось на свои места.
          • Да, тогда вы обратились не к тому интернет ресурсу для публикации своего опыта. На сколько мне известно, тут этот ваш комментарий проинтерпретируют весьма однозначно — троллинг.
          • Не, серьезно. Статья непонятна не из за уровня читателя. Уровень тут минимальный нужен, но вот врубиться в это…

            Сбивают с толку:
            а) заголовок (copy-paste традиционно имеет несколько другой смысл, нежели описываемый подход)
            б) лирика, не имеющая отношения к основной мысли (история взаимоотношений с TDD тут несколько притянута)
            в) недостаточно четко выраженная сама основная мысль (не сделан упор на то, как именно используется копипаста).

            Как то в комментарии выше в двух строках понятней у вас получилось, может, и не нужно больше строк? ;-)
            • почему-то похоже на то, что написано так специально, чтоб веселье началось и можно было поспорить :) может и подсознательно)
              • У вас исключительно проницательный ум. :)
        • Зачем? Человек ещё покопипастит таких же десять статей (он же обещал), а там, того и гляди, вылезут общие блоки, потом объединит — и покажет на практике, как эта схема работает.

          А мы пока будем читать самоорганизующийся (со временем) поток сознания. Ибо такие вещи как «композиция», «план», «дидактика» автору претят.
      • Я то на самом деле уловил. И даже понял :), хотя и не приемлю такого подхода. Мне гораздо проще разок обернуть в функцию и юзать. Времени теряется минимум, зато дальше идти проще.
        Статья написана нечетко и ее понимают только те, кому эта статья в общем и не нужна :)
  • Паттерны – это рутины, для тех, кто не умеет программировать. У хороших-же программистов, рутины, для тех, кто не умеет программировать, выскакивают прямо из-под клавиатуры.
    • Всё НЛП построено на моделировании «нужных» людей. Если вы про рутины. А не наоборот. Я об этом и пишу. Если вы уже являетесь хорошим программистом, то, простите, какого чёрта вам моделировать других хороших программистов? Рутины нужны тем, кто не может вжиться в роль сам по себе. Для плохих актёров рутины. Только хорошим актёром вы всё равно так не станете. Конгруэнтности не будет. Помните пресловутое «Не верю»? Это отсутствие конгруэнтности. Появляется, когда человека играет технику, а не использует технику для входа в нужное состояние. Но это мы уже сейчас в актёрское мастерство уйдём. :)
  • В данном подходе содержаться грабли, на которые большинство и наступит радостно, потому что если заранее не проектировать общие детали, то можно здорого прогореть на этом. Такой подход очень опасен в том случае, когда приложение не является монолитным. Потому что менять API это всегда больно, API всегда должно быть сформировано хотя бы в общих чертах до того, как на него будет что-то нанизываться, или придется мартышкиным трудом заниматься. А ежели брать шире, то всегда есть шанс зайти в такой тупик, из которого можно выбраться лишь выкинув половину кода.
    А насчет копипасты, вы разве себя никогда не проклинали за неё в те моменты, когда приходилось в каждом из копипащенных кусков что либо? Я вот из за этого боюсь копипасты и применяю её только в каких то тестовых кусках, которые всёравно ждёт судьба быть выпилеными. И ещё что касается усложнения структуры, лучше несколько маленьких, но простых и понятных блоков, чем один большой монолит, умеющий всё. Поэтому часто казалось бы увеличение числа обьектов ведет к более понятной и логичной структуре, хотя логика иногда пытается обратное доказать, мол чем больше обьектов тем сложнее в них разобраться. Да вот ещё, хорошими программистами сразу же не становятся, и для обучения данный подход прямо скажем опасен, ну не будут выскакивать из под клавиатуры паттерны программирования, для этого нужно многое осознать и понять.
    Но конечно если ты в меру опытен и пишешь что-то для себя, то можно и поэкспериментировать, вдруг получится разработать нечто новое и хорошее
  • Случай клинический.
    Могу только пожелать вам не жить в домах, построенных без проекта, не ездить в авто, сделанных без проекта и вообще пользоваться результатами труда средневековых ремесленников, а не профи. Зато у них акт творения, а не какие-то там скучные расчёты сопромата и диаграммки. Акт творения — наше всё!
    • Когда вы поймёте разницу между молекулой и битом информации — вы измените своё мнение.
      • Не могу удержаться. Судя по комментариям автора — либо автор неадекватен, либо это тонкий троллинг. Склоняюсь к первому варианту.
  • «Когда я начинаю писать программу, я абсолютно не представляю, какой структурой классов закончится этот мой творческий акт через неделю или месяц.»

    Всё, после этого читать не стал, ибо понял, что автор простой кодер без навыков проектирования. Сам лично не сажусь даже писать код если не представляю структуру и какие классы, библиотеки и связи между ними у меня будут.
    • Вы слишком много предполагаете об авторе. :) Да прошёл я уже всё это. То, что вы делаете на бумаге, я делаю в голове при написании кода, по ходу дела. Хотя бумагой я активно пользуюсь для различного рода пометок. Сильно временных. Конечный продукт — код, любые размышления идут в мусорную корзину.
      • Слабый подход, конечно дефки пляшут как хотят и личное дело каждого… Но за такой подход и код, я бы просто на код ревизии гневные комментарии слал и не включал бы код в общий котел :)
        • Слабый в чём? Вы-ж статью не читали. :)
  • Избегать copy-paste стоит там, где сразу можно сделать extract method. Избегать дублирования кода. Статья идет о пользе разработки на тестах. Когда вы пишете тест, вы придумываете интерфейс. Можно сначала придумать иерархию и интерфейсы, а потом написать тесты. Не суть. Но где тут, мать его, польза копипаста?
    • Наверно автор бережёт ресурс своей клавиатуры :)
  • Ваш подход может работать лишь до тех пор пока вы не в команде. Командная работа требует цивилизованных, распространенных подходов.
    • Я бы даже сказал нормативных.
  • Все модные дядьки говорили, что самая большая ценность паттернов в том, что у них есть имена
    И ты можешь сказать другому программисту — вот здесь такой паттерн
    С новыми же языками программирования смысл многих паттернов отпадает, потому что они встроены в язык
    Другие паттерны вообще специфические и редко используются

    Рефакторинг проводить легче, если знать паттерны. А с тем, что паттерны использовать с самого большого смысла начала нет — согласен на 100%
  • Это все отлично, но все-таки покажите нам свой код, а там — поговорим! (желательно чтоб он охватывал статью)
  • Интересный пример с девушками.
    Только вот житель индейского племени тоже умеет общатся с противоположным полом, на своих индейских понятиях.
    И по приезду в цивилизованную страну он не возымеет успеха у слабого пола.
    А если его местный, цевелезованный друг предложит познакомится с карсивой дамой, тот может не правильно понять и доставит эту даму ему в зажаренном виде.

    Такой подход жив, пока вы находитесь в однородной среде, подбных вам людей, с одинаковой культурой.

    И во всём нужно чувство меры. Вы не будете пол года проектировать, делать сложные инженерные расчёты, при строительстве будки или сарая (хотя для сарая скорее всего план накидаете).
  • Не всегда идея проектирования снизу вверх подходит. В некоторых случаях лучше продумать архитектуру системы/подсистемы заранее, до написания кода.
    Еще чаще приходится комбинировать оба подхода.
    Только не совсем ясно, почему именно копипаст стал «лицом» идеи проектирования снизу вверх.
    • Я проектирую сверху вниз. Если для вас это не очевидно, вам рано писать критические комментарии.
      • Хех, разве написание реализации при помощи копипаста и последующий рефакторинг не подразумевает методики «снизу вверх»?
        Да, думаю рановато мне писать что-то конструктивное, раз я не разбираюсь в элементарнейших вещах, таких как всемогущество копипаста.
        • Перечитал и понял вашу мысль. Сверху вниз — на уровне паблик интерфейса класса и снизу вверх — на уровне реализации. Раз вы акцентировали внимание на реализации, мне именно эта часть и запала в голову.
          • Вот видите, как оно оказывается на самом деле. :)
  • Все что тут описано, подходит для разработки в одиночку, или совсем уж небольшими групками, когда абсолютно каждый знает и понимает, что происходит в проекте. Но если у вас имеется огромная корпоративная махина, то вы тут скованы по рукам и ногам, и если изначально не спроектируете, менять интерфейсы по 10 раз вам никто не даст.

    И оставьте уже этот TDD и слова по типу «вы поймете, что я прав, когда у вас будет много опыта», «я практикую TDD уже три года» и т.д., потому как подобное высокомерие не имеет ничего общего с нормальной разработкой :)
    • Это не высокомерие. Я не люблю, когда меня начинают поучать как мальчишку люди, которые даже не въехали в написанное. Меня бы устроила критика, скажем, от kmike или maxatwork, потому что я вижу, что люди секут. А так, поднимать меня на флейм, цепляясь за знакомую фразу и откидывая всё написанное, — ну не интересно мне это. Кто-то ведь даже статью до конца не прочитал, но критический комментарий оставил. «Пастернака не читал, но осуждаю» — мне чем-то эту ситуацию напоминает. В принципе, статья-то изначально и писалась, чтобы зацепить. Но я не ожидал, что набежит столько технически-безграмотных комментаторов да еще и плохих читателей. Это уж точно не было моей целью.

      Насчёт больших корпоративных махин — ничего, что я пишу в разрезе разработки под iPhone? Какая тут к чёрту корпоративная махина? Я не люблю универсализма и не собираюсь рассматривать какие-то абстрактные случаи. Есть проблема — вот вам решение. Причём тут корпоративные махины? Я пас…
      • Все вами сказанное лежит на поверхности и достаточно понятно, по этому не стоит упрекать меня, и людей, что они недооценили вашу работу, потому что не читали текст полностью. По поводу высокомерия, посчитайте количество я в вашем рассказе :)

        > Насчёт больших корпоративных махин — ничего, что я пишу в разрезе разработки под iPhone?

        Ничего, что iPhone упомянут в последним предложении данной статьи? В своих собственных программах, или программах написанных на заказ для маленьких заказчиков вы вправе писать как угодно, однако не стоит предлагать такой метод, как аксиому.
        • >>Все вами сказанное лежит на поверхности и достаточно понятно
          Я тоже так думал. Но решил написать статью, чтобы проверить. Ситуация оказалась противоположной.

          >>По поводу высокомерия, посчитайте количество я в вашем рассказе :)
          Высокомерие — это не то, на какое место вы ставите себя. Это то, на какое место вы ставите других людей.

          >>Ничего, что iPhone упомянут в последним предложении данной статьи?
          Статья и сейчас, и всегда находилась в блоге про iPhone. Сделано это было не случайно.

          >>не стоит предлагать такой метод, как аксиому.
          На поверхности говорите лежит? То, про что я рассказал — это всего лишь одна из практик test-driven development, описанная в книге Кента Бека. :) Там где-то ближе к концу книжки, посмотрите. Но при этом я изложил свой взгляд на вещи, который сложился не в результате заучивания большого количества книг, но в результате большого количества практики. Именно поэтому, когда вы чувствуете код, книги по паттернам можно отложить, а рефакторинг из чего-то научного превращается в повседневное и естественное. Но об этом статья. А вы говорите — «на поверхности». :) Не пришлось бы мне тогда еще самому себе критику в комментах писать, чтобы разжевать для доходчивости.
  • > У хороших-же программистов паттерны выскакивают прямо из-под клавиатуры. Сами по себе.

    Да, и у хороших конструкторов механические транспортные средства с двумя колесами выскакивают сами по себе…
Только авторизованные пользователи могут оставлять комментарии. Авторизуйтесь, пожалуйста.