Есть веская причина для дублирования кода? [закрыто]

В тимелеаф текущие сценарии являются javascript (th: inline = "javascript") и dart (th: inline = "dart").

blockquote>

Используйте следующий фрагмент вместо

20
задан Yvette Colomb 24 October 2018 в 14:00
поделиться

20 ответов

Когда я только начинал программировать, я написал приложение, в котором у меня было множество аналогичных функций, которые я заключил в аккуратную маленькую функцию из 20-30 строк ... Я очень гордился собой за то, что написал такую ​​элегантную часть код.

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

Год спустя, когда меня попросили сделать нечто очень похожее, я сознательно решил проигнорировать DRY. Я собрал базовый процесс и создал весь повторяющийся код. Повторяющийся код был задокументирован, и я сохранил шаблон, использованный для генерации кода. Когда клиент запросил конкретное условное изменение (например, если x == y ^ z + b, то 1 + 2 == 3.42), это было проще простого.

14
ответ дан 29 November 2019 в 22:25
поделиться

Нет веских причин для дублирования кода.

См. Шаблон проектирования Безжалостно рефакторинг .

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

0
ответ дан 29 November 2019 в 22:25
поделиться

У меня нет проблем с дублированием кода, когда он создается генератором исходного кода.

1
ответ дан 29 November 2019 в 22:25
поделиться

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

1
ответ дан 29 November 2019 в 22:25
поделиться

В больших проектах (имеющих кодовую базу размером с ГБ) вполне возможно потерять существующий API. Обычно это происходит из-за недостаточной документации или неспособности программиста найти исходный код; отсюда дублированный код.

Сводится к лени или плохой практике проверки.

РЕДАКТИРОВАТЬ:

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

Вы просматривали историю изменений файла?

1
ответ дан 29 November 2019 в 22:25
поделиться

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

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

править: в те времена, когда компиляторы были дрянными, а оптимизаторы еще более дрянными, могло случиться так, что из-за какой-то ошибки в компиляторе, возможно, пришлось проделать такой трюк, чтобы обойти ошибку . Может это как то? Сколько лет?

1
ответ дан 29 November 2019 в 22:25
поделиться

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

Кроме того, иногда - даже при дублировании логики - стоимость уменьшения дублирования слишком высока. Это может произойти, особенно когда это не просто дублирование кода: например, если у вас есть запись данных с определенными полями, которая повторяется в разных местах (определение таблицы БД, класс C ++, текстовый ввод), обычный способ уменьшить это дублирование происходит с генерацией кода. Это усложняет ваше решение. Почти всегда эта сложность окупается, но иногда нет - это ваш компромисс.

2
ответ дан 29 November 2019 в 22:25
поделиться

Производительность - не единственная проблема. Если вы собираетесь использовать HTTPS, вам действительно нужно убедиться, что весь ваш контент, включая сторонние изображения и библиотеки, доступен через HTTPS. В противном случае вы будете генерировать раздражающие сообщения смешанного содержания в IE:

http://blog.httpwatch.com/2009/04/23/fixing-the-ie-8-warning-do-you-want-to-view -only-the-webpage-content-that-was-delivery-securely /

Это также означает, что вам потребуются отдельные сертификаты SSL для каждого имени хоста, которое вы используете (например, images.example.com) или какой-то SSL-сертификат wild card (например, для * .example.com).

2
ответ дан 29 November 2019 в 22:25
поделиться

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

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

Тем не менее, я не могу думать любого разумного способа оправдать дублирование кода. Посмотрите, почему это плохо.

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

3
ответ дан 29 November 2019 в 22:25
поделиться

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

Пример (псевдокод):

procedure setPropertyStart(adress, mode, value)
begin
  d:=getObject(adress)
  case mode do
  begin
    single: 
       d.setStart(SingleMode, value);
    delta:
       //do some calculations
       d.setStart(DeltaSingle, calculatedValue);
   ...
end;

procedure setPropertyStop(adress, mode, value)
begin
  d:=getObject(adress)
  case mode do
  begin
    single: 
       d.setStop(SingleMode, value);
    delta:
       //do some calculations
       d.setStop(DeltaSingle, calculatedValue);
   ...
end;

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

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

4
ответ дан 29 November 2019 в 22:25
поделиться

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

6
ответ дан 29 November 2019 в 22:25
поделиться

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

Do_A_Policy()
{
  printf("%d",1);
  printf("%d",2);
}

