4.6 KiB
[DesignByContractAsFoundation] Tags: DBC, CONTRACT, PRECONDITION, POSTCONDITION, INVARIANT, KDOC, REQUIRE, CHECK
Принцип 'Проектирование по контракту' (DbC) — это не опция, а фундаментальная основа моего подхода к разработке. Каждая функция и класс, которые я создаю, являются реализацией формального контракта между поставщиком (код) и клиентом (вызывающий код). Это устраняет двусмысленность, предотвращает ошибки и делает код самодокументируемым и предсказуемым.
Rules
ContractFirstMindset
Я всегда начинаю с проектирования и написания KDoc-контракта. Код является реализацией этой формальной спецификации. Проверки контракта (require, check) создаются до или вместе с основной логикой, а не после как запоздалая мысль.
KDocAsFormalSpecification
KDoc-блок является человекочитаемой формальной спецификацией контракта. Для правильной обработки механизмом Causal Attention, он ВСЕГДА предшествует блоку семантической разметки и декларации функции/класса. Я использую стандартизированный набор тегов для полного описания контракта.
Tags
- @param: Описывает предусловия для конкретного параметра. Что клиент должен гарантировать.
- @return: Описывает постусловия для возвращаемого значения. Что поставщик гарантирует в случае успеха.
- @throws: Описывает условия (обычно нарушение предусловий), при которых будет выброшено исключение. Это часть 'негативного' контракта.
- @invariant: (для класса) Явно описывает инвариант класса — условие, которое должно быть истинным всегда, когда объект не выполняет метод.
- @sideeffect: Четко декларирует любые побочные эффекты (запись в БД, сетевой вызов, изменение внешнего состояния). Если их нет, я явно указываю
@sideeffect Отсутствуют..
PreconditionsWithRequire
Предусловия (обязательства клиента) должны быть проверены в самом начале публичного метода с использованием require(condition) { "Error message" }. Это реализует принцип 'Fail-Fast' — немедленный отказ, если клиент нарушил контракт.
Location: Первые исполняемые строки кода внутри тела функции, сразу после лога [ENTRYPOINT].
PostconditionsWithCheck
Постусловия (гарантии поставщика) должны быть проверены в самом конце метода, прямо перед возвратом управления, с использованием check(condition) { "Error message" }. Это самопроверка, гарантирующая, что моя работа выполнена правильно.
Location: Последние строки кода внутри тела функции, непосредственно перед каждым оператором return.
InvariantsWithInitAndCheck
Инварианты класса (условия, которые всегда должны быть истинны для экземпляра) проверяются в двух местах: в блоке init для гарантии корректного создания объекта, и в конце каждого публичного метода, изменяющего состояние, с помощью check(condition).
Location: Блок init и конец каждого метода-мутатора.
[/End DesignByContractAsFoundation]