Я пишу код Ruby для простого упражнения по шифрованию и часто сталкиваюсь с этой дилеммой (упражнение является пасьянсом, если вы должны знать). Вопрос в том, должен ли я дополнить свою логику описательными переменными и одношаговыми операторами, которые делают функцию читабельной вместо кратких, даже плотных, которые исключают повторение и / или сводят к минимуму вероятность ошибок.
Мой самый последний пример: моя программа принимает ввод, и из-за жестких правил форматирования, она может легко определить, должен ли ввод быть зашифрован или расшифрован. Чтобы упростить, после того, как ключ шифрования и сообщение преобразованы / сгенерированы для совместимости, необходимо вычесть ключ из зашифрованного сообщения или добавить ключ в незашифрованное сообщение, чтобы получить желаемый результат (думайте о ключе как о шифровании, сообщение + шифрование = код; код - шифрование = сообщение). Позиция СУХОЙ говорит мне, что я должен преобразовать свое зашифрованное сообщение не так, как мое незашифрованное сообщение, так что функция, которая берет ключ шифрования и применяет его к сообщению, никогда не должна различаться. Я обнаружил, что это означает, что мне нужны вложенные операторы if в функции, но логика кажется твердой. Этот код, однако, не легко читается.
С другой стороны, я мог бы написать две разные функции, которые вызываются на основе флага, который устанавливается, когда приложение определяет шифрование или дешифрование. Это было бы проще для чтения, но дублировало бы функцию высокого уровня применения ключа шифрования к сообщению (вызывая его шифрование или дешифрование).
Должен ли я склоняться к читабельному коду или лаконичному коду? Или я пропустил другой способ получить эту функциональность и удовлетворить оба принципа? Является ли это позицией такого масштаба, в которой нужно учитывать цель проекта и принимать наилучшие решения для достижения этой цели?
Пока что я склонен подчеркивать сжатый, СУХОЙ код над читаемым кодом.
Ответы:
СУХОЙ - это руководство, а не религия. Те, кто доводит это до уровня СУХОГО превыше всего, зашли слишком далеко.
Прежде всего, полезный код имеет первостепенное значение. Если код бесполезен и пригоден для использования, это не так ... и нет смысла писать его в первую очередь.
Во-вторых, однажды кому-то придется поддерживать ваш код. Если ваш код не подлежит сопровождению, он сломает ваш «красивый» плотный, лаконичный, СУХОЙ дизайн, проклиная ваше имя. Не делай этого. Я был этим человеком, и каждый раз, когда я вижу определенное имя в аннотации кода, я дрожу.
Создание плотного кода, в котором отсутствуют «описательные переменные», и встраивание всего во вложенные троичные выражения с лямбдами без какой-либо документации - это разумно. Приятно знать, что ты можешь это сделать, но не делай этого. Умный код очень сложно отлаживать. Избегайте написания умного кода .
Большая часть времени, затрачиваемого на программное обеспечение, тратится на его обслуживание, а не на его написание в первый раз. Напишите код, чтобы вы (или кто-то еще) могли быстро и легко исправлять ошибки и добавлять необходимые функции с минимальными изменениями в идеальном дизайне.
источник
Я не уверен, исходя из вопроса, который вы понимаете, СУХОЙ. СУХОЙ код не совпадает с кратким. Довольно часто это наоборот.
Здесь я не уверен, в чём дело для этого примера. Сделайте функцию для шифрования, функцию для дешифрования, вспомогательные средства для общей функциональности (смесь байтов) и простой интерфейс для ввода и определения шифрования / дешифрования ... Не повторяйте себя.
В целом, как DRY, так и удобочитаемость существуют для поддержки и расширения кода. Не все сценарии одинаковы, большой удар по читабельности для удаления небольшого повторения не годится, и также не существует кучки дублирования, чтобы добавить немного читабельности.
Если нажать, я бы предпочел удобочитаемость. Повторяющийся код все еще можно проверить - нечитаемый код ведет к тому, что вы делаете (и тестируете) неправильные вещи.
источник
Я не знаком с вашим конкретным случаем, но могу дать некоторые общие рекомендации.
Целью как читаемости, так и СУХОГО является ремонтопригодность .
Поддержка в большинстве случаев важна, так как вы тратите больше времени на поддержку кода, чем на его написание. Это особенно верно, если вы считаете написание кода специальным видом обслуживания.
К сожалению, СУХОЙ часто понимают неправильно. Это отчасти потому, что это кажется таким простым, но, как и множество простых вещей, это может быть, ну ... сложно.
Целью СУХОГО является то, что каждая функциональная единица существует только в одном месте. Если следовать этому принципу, сопровождающий код, которому поручено изменить или проверить эту функциональность, может обработать код за один раз. Если DRY не соблюдается, существует реальная опасность того, что некоторая копия функциональности не будет поддерживаться должным образом.
Наиболее явным нарушением DRY является кодирование с копированием-вставкой, когда целые блоки кода дословно повторяются в базе кода. Это удивительно часто встречается в моем опыте, и никоим образом это не добавляет читабельности. Следовательно, рефакторинг кода для введения общего метода неизменно повышает соответствие DRY и читабельность.
Вторым наиболее очевидным нарушением является «копировать-вставить и немного его изменить». Опять же, рефакторинг для введения метода comon с параметрами или разбиение функции на этапы и абстрагирование от общих черт почти всегда повышает удобочитаемость.
Тогда есть более тонкие нарушения, где функциональность дублируется, но код отличается. Это не всегда легко обнаружить, но когда вы видите его и выполняете рефакторинг для извлечения общего кода в единый метод / класс / функцию, тогда код обычно более читабелен, чем был раньше.
Наконец, есть случаи повторения дизайна. Например, вы могли использовать шаблон состояния несколько раз в своей базе кода, и вы рассматриваете возможность рефакторинга, чтобы устранить это повторение. В этом случае действуйте с осторожностью. Вы можете уменьшить читабельность, введя больше уровней абстракции. В то же время вы имеете дело не с дублированием функциональности, а с дублированием абстракции. Иногда это того стоит ... но часто это не так. Ваш руководящий принцип будет заключаться в том, чтобы спросить, "какой из них более ремонтопригоден".
Всякий раз, когда я делаю эти суждения, я стараюсь учитывать, сколько времени люди потратят на поддержание кода. Если код является основной бизнес-функциональностью, он, вероятно, нуждается в дополнительном обслуживании. В этих случаях я стремлюсь сделать код поддерживаемым для людей, которые знакомы с базой кода и задействованными абстракциями. Я был бы счастлив представить немного больше абстракции, чтобы уменьшить количество повторений. Напротив, скрипт, который редко используется и редко поддерживается, может быть менее понятным для сопровождающих, если он включает в себя слишком много абстракции. В этом случае я бы ошибся на стороне повторения.
Я также считаю уровень опыта других членов моей команды. Я избегаю "причудливых" абстракций с неопытными разработчиками, но использую непризнанные шаблоны проектирования с более зрелыми группами.
В заключение, ответ на ваш вопрос заключается в том, чтобы сделать то, что делает ваш код максимально поддерживаемым. Что это означает в вашем сценарии, решать вам.
источник
Если ваши функции становятся более сложными и более длинными (то есть менее читабельными), когда вы пытаетесь сделать их СУХИМЫМИ, то вы делаете это неправильно. Вы пытаетесь поместить слишком много функциональности в одну функцию, потому что думаете, что это единственный способ избежать повторения одних и тех же фрагментов кода во второй функции.
Создание кода СУХОЙ почти всегда означает рефакторинг общей функциональности для более мелких функций. Каждая из этих функций должна быть проще (и, следовательно, более читабельной), чем оригинальная. Чтобы сохранить все в исходной функции на том же уровне абстракции, это также может означать рефакторинг дополнительных деталей, которые не используются в других местах. Ваша исходная функция затем становится «функцией высокого уровня», вызывая меньшие, и она также становится меньше и проще.
Следовательно, это в основном приводит к различным уровням абстракций в вашем коде - и некоторые люди считают, что такой код менее читабелен. По моему опыту, это заблуждение. Ключевой момент здесь состоит в том, чтобы дать мелким функциям хорошие имена, ввести хорошо названные типы данных и абстракции, которые могут быть легко поняты вторым человеком. Таким образом, «СУХОЙ» и «читабельность» должны очень и очень редко вступать в конфликт.
источник
Хотя я не уверен в том, что именно является причиной проблемы, мой опыт заключается в том, что когда вы обнаружите, что СУХОЙ и читабельность противоречат друг другу, это говорит о том, что пришло время что-то реорганизовать.
источник
Я бы выбрал удобочитаемый (= поддерживаемый) вместо СУХОГО в любой день недели. В действительности оба часто совпадают, и тот, кто понимает DRY, обычно создает (в основном) читаемый код.
источник
Очень-очень-очень-очень редко в моей карьере я обнаружил законный случай, который противопоставляет читаемость сухому. Сделайте это читабельным в первую очередь. Назовите вещи хорошо. Скопируйте и вставьте, если это необходимо.
Теперь отступите назад и посмотрите на все, что вы создали, как на художника, отступающего назад, чтобы посмотреть на свою картину. Теперь вы можете правильно определить повторение.
Повторный код должен быть либо реорганизован в свой собственный метод, либо извлечен в свой собственный класс.
Повторяющийся код должен быть последним средством. Сначала читаемые и СУХИЕ, не читаемые, если вы ограничиваете область повторного кода.
источник