Управление качеством кода — как писать элегантный код

внешний интерфейс модульный тест функциональное программирование CSS

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

Примечание. Большая часть контента взята из Интернета, мнения нескольких статей были объединены и обработаны, а также включены некоторые личные мнения.

в общем

  • Принцип единой ответственности

  • Принцип простоты использования

  • принцип удобочитаемости

  • Принцип сохранения сложности: как бы вы ни кодировали, сложность никогда не исчезнет.

    Примечание. Если логика сложная, код должен выглядеть сложным. Если логика проста, код должен выглядеть просто.

Принцип единой ответственности

Один из пяти основных принципов объектно-ориентированных шаблонов проектирования. которыйЧасть кода должна использоваться только для определенной функции и не должна сочетаться с другими функциями..

Предположим, одна из ваших функций реализует и функцию a, и функцию b, а затем требования меняются, вам нужно изменить функцию a, но, поскольку эти две функции находятся в одной функции, вы должны подтвердить, повлияет ли это на функцию b. Это создает ненужные затраты.

Ниже я резюмирую три принципа разделения кода:

Принцип «И»

Когда вам нужно добавить «и» на имя вашего метода, пришло время рассмотреть метод.

Принцип «100»

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

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

Принцип разделения команд и запросов

Большинство операций в нашей разработке можно охарактеризовать как «команды» и «запросы». Например, запись файлов cookie, изменение данных и отправка почтовых запросов можно назвать «командами», а чтение файлов cookie и ajax для получения данных — «командами». операции "запрос".

В функциональном программировании подчеркивается «неизменяемость данных», то есть:

Только чистые функции без побочных эффектов являются квалифицированными функциями.

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

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

Разделение «команды» и «запроса» на самом деле является частью идеи функционального программирования, см. следующий код:

function getFirstName() {
    var firstName = document.querySelector("#firstName").value;
    firstName = firstName.toLowerCase();
    setCookie("firstName", firstName);
    if (firstName === null) {
        return "";
    }
    return firstName;
}
 
var activeFirstName = getFirstName();

Судя по названию, этот метод используется для получения первого имени, но на самом деле он также устанавливает cookie, чего мы не ожидали. Для метода "запрос" он не должен иметь никакого поведения по изменению переменных вне метода, т.е. "побочных эффектов". Лучше написать так:

function getFirstName() {
    var firstName = document.querySelector("#firstName").value
    if (firstName === null) {
        return "";
    }
    return firstName;
}
 
setCookie("firstName", getFirstName().toLowerCase());

На первый взгляд, getFirstName возвращает только firstName, а операция set cookie происходит вне его.

Принцип простоты использования

Простой

Простота здесь в основном сводится к некоторым принципам проектирования функции, а именно: простота вызова, простота понимания, снижение затрат памяти и обработка параметров.

Таким образом, я просто хочу изменить цвет, ширину и другие атрибуты DOM.Нативный код выглядит следующим образом:

document.querySelector('#id').style.color = 'red'
document.querySelector('#id').style.width = '123px'
document.querySelector('#id').style.height = '456px'

И после упаковки:

function a(selector, color, width, height) {
  document.querySelector(selector).style.color = color
  document.querySelector(selector).style.width = width
  document.querySelector(selector).style.height = height
}
a('#a', 'red')

стать мгновенноПростой Доступный~

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

function letSomeElementChange(selector, color, width, height) {
  document.querySelector(selector).style.color = color
  document.querySelector(selector).style.width = width
  document.querySelector(selector).style.height = height
}

Таким образом, мы можем сразу увидеть, что делает метод, но еще есть место для оптимизации. Кто может запомнить такое длинное название метода?Уменьшить стоимость памятиА, другое имя:

function setElement(selector, color, width, height) {
  document.querySelector(selector).style.color = color
  document.querySelector(selector).style.width = width
  document.querySelector(selector).style.height = height
}

Хорошо, до сих пор этот метод выполнял свои обязанности и работал хорошо, но он все еще кажется странным. Эта куча параметров слишком раздражает. . .

function setElement(selector, opt) {
  const { color, width, height } = opt
  color && document.querySelector(selector).style.color = color
  width && document.querySelector(selector).style.width = width
  height && document.querySelector(selector).style.height = height
}

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

последовательность

Если есть такой метод, получите список песен и установите его в значение innerText div:

function getSongs() {
    return $.get('/songs).then((response) {
        div.innerText = response.songs
  })
}

Это нарушает методКонсистенция внутри и снаружи, что также нарушает вышеизложенноеПринцип единой ответственностисерединаПринцип разделения команд и запросов, потому что он не только получает список воспроизведения, но и изменяет innerText, чтобы сделать его более разумным:

  • или изменить имя
  • Либо разделить на два метода

низкое сцепление

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

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

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

высокая сплоченность

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