Do_B_Policy()
{
  printf("%d",1);
  printf("%d",2);
}

Теперь вы можете предотвратить «дублирование кода» с помощью такой функции:

first_policy()
{
printf("%d",1);
printf("%d",2);
}

Do_A_Policy()
{
first_policy()
}

Do_B_Policy()
{
first_policy()
}

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

12
ответ дан 29 November 2019 в 22:25
поделиться

Хорошее прочтение об этом - крупномасштабный проект программного обеспечения C ++ Джона Лакос.

У него много хороших замечаний по поводу дублирования кода, когда оно может помочь или помешать проекту.

Самый важный момент - это вопрос, когда решается удалить дублирующийся или повторяющийся код:

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

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

26
ответ дан 29 November 2019 в 22:25
поделиться

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

Нет времени для правильного рефакторинга

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

Обобщение кода невозможно / не «красиво» из-за языковых ограничений

Допустим, глубоко внутри функции у вас есть несколько операторов, которые сильно отличаются от экземпляра к экземпляру одного и того же дублированного кода. Например: У меня есть функция, которая рисует 2-мерный массив миниатюр для видео, и она встроена с вычислением каждой позиции миниатюр. Чтобы вычислить хит-тест (вычислить индекс миниатюр по позиции клика), я использую тот же код, но без рисования.

Вы не уверены, что будет вообще какое-либо обобщение.

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

Я добавлю еще, если вспомню что-то еще.


Добавлено позже .. .

Развертывание цикла

До того, как компиляторы стали такими умными, как Эйнштейн и Хокинг вместе взятые, вам приходилось развертывать циклы или встроенный код, чтобы работать быстрее. Развертывание цикла заставит ваш код дублироваться и, вероятно, быстрее на несколько процентов,

14
ответ дан 29 November 2019 в 22:25
поделиться

Для такого рода дублирования кода (много строк дублируется много раз), я бы сказал:

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

Вероятно, первое решение из того, что я обычно видел: - (

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

Разделение кода на несколько функций, правильное повторное использование кода и все это часто приходит с опытом - или вы не наняли нужных людей; -)

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

Однако в данном случае я не думаю, что они это сделали, хех.

2
ответ дан 29 November 2019 в 22:25
поделиться

Лень, это единственная причина, о которой я могу думать.

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

По-прежнему оставляет неприятный привкус во рту.

16
ответ дан 29 November 2019 в 22:25
поделиться

Брофилд,

У меня была точно такая же проблема, и я просто наткнулся на решение, которое не требует преобразования исходных строк в широкие символы и обратно: сохраните исходный файл как UTF-8 без подписи и VC2008 оставит его в покое. Отлично сработало, когда я придумал опустить подпись. Подводя итог:

Unicode (UTF-8 без подписи) - кодовая страница 65001, не выдает предупреждение c4566 в VC2008 и не заставляет VC вмешиваться в кодировку, тогда как кодовая страница 65001 (UTF-8 с подписью) выдает c4566 (как вы выяснили).

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

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

  • определенно любое использование кода Inline :: C или XS
  • прямое использование ссылок, например \ @ list или \% hash , а не предварительно выделенные ссылки, такие как [qw (foo bar)] (первая создает другую ссылку, которая может потеряться; во втором есть только одна ссылка, о которой нужно беспокоиться,
3
ответ дан 29 November 2019 в 22:25
поделиться

То, что мы обнаружили, заставляло нас дублировать код, было нашим кодом манипулирования пикселями. Мы работаем с ОЧЕНЬ большими изображениями, и накладные расходы на вызов функций съедали порядка 30% нашего времени на каждый пиксель.

Дублирование кода манипулирования пикселями дало нам на 20% более быстрое прохождение изображений за счет сложности кода.

Очевидно, что это очень редкий случай, и в конечном итоге он значительно раздул наш источник (функция 300 строк теперь составляет 1200 строк).

1
ответ дан 29 November 2019 в 22:25
поделиться

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

или, давайте обратимся к цитате Ларри Уолла:

«Мы будем поощрять вас развивать три великие добродетели программиста: лень, нетерпеливость, ха-ха;)

0
ответ дан 29 November 2019 в 22:25
поделиться

Поскольку существует "Паттерн стратегии", нет никакой веской причины для дублирования кода. Ни одна строка кода не должна быть продублирована, все остальное - epic fail.

0
ответ дан 29 November 2019 в 22:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: