Чистый код
About
Заметка еще процессе работы....
Архитектура
Technical debt
#code_debt
В случае, когда в коде намеренно реализуется плохое решение, явно это указывать тегом #code_debt. Можно TODO: code_dept что бы не терялось (ЕСЛИ в вашем проекте это не теряется), или заводить issue, если это поможет когда-нибудь исправить код.
#depends
Очень часты ситуации, в которых один код неявно зависит от исполнения другого. Вообще это самые опасные дырки в построении программы, но всякое бывает. Это могут быть юнит тесты, которые должны исполняться в определенном порядке, или классы, которые общаются через абстрактный интерфейс и на инициализации обязательно нужен определенный порядок вызова.
Кроме человека, который написал этот код, никто с ходу не сможет сказать что там есть зависимость.
В момент, когда в нашем коде появляется неявная зависимость от другого куска, единственный способ это не забыть - написать #depends %от%, желательно с подробностями расписав что и где может сломаться
#depends
Очень часты ситуации, в которых один код неявно зависит от исполнения другого. Вообще это самые опасные дырки в построении программы, но всякое бывает. Это могут быть юнит тесты, которые должны исполняться в определенном порядке, или классы, которые общаются через абстрактный интерфейс и на инициализации обязательно нужен определенный порядок вызова.
Кроме человека, который написал этот код, никто с ходу не сможет сказать что там есть зависимость.
В момент, когда в нашем коде появляется неявная зависимость от другого куска, единственный способ это не забыть - написать #depends %от%, желательно с подробностями расписав что и где может сломаться
Функции
Документирование
pure/nonpure
Pure-свойство функции - изменяет ли или не изменяет состояние приложения функция в процессе своей работы. При документировании указывается два флага - #pure и #nonpure. Указывать их важно не в любом случае (Хотя и не помешает), а только в тех случаях, когда название функции не согласовывается с тем, что она делает. Например, для функций с припиской get, is, find, подразумевается pure исполнение, однако, если в процессе своей работы, функция getValue еще и меняет какие-то значения, важно отметить ее как #nonpure
reusable
reusable свойство указывает на то, что nonpure функцию можно вызывать повторно с другими аргументами, и при этом она подчистит старые изменения до того состояния, как если бы она вызывалась в первый раз. Например, функция setParent сначала удалит себя из списка детей своего родителя, потом удалит ссылку на своего родителя, и только потом отработает в нормальном режиме
Тесты
Глобально тесты можно разделить на два типа: покрывающие чистый и покрывающие пахнущий код. Принципиальная разница - тесты, покрывающие чистый код, должны сигнализировать о том, что программа работает так, как изначально задумана на архитектурном уровне. Тесты для пахнущего кода, это тесты, подтверждающие, что этот костыль работает при определенных условиях кода, которые были когда этот тест писался
Тесты чистого кода
- Эти тесты являются документацией кода и подтверждением его работы
- Если хотя бы один такой тест не проходит проверку, это означает, что программа не готова к работе
- Падение такого теста должно означать изменение в архитектуре, а значит это затрагивает весь код, который от нее зависит
- Они должны максимально дотошно покрывать каждую функцию начиная с самых незначительных
- Все результаты должны быть проверены через ассерты. Больше - лучше
- В случае обнаружения багов создается тест 'issue #X' в котором проверяется исправленный сценарий
Тесты пахнущего кода
Вообще принято делать вид, что "пахнущий" код это плохо, бездарно, и это удел новичков и лентяев. Но у любого проекта будут тысячи проблем и несостыковок, и их так же важно тестировать, как и все остальное.
- Падение этих тестов должно означать, что скорее всего пора переписывать сам код
- Сами тесты должны быть простыми и быстрыми - на них не нужно тратить много времени и бояться переписывать
Названия
`Паттерны
get,set,add
Для работы с числовыми функциями всегда использовать три стандартных метода - get,set,add.
- get, в зависимости от ситуации, либо всегда возращает 0 по умолчанию (Для не найденных значений), либо кидает ошибку, тогда это явно указывается в документации (@throws).
- set всегда проверяет на наличие инстанса в данных, и инициализирует поле со значением 0 по умолчанию
- add всегда вызывает set(get() + amount)
Классы
Конструктор - у конструктора не должно быть side-эффектов! Т.е. все, что делает конструктор, это выделяет память, инициализирует переменные и т.п. Т.е. конструктор всегда должен быть pure (Конечно, по отношению к остальной части программы) функцией. Если нужно изменить состояние программы, добавляется метод init в класс, выполняющий все операции
Синглтон
У синглтона два обязательных метода:
- getInstance(), который возвращает указатель но инстанс класса, и создает его если его еще не существует
- init() выполняет все операции, которые имеют side эффекты
Предварительная валидация данных
Для всех классов, работающих напрямую с данными (Например с json в js), всегда вставлять метод, вызываемый из конструктора, и проверяющий наличие всех конфигураций, к которым этот класс может обратиться
Comments
Post a Comment