Сплоченность — это мера силы связи между переменными и методами в классе..高内聚是值得要的,因为它意味着类可以更好地执行一项工作。低内聚是不好的,因为它表明类中的元素之间很少相关。每个方法也应该高内聚,大多数的方法只执行一个功能,不要在方法中添加‘额外’的指令,这样会导致方法执行更多的函数,同时也违反了上文的Принцип единой ответственности.

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

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

Обработка ошибок

  • Предсказуемое неправильное использование: ajax, такие как обратный вызов, параметры функции, такие проблемы решены, только еще один шаг к рассмотрению в развитии различных экстремальных условий может сделать совместимым.
  • Непредвиденные ошибки: похожие на проблемы с совместимостью, ошибки, которые нельзя точно предвидеть во время разработки, вы можете быть готовы выдавать ошибки, console.error/log/warn, и, наконец, вы можете оставить какой-то выход для своей программы: попробуйте ...catch .

принцип удобочитаемости

имя

Именование должно гарантировать, что другие могут сразу увидеть, что содержит переменная или для чего используется метод.

  • Существительные, используемые для общих переменных и атрибутов, следующие:

    var person = {
        name: 'Frank'
    }
    var student = {
        grade: 3,
        class: 2
    }
    
  • Переменные BOOL используются атрибуты (прилагательные) или (являются глаголом) или (модальный глагол) или (HASX), следующим образом:

    var person = {
        dead: false, // 如果是形容词,前面就没必要加 is,比如isDead 就很废话
        canSpeak: true, //情态动词有 can、should、will、need 等,情态动词后面接动词
        isVip: true, // be 动词有 is、was 等,后面一般接名词
        hasChildren: true, // has 加名词
    }
    
  • Общие функции, методы начинаются с (глагол):

    var person = {
        run(){}, // 不及物动词
        drinkWater(){}, // 及物动词
        eat(foo){}, // 及物动词加参数(参数是名词)
    }
    
  • Обратный вызов, функция ловушки:

    var person = {
        beforeDie(){},
        afterDie(){},
        // 或者
        willDie(){}
        dead(){} // 这里跟 bool 冲突,你只要不同时暴露 bool dead 和函数 dead 就行,怕冲突就用上面的 afterDie
    }
    button.addEventListener('click', onButtonClick)
    var component = {
        beforeCreate(){},
        created(){},
        beforeMount(){}
    }
    
  • согласованность имен

    • Последовательная согласованность: например, порядок updateContainerWidth и updateHeightOfContainer неудобен
    • постоянство времени: Возможно, что с изменениями кода значение переменной отличается от ее первоначального значения.В это время вам нужно вовремя изменить имя переменной. Это сделать сложнее всего, потому что код написать легко, а изменить код сложно. Если этот код плохо организован, то, вероятно, возникнет ситуация, затрагивающая все тело (например, глобальные переменные сложно изменить)

Примечания

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

/**
 * [function_name description]
 * @param  {[type]} argument [description]
 * @return {[type]}          [description]
 */
function function_name(argument) {
  // body...
}

Четко напишите параметры и возвращаемые значения метода.Среда IDE, которую я сейчас использую, великолепна, используяDocblockrПлагин умеет автоматически генерировать форматированные комментарии, что очень удобно.

Bad Smell

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

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

гид по стилю

  1. правильно назван: класс должен быть написан с "-", не используйте верблюжий регистр и подчеркивание.

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

  3. отказаться от копирования: Если вы хотите повторно использовать существующий стиль, вы можете напрямую использовать синтаксис ",", чтобы отделить исходный класс, и вы можете применить его. Не копируйте другой стиль, и будут применены оба стиля. Вы должны рассмотреть эту проблему. стиля покрытия.Очень недружелюбно.

  4. класс злоупотреблений: Не добавляйте ненужные классы.Для добавления каждого класса должна быть четкая причина. Неправильное использование классов может привести к переопределению стиля, и стиль используется там, где этот стиль не должен применяться.

  5. Используйте с осторожностью!important, он принудительно переопределит все стили одного и того же атрибута. После его использования код будет сложно поддерживать. Никогда не полагайтесь на этот метод в процессе разработки. Некоторые виды использования приведены ниже.!importantопыт в:

    • Обязательно оптимизируйте, рассмотрите возможность использования приоритета правил стиля для решения проблемы вместо !important
    • Используйте !important только на определенных страницах, которые должны переопределять общесайтовые или внешние css (например, ссылки на ExtJ или YUI).
    • Его можно использовать для решения неотложных онлайн-проблем, но код необходимо как можно скорее заменить обратно удобным для сопровождения способом.
    • Никогда не используйте !important на CSS для всего сайта
    • Никогда не используйте !important в своем плагине

Проще сказать, чем сделать

эффект разбитого окна

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

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

Наконец, сделайте слабую слабую рекламу,мой блог, приветствую советы великих богов из всех слоев общества

Справочная статья: