Как стать автором
Обновить

Комментарии 41

Все это так. Не бывает безупречного кода. Особенно, когда это код другого программиста.

Не надо код переписывать, пока он работает и удовлетворяет бизнес-задачам. Легаси код это типичный пример ошибки выжившего (каноничные дырки в самолете).

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

Другой пример, мы все смотрим Ютюбчик. Я уверен, что большинству пофигу как он написан, на каком языке, что у него под капотом, и какие умные люди его писали. Даже если бы это писали криворукие дебилы с соответствующим кодом. Потребителю на это наплевать, главное что работает.

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

Мне, как пользователю, очень не плевать на то, что он теряет очередь воспроизведения при перезагрузке. И от того на чём и как он написан напрямую зависит число таких вот "особенностей".

А вы не задумывались откуда взялись эти патеррны? Если копнуть глубже, то станет понятно почему они важны и как помогают бизнесу, пусть не всегда явно

Проблема плохого кода - сложность расширяемости. Если на решение простой фичи нужно не 15 минут, а два месяца, потому что код стоит на костылях и нужно всё переделывать чтобы внедрить нужный функционал, это начинает касаться и бизнеса и клиентов.

Если посрезать лирику, думаю что наша задача - делать достаточно хорошо. Задача лидеров - осознавать критерий разумной достаточности на их конкретном проекте, творческим образом организовать процесс, при котором "муравейник" будет эффективнее "муравья".

Баг мышления: "лучше идеальное, но никогда чем кое-как, но как можно скорей". И фу такими быть.

Идеального

Не бывает идеального.

А хороший бывает - просто потому, что бывает плохой и их можно сравнить.

Потому (например) и возникли концепции низкой связанности (coupling) и высокой внутренней (cohesion), чтобы контролировать говнишко на уровне модуля/пакета/сервиса

с который реально разобраться и удерживать в границах разумного

критерий "строка хорошо написано или нет" — так себе дял контроля сложности и проблем

Ревью

а вот то, что ревью не всегда следует цели — верная и даже может запнуть в паутину

написал статью на эту тему Ревью: защищайте свое решение!

Будешь защищать - тебя объявят конфликтным, бескомпромисным и тормозящим разработку. После чего отлучат от зарплаты.

Просто перефразируйте защиту кода на стремление к качеству и ваши оппоненты сами смогут отъехать. Программисты чёт редко заглядывают в раздел "ценности" организации, а там можно много интересного найти для создания перед кодом эшелонированной и аргументной обороны

У всех своё представление о "качестве кода". И на ревью ты людям мозги не переформатируешь. Особенно, своему лиду
.

Лиды не те люди, которые начинают втирать про токсичность, мой комментарий скорее про общение с менеджерьем

Лиды такие ж люди, как и любые другие.

Все же я привел ссылку в контексте обсуждаемой темы (что ревью может завести не туда)

:)

НЛО прилетело и опубликовало эту надпись здесь

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

надо иметь хороших лидов для каждой из таких команд

Ну да, на 3-6 разработчиков нужен лид. 20 разрабов в команде звучит оч трешово

Есть такая штука, как оптимальность по Парето. С точки зрения кода это обычно фиксированный кодстайл, фиксированный подход к проектированию, написанию и тестированию кода при котором никто из разрабов не остается довольным полностью. Главное чтобы работало и расширялось.


Как-то так

image

Главное чтобы работало и расширялось.

А еще чтобы эксплуатировалось. Потому что когда на 5 году к команде поддержке (оригинальные сеньеры-разработчики же уже все разбежались. Т.к. технология устаревшая, немодно и вообще уже не интересно, на претензии реальных пользователей продукта отвечать.) приходят с вопросом 'А почему это штука вот это делает, нам не нравится и кажется, что оно неправильно' — эта команда поддержки должна сказать что-то внятное за разумный промежуток времени и суметь починить, если действительно неправильно.


В общем, оптимальность надо бы считать с потенциально очень длинным хвостом эксплуатации.

