Я ищу руководство по соединению DRY vs Code. Я не люблю дублировать мой код, а также мне не нравится связывание кода между несвязанными модулями. Поэтому я реорганизую дублирующий код, если найду идентично дублирующий код через год после того, как дублирование было введено. Однако я все чаще сталкиваюсь с ситуациями, когда реальный мир становится гораздо более непредсказуемым, и после рефакторинга кода возникают ситуации, которые требуют повторного раскладывания кода.
Например, если бы у меня был код для работы с бензиновыми автомобилями, бензиновыми внедорожниками, электромобилями и электрическими внедорожниками, допустим, я преобразовал дублирующий код в иерархию «бензин» и «электрическую», обе из иерархии «транспортных средств». Все идет нормально. И затем, моя компания представляет гибридный автомобиль и гибридный Semi, что потребует внесения основных изменений в мою первоначальную иерархию. Возможно, для этого потребуется «состав» между бензином и электрической иерархией.
Очевидно, что дублирование кода является плохим, потому что оно увеличивает время, необходимое для реализации изменений, общих для всех вышеупомянутых продуктов. Но рефакторинг общего кода делает одинаково трудным введение специфичных для продукта вариаций и приводит к большому количеству «скачков классов», когда нужно найти строку кода, чтобы исправить ошибку - одно изменение в родительском классе более высокого уровня может вызвать триггеры регрессии ошибок среди всех потомков.
Как найти оптимальный баланс между СУХОЙ и нежелательной связью кода?
Ответы:
Я думаю, что это одна из главных причин, почему люди переходят к композиции, а не к наследованию.
Наследование вынуждает вас к большой реструктуризации, когда у вас есть концептуальные изменения, подобные описанным вами.
Когда реструктуризация «слишком большая / сложная», люди пишут дублирующий код, чтобы избежать этого.
Вместо удаления дубликата путем перемещения кода вверх по цепочке наследования вы можете переместить его в вспомогательный класс или службу, а затем внедрить этот класс как часть композиции, где это необходимо.
Является ли полученный дизайн ООП открыт для обсуждения
источник
Вы правы, следуя принципу СУХОЙ, вы можете увеличить связь между в противном случае не связанными модулями. Особенно в больших программных системах это может привести к ситуациям, когда не следование DRY может быть лучшей альтернативой.
К сожалению, ваш пример не очень подходит для демонстрации этого - описанные проблемы вызваны классическими ошибками при
неправильномнеоптимальном использовании наследования. Тем не менее, для того, что я написал выше, не имеет значения, будете ли вы преобразовывать общий код в общий базовый класс или в вспомогательный класс (состав). В обоих случаях можно заставить общий код поместить в библиотеку L и сослаться на эту библиотеку из двух ранее не связанных программ A и B.Давайте предположим, что A и B были совершенно не связаны ранее, они могут быть версионированы, выпущены и развернуты независимо. Однако, помещая общий код в разделяемую библиотеку L, новые требования для A могут вызвать изменения в L, что теперь может вызвать изменения в B. Таким образом, это вызывает необходимость в дополнительных тестах и, возможно, новом цикле выпуска и развертывания для B.
Итак, как вы можете справиться с этой ситуацией, если вы не готовы отказаться от принципа СУХОЙ? Ну, есть несколько известных тактик, чтобы подойти к этому:
Либо держите A, B и L как часть одного и того же продукта с одним общим номером версии, общим процессом сборки, выпуска и развертывания с высокой степенью автоматизации
или сделать L продуктом самостоятельно, с младшими номерами версий (без несовместимых изменений) и номерами основных версий (возможно, содержащих критические изменения), и пусть A и B позволяют каждому ссылаться на разные строки версии L.
Сделайте L как можно более твердым, и позаботьтесь о обратной совместимости. Чем больше модулей в L может быть повторно использовано без модификации (OCP), тем менее вероятны критические изменения. И другие принципы «SOLID» помогают поддерживать эту цель.
Используйте автоматические тесты, особенно для L, но также для A и B.
Будьте осторожны с тем, что вы вкладываете в L. Бизнес-логика, которая должна существовать только в одном месте системы, является хорошим кандидатом. Вещи, которые просто «выглядят одинаково» и могут измениться в будущем, являются плохими кандидатами.
Обратите внимание, что когда A и B разрабатываются, поддерживаются и развиваются разными, не связанными между собой командами, принцип DRY становится гораздо менее важным - DRY подразумевает ремонтопригодность и эволюционируемость, но предоставление двум разным командам индивидуального обслуживания может иногда оказаться более эффективным, чем связывание их продуктов. вместе из-за небольшого повторного использования.
Так что, в конце концов, это компромисс. Если вы хотите следовать принципу СУХОЙ в больших системах, вам нужно приложить гораздо больше усилий для создания надежных, повторно используемых компонентов - как правило, больше, чем вы ожидаете. Вы должны доверять своему суждению, когда оно того стоит, а когда нет.
источник
СУХОЙ - это еще одно структурное правило. Это означает, что если вы доведите это до крайности, это так же плохо, как если бы вы игнорировали это. Вот метафора, чтобы вывести вас из структурного мышления.
Люблю твоих близнецов. Убей клонов.
Когда вы слепо копируете и вставляете текст, чтобы избежать ввода с клавиатуры, вы бездумно создаете клоны. Конечно, они делают то, что вы хотите, но они отягощают вас, потому что теперь изменение этого поведения обходится очень дорого.
Когда вы воспроизводите идентичное поведение с идентичным кодом из-за разной ответственности, теперь возникает одна и та же потребность, но это может подвергнуть вас различным изменениям, у вас есть близнец, который может свободно изменяться и расти как личность с течением времени.
Вы можете сканировать их ДНК (код) все, что вам нравится. Клонов и близнецов трудно отличить друг от друга, если вы только смотрите на них. Вам нужно понять контекст, в котором они живут. Почему они родились. Какова будет их окончательная судьба.
Допустим, вы работаете в компании ABC. Он управляется тремя руководителями компаний, A, B и C. Все они хотят, чтобы вы создали программный продукт, но у каждого из них есть свои отделы. Все они хотят, чтобы вы начали с малого. Просто выведите простое сообщение на данный момент. Итак, вы пишете «Hello World».
Ненавидит, хочет, чтобы вы указали название компании.
B любит это, хочет, чтобы вы оставили это в покое и добавили название компании на заставку.
Си просто хочет калькулятор и подумал, что сообщение - это просто способ начать.
В одном вы уверены, у этих ребят совершенно разные представления о том, о чем этот проект. Иногда они соглашаются. Иногда они будут тянуть вас в разные стороны.
Когда вы дублируете код, потому что вы создаете возможность его независимого изменения, вы создаете двойника. Когда вы дублируете код, потому что набирать текст просто, а копировать и вставлять легко, вы создаете злых клонов.
A, B и C - разные мастера, которым должен служить ваш код. Ни одна строка кода не может долго обслуживать более одного мастера.
источник