- PVSM.RU - https://www.pvsm.ru -
Львиная доля программистов с чистой совестью заявит, что предпочитает решать задачи просто, руководствуясь прежде всего здравым смыслом. Вот только это "просто" у каждого свое и как правило отличное от других. После одного долгого и неконструтивного спора с коллегой я решил изложить, что именно считаю простым сам и почему. Это не привело к немедленному согласию, но позволило понять логику друг друга и свести к минимуму лишние дискуссии.
Особенности
Отсюда рекомендация — в идеале иметь не более трех членов в интерфейсе, трех параметров в методе и так далее и не допускать увеличение их количества свыше девяти.
Этот критерий может быть реализован средствами статического анализа.
Самое важное — в первых двух строках любого класса.
В результате мы знаем о классе все, что необходимо для его использования (имя, параметры, входы, выходы), даже не заглядывая в оставшийся код.
Разумеется, это работает при условии ограничений:
И этот критерий может быть реализован средствами статического анализа.
Один тип — одна задача. Контракты — интерфейсам, реализации — классам, алгоритмы — методам!
Мультитулы хороши только если ничего другого под рукой вообще нет. Благодаря первым двум критериям писать такие типы несложно. Да, это принцип единственной ответственности [2] (и разделения интерфейсов [3] до кучи)
А вот здесь статический анализ придется доверить человеку.
Ограничения — такая же легальная часть контракта, как и сигнатуры методов.
И следовательно...
Статический анализ тут может помочь лишь рекомендациями по использованию более простых вариантов типов, если их увидит.
Максимальное удобство для повторного использования.
Применяйте наследование интерфейсов, избегайте наследования реализаций и получите сразу три источника повторного использования кода
Да, это принцип подстановки Лисков [4] в максимально простой и практичной форме.
Статический анализатор может сообщать об использовании нежелательного наследования реализации.
Также не стоит прятать типы или методы "на всякий случай". Публичным должно быть все, кроме того, что необходимо спрятать как детали реализации.
Ваши типы должны быть более простыми для композиции, декорирования, адаптации, организации фасада и т.п., чем для изменения. При соблюдении предыдущих критериев этого добиться несложно.
Это позволит как можно больше изменений свести к добавлению нового кода вместо переписывания текущего, что уменьшит регрессию и необходимость править еще и старые тесты.
Идеальный пример — методы расширения интерфейсов, добавляющие функциональность с одной стороны и никак не меняющие исходные контракт и реализацию с другой.
Да, это принцип открытости-закрытости [5].
Нет, статический анализ тут мало чем поможет
Типы параметров конструктора должны как можно больше говорить о том, как надо использовать их значение.
Например:
Увы, статический анализ мало чем тут поможет.
Маленькие типы лучше больших, так как даже плохо спроектированные или реализованные маленькие типы намного проще исправить, переписать или удалить по сравнению с большими.
Большое количество маленьких типов не является само по себе фатальной проблемой, так как типы — это не список, а граф. В голове одновременно достаточно держать связи текущего типа, а их количество ограничивается первым критерием.
Зависимости типов между собой необходимо ограничивать
Целью является максимальное упрощение графа зависимостей типов. Это помогает как при навигации по коду, так и при определении возможного аффекта от тех или иных изменений.
Да, в этот критерий входит принцип инверсии зависимостей [6].
Да, тут может помочь статический анализ.
То же, что и девятый критерий, но для сборок. Сильно упрощает жизнь и ускоряет сборку, особенно если сразу проектировать с его учетом. Для сборок с контрактами проще поддерживать обратную совместимость (опубликованные контракты не меняются). Сборки же с реализациями можно заменять целиком — они все равно друг от друга напрямую не зависят.
Средствами статического анализа можно воспретить одним сборкам ссылаться на другие.
Все предыдущие критерии могут быть нарушены при необходимости оптимизации. Но одно, на мой взгляд работает всегда:
Проще оптимизировать корректный код, чем корректировать оптимизированный.
Письменное изложение собственных представлений многое прояснило для меня самого.
Хотелось бы увидеть ваши критерии простоты в комментариях.
Упоминания статического анализа означают возможность реализации, а не ее наличие на текущий момент.
Дополнения и критика традиционно приветствуются.
Автор: Bonart
Источник [7]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/c-2/200515
Ссылки в тексте:
[1] мозга: http://www.braintools.ru
[2] принцип единственной ответственности: https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B8%D0%BD%D1%86%D0%B8%D0%BF_%D0%B5%D0%B4%D0%B8%D0%BD%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9_%D0%BE%D0%B1%D1%8F%D0%B7%D0%B0%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D0%B8
[3] разделения интерфейсов: https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B8%D0%BD%D1%86%D0%B8%D0%BF_%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81%D0%B0
[4] принцип подстановки Лисков: https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B8%D0%BD%D1%86%D0%B8%D0%BF_%D0%BF%D0%BE%D0%B4%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B8_%D0%91%D0%B0%D1%80%D0%B1%D0%B0%D1%80%D1%8B_%D0%9B%D0%B8%D1%81%D0%BA%D0%BE%D0%B2
[5] принцип открытости-закрытости: https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B8%D0%BD%D1%86%D0%B8%D0%BF_%D0%BE%D1%82%D0%BA%D1%80%D1%8B%D1%82%D0%BE%D1%81%D1%82%D0%B8/%D0%B7%D0%B0%D0%BA%D1%80%D1%8B%D1%82%D0%BE%D1%81%D1%82%D0%B8
[6] принцип инверсии зависимостей: https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B8%D0%BD%D1%86%D0%B8%D0%BF_%D0%B8%D0%BD%D0%B2%D0%B5%D1%80%D1%81%D0%B8%D0%B8_%D0%B7%D0%B0%D0%B2%D0%B8%D1%81%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B5%D0%B9
[7] Источник: https://habrahabr.ru/post/312950/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.