Ну тоже не факт. Большинство бизнесов не проживают и одного года. Пять лет - уже дофига.

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

Ага. Теперь читаем новости и и историю про British Post Office. Люди в тюрьмы попадали потому что система проводки теряла. И вот готов поспорить, что исправить это все не сумели не только потому что не очень хотели, но и потому что никто особо не понимал, как это все работало.


Хотя казалось бы — денег для исправления должно было бы хватить.


И еще тонкость — "через 10 лет станет проблемой" — не у того, кто написал. Оно уже чем-то другим занимается. И иногда даже удивляется "а что, моя поделка используется еще что ли?" Т.к. предсказать, что вот это вот так долго проживет — нельзя.

Собственно, требование расширяемости как раз и предназначено для того чтобы иметь возможность как-то развивать систему. Где-то добавить, где-то отрезать, где-то починить устаревшее/поменявшееся. Просто способов как это сделать всегда найдется несколько и каждый со своим плюсом и минусом. И требования к системе почти всегда со временем изменяются, в том числе и противоположные или противоречивые текущей архитектуре. В том или ином виде некоторое дерьмо всплывёт и под звуки такой-то матери его будут чинить в той парадигме, в которой изначально писалась система. Если конечно цена переписывания будет заметно больше.

Фиг знает. Ковырял код nginx и наслаждался... Бывает, устану от своего рабочего кода и пойду в репу nginx, посмотреть, душу отвести.

Можно pet проектом завести какую-нить библиотеку и клепать там идеальный код чтоб душу, так сказать, отвести

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

А если PM скажет не «до завтра», а «через минуту», код будет просто вырви глаз? По какому закону изменяется качество?)

Твиттер, со своей невозможностью редактирования твитов из-за факапа архитектуры, заложенной при старте - отличнейший пример многолетней боли пользователей, по причине "пишем как можем, главное чтобы работало"

Так что "лучшие практики" нужно учить

Да ладно) неужели это так сложно реализовать? Есть ли пруфы этого заявления?

В нормальной команде на ревью скилл тех кто ниже уровнем быстро доходит до среднего по больнице. И как в анекдоте про обезьян и банан они сами начнут проверять наличие комментариев, сложность функций и покрытие тестами

Почему здесь необходим цикл?

Потому, что всё программирование состоит из циклов, даже если юзер высокоуровневой библиотеки этого не видит.

Можно ли будет развить твое решение без рефакторинга?

А зачем вам без рефакторинга? Или вы боитесь рефакторинга? Пробовали, не понравилось?

Да, рефакторинг, вероятно, не подходящее слово.
Я имел ввиду изменение архитектуры.

Стандартный принцип проектирования – код должен быть открыт к расширению, но закрыт к изменению. Если для расширения существующего кода требуется его изменить, значит есть вероятность, что решение спроектировано с ошибками.

код должен быть открыт к расширению, но закрыт к изменению

Я подозреваю, что open-closed principle родился в определённом контексте, а используют его почему-то также и вне этого контекста.

Контекст open-closed principle — это разработка библиотеки для третьих сторон. Третья сторона получает скомпилированный объектный файл (closed), поэтому не может вносить в него изменения и вынуждена пользоваться только тем интерфейсом, который вы (как его разработчик) задокументировали. Если вам для добавления функциональности к библиотеке нужно изменить её код, то вам надо перекомпилировать объектные файлы и доставить их пользователям вашей библиотеки. То есть изменение интерфейса ради новой функциональности создаёт организационную проблему. Именно на решение этой проблемы и направлен open-closed principle: мол, закладывай интерфейс такой, чтобы добавление новой функциональности (open) было возможно без изменения исходного кода.

Однако в статье вы говорите про корпоративную разработку. Да, всё зависит от объёма кодовой базы, от разделения ответственности между командами, от способа доставки кода, от необходимости поддерживать разные версии продукта, поэтому, безусловно, open-closed principle может иметь свой вес и во внутренней разработке.

