Pull to refresh

О классификации кода

Reading time 4 min
Views 1.6K

О, коде

Когда я пишу код, мне нравится отдавать себе отчёт о том, что именно я делаю.

Например, код, который пишется за одну ночь для демы завтра утром сильно отличается от кода, который станет основным API системы.

В этом посте я бы хотел рассказать о разных типах кода и дать несколько советов, которые помогают мне и ночью перед демой, и при дизайне больших API.



Код «для себя»

Это код, который решает одну задачу один раз в жизни. Это может быть, например, решением «задачки на смекалку», или вызовом какой-нибудь сложной функции, чтобы посмотреть, «как работает», или скриптом, избавляющемся от каждой третьей точки в файле, или «Hello, world!» на новом языке.

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

Код прототипа

Это код, который должен реализовать минимальную функциональность какой-нибудь новой фичи. Это может быть практически всем, чем угодно: и пробной интеграцией с другим продуктом, и принципиально новой функциональностью, и новой фичей существующего продукта. Зачастую реализацию прототипа надо закончить в короткие сроки.

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

Есть ещё одно важное правило. Если для работы прототипа необходимо поменять старый код, изменение должно иметь комментарий. Хотя изменение может быть очевидно в момент написания прототипа, через несколько месяцев будет очень сложно понять, что же хотелось сделать. Особенно если прототип пришлось выкинуть.

Основной код

Это код самой системы. То, что релизится, то что тестирует QA, то, что видят пользователи.

Про то, как создавать этот код пишут книжки. Моя любимая – книга МакКоннела Code Complete.

Я не буду останавливаться на общих правилах создания основного кода. Однако, я бы хотел выделить четыре категории основного кода.

API
Это та часть компонента, которой будут пользоваться остальные. Мне очень нравится, когда каждый член команы разработчиков создаёт свой компонент и предоставляет остальным API для использования.

Понятно, что все методы и классы API должны иметь самую лучшую документацию, самые дотошные проверки данных, самые читабельные юнит-тесты.
Ну и, конечно, сам API должен должен быть удобным в использовании. Рекомендую презентацию Блоха How to Design a Good API and Why it Matters.

Точка интеграции
Если я разрабатываю компонент вместе с коллегой, то точки интеграции – это те части кода, которые должен поменять коллега, чтобы интегрировать свои изменения. Самый частый комментарий в таких местах: "//TODO: Your code here".

Точки интеграции должны обладать неплохой документацией (может, не такой дотошной как API). Более того, должно быть понятно, как именно интегрировать свою часть компонента. Иногда помогает пример.

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

Точка роста
Это часть компонента, которая наверняка будет пополняться новыми фичами. Например, это код, который создаёт контекстное меню. По мере роста системы контекстное меню будет, скорее всего, увеличиваться. Другой пример: системы доставки контента. Хотя изначально может поддерживаться лишь одна, скорее всего в будущем нужно будет добавить ещё несколько.
Ясно, что для таких точек используются шаблоны factory method и abstract factory.

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

Я специально выделил точки роста в отдельную категорию. Очень важно понять рано, что данный кусочек кода является точкой роста. Если этот момент пропустить, то каждое следующее дополнение будет добавлять новые хаки. Если в класса (или файле) больше 2000 строчек, то это, скорее всего, запущенная точка расширения.
Более того, именно в этих точках зачастую появляются зависимости от других компонентов. Это ещё один аргумент в пользу выделения точек роста в отдельный класс (или файл).

Остальной код
А это всё остальное. Про этот тип кода написано много статей. Я стараюсь писать этот код так, чтобы через полгода мне было приятно его читать.

Заключение

Мне кажется, что очень важно отдавать себе отчёт о том, какой именно код сейчас пишешь. Это и ускоряет процесс разработки, и делает код лучше.

Какие ещё типы кода стоит выделить? Может, стоит добавить какие-нибудь советы?
Tags:
Hubs:
+85
Comments 46
Comments Comments 46

Articles