Культовый разработчик Кент Бек сформулировал принципы написания ПО, которые в вольном изложении звучат приблизительно так:
1. Заставь код работать.
2. Сделай его понятным.
3. Оптимизируй для лучшей производительности.
Этим основам не один десяток лет, однако джуны (да и старшие порой, будем честны:) спотыкаются уже на втором шаге. В результате получается рабочий, но нечитаемый код, который не просто трудно понять — его нельзя дополнить или исправить, не поломав программу.
Причина проста: на проектной работе важно как можно быстрее выйти на рынок и получить деньги. Джуны спешат разобраться с задачей, не тратя времени на рефакторинг и комментарии.
Обычно до оптимизации дело так и не доходит: важные участки кода скорее «заморозят» и запретят вносить в них изменения, чем перепишут. Беда, если именно в них будет крыться экономическое преимущество системы.
Чистый код существует?
Лирическое отступление
Вопрос на экзамене по программированию: «Что такое Clean Code?»
Студент мучается, пыхтит: «Ну-у-у, там, методы без… э… имена не… Простите, профессор, знал, но забыл!»
Профессор встает и торжественно объявляет аудитории: «Друзья, трагедия! Единственный человек знал про Clean Code — и тот забыл!»
В четком виде теории чистого кода не существует: авторы тематических книг опираются на субъективный опыт и порой противоречат друг другу. В конце концов, всё зависит от задач, которые выполняет код. Однако мы можем выделить несколько эффективных принципов, которые применимы в большинстве случаев.
Принципы написания чистого кода
1. Используйте значимые имена. Назначение переменных, функций, классов и других идентификаторов должно быть понятно из их названия.
Пример (Java):
public void assign(Author author, Book book) { book.setAuthor(author); book.save(); }
По названию метода нельзя определить, что в нём происходит. Это плохо. Конкретизируем имена, и код объяснит сам себя:
public void assignAuthorForBook(Author author, Book book) { book.setAuthor(author); book.save(); }
2. Оставляйте комментарии в сложных участках. Пусть они будут нечастыми, но содержательными. Идеальный код можно понять без дополнительной документации.
Пример (Dart):
Комментарии могут связать код с реальностью и дать объяснение, почему мы решили закодить именно так.
///! category && product открывают одинаковый экран /// Это нужно для обработки диплинков /// Так как на вебе в url может быть либо products, либо category GoRoute( path: CatalogueRoutes.productsItem.path, name: CatalogueRoutes.productsItem.path, builder: (context, state) => CategoryPage( key: state.pageKey, slug: state.pathParameters['slug']!, args: state.extra as CategoryArgsModel?, ), ), GoRoute( path: CatalogueRoutes.categoryItem.path, name: CatalogueRoutes.categoryItem.path, builder: (context, state) => CategoryPage( key: state.pageKey, slug: state.pathParameters['slug']!, args: state.extra as CategoryArgsModel?, ), ),
3. Наводите красоту пустотами. Пробелы, табы и отступы помогут разделить код на логические секции и сделать его удобным для чтения.
Пример (Javascript):
function filterPermissions(permissions, searchQuery) { const q = searchQuery.trim().toLowerCase() if (!q) return permissions const searchDeep = (permission) => filterTree(permission, ({title}) => title.toLowerCase().includes(q)) return permissions.map(searchDeep).filter((v) => v) }
Такими кирпичами только стены строить. Добавим отступы, выстроим лесенку, и наш увесистый блок превращается в прекрасный читабельный код:
function filterPermissions(permissions, searchQuery) { const q = searchQuery.trim().toLowerCase() if (!q) { return permissions } const searchDeep = (permission) => filterTree( permission, ({title}) => title.toLowerCase().includes(q) ) return permissions .map(searchDeep) .filter((v) => v) }
4. Отбрасывайте ненужное. После рефакторинга сразу удаляйте участки, которые больше не несут практической ценности. Не оставляйте на случай «вдруг пригодится» — удалённый кусок всегда можно отыскать в истории Git-а.
Пример (go):
//test_banner := model.Banner{ID: 1, FeatureId: 45, TagIds: []int32{5, 12, 244}} if !banner.IsActive { log.Warn("attempt to get inactive banner") //return model.Banner{ID: -1, FeatureId: -1, TagIds: []int32{}, content {"forbidden! - empty"}} return nil, fmt.Errorf("banner {id:%d, featureId:%d, tagIds:%v} is inactive", banner.ID, banner.FeatureId, banner.TagIds) }
Тестовые строчки в комментариях засоряют код и мешают нормальному чтению. Их нужно сносить беспощадно.
Подведем итоги
Чистый код не только «легко читается». В первую очередь мы говорим о грамотном проектировании системы, которое дает нам куда большие преимущества:
— Код легко расширить без технических затрат. Сущности не связаны между собой слишком тесно.
— Код стабилен и предсказуем. Если появляется проблема, мы уже знаем, куда смотреть.
P.S.
На практике к чистке кода стоит подходить с умом. Помните, что в каждом правиле есть свои исключения. Принципы могут стать хорошим подспорьем, но не основой успеха вашего продукта.
Наши источники
Для статьи мы отбирали советы из книг Роберта Сесила Мартина, Стива Макконнелла и Кента Бека, советовались с практикующими программистами и черпали вдохновение на канале ExtremeCode. Для закрепления информации читайте краткое изложение трудов Дяди Боба и похожий материал о принципах чистого кода, где можно подглядеть ещё больше примеров.
Кстати, как вам материал? Если хотите больше таких – пишите в комментах, нам будет приятно 🙂
ссылка на оригинал статьи https://habr.com/ru/articles/807383/
Добавить комментарий