Но я призываю вас не возводить его в абсолют, потому что каждый отдельно взятый контекст может и не подходить по условия применимости open-closed principle.

Могу привести в пример проект, в котором я работаю прямо сейчас. Его back-end содержит около 800 классов, распределённых по 70 библиотекам. И знаете что? Ни один класс не имеет стороннего (т.е. не управляемого компанией) клиента: весь front-end разрабатывается исключительно внутри компании, а единственный программный интерфейс для партнёров — это экспорт данных в CSV. И если мне нужно поменять интерфейс взаимодействия класса с его зависимыми классами или наследниками, мне ничто не мешает это сделать. Поднял версию библиотеки, поднял версию зависимости в зависимых библиотеках, раскатал код на сервера (язык интерпретируемый), готово. Зачем мне open-closed principle? Какую конкретно мою проблему он решает?

И мне честно было бы интересно узнать, какая часть программистов на хабре действительно разрабатывает библиотеки для сторонних клиентов. Или точнее, какая доля классов / модулей / библиотек, разрабатываемых в компаниях, где работают читатели хабра, предназначена для сторонних клиентов. Потому что ясно, что есть код для внешнего взаимодействия (собственно, интерфейс), а есть код для внутреннего использования (подробности реализации). И их соотношение может быть совсем не в пользу open-closed principle.

PS. А начать, наверное, надо было в того, что рефакторинг и изменения в интерфейсе — это две большие разницы.

В корпоративном приложении верная архитектура это когда можно быстро найти и изменить нужный код. А когда код пишут с расчётом на расширение плагинами или интерфейсами вот это как раз очень плохая архитектура.

Прагматичный подход к свое работе, дело похвальное. Продолжу задавать вопросы.
Какую конечную ценность имеет продуманная гипотетически хорошая архитектура, и какую ценность имеет рабочая плохая архитектура?
Сколько в рублях, у.е. принесёт один час потраченный на улучшение архитектуры?
Сколько часов будет сэкономлено на поддержке грязного кода, если его переписать, в расчете на один час на рефакторинга?
Сколько будет стоить рефакторинг цикла, и сколько будет сэкономлено на вычислениях в облаке после рефакторинга?

Жаль в голосовалке нет множественного выбора(

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

Как научить? – кодирование да, а вот архитектура, это опыт который годами вырабатывается

Даже если учить, кадры меняются, в лучшем случае раз в 2-4 года, и потом все вложенные усилия нужно вкладывать повторно, в новые кадры

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

Какой смысл, если можно просто сменить кадры?

Это как пытаться из ВАЗ сделать Subaru меняя детали со временем, когда можно просто купить Subaru и не тратить время

Я думаю что вы правы, но это работает, вероятно, не везде

Задача программиста не в написании кода, а в уменьшении сложности и связанности. Книгу пишет не машинистка.

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

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

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

Изменять и рефакторить код на продакшене уже нельзя, тем более легаси. И на этом этапе уже не будет выбора, а переписывать с 0 уже не разумно.

PS Нужно не забывать, что гит помнит наши имена и наши правки.

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

Это не так. Архитектура - это воля кибернетики.

Бизнес-логика дается сверху, и она всегда неполна и не рассматривает все состояния.

Если в коде два "if", то энтропия кода будет 4, т.е 4 возможных состояния.

Если в коде 8 if, то энтропия уже 256. В спагетти-коде энтропия больше чем гугол. Программист обязан все эти состояния проверить, причем если добавить условия проверки, то это только увеличит энтропию.

Это уже сложная система, в сложных системах всегда возникают непредсказуемые системные эффекты.

Цель разработки - в поиске полезных системных эффектов и чтобы система не погрязла в хаосе. Разработка итерационная.

SOLID - это типичное кибернетическое управление, причем единственное. Есть и некибернетические подходы.

От архитектуры зависит все. Зависит время жизни проекта, состав команды, время жизни компании, и сам проект и его фичи.

Скажите это Роберту Мартину J

Как вы посчитали 256?

Хорошо что автор думающий, все знает и понимает

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.