Pull to refresh

Comments 145

Если бы я мог нажать на кнопку, и моя работа переструктурировалась бы на хорошие
коммиты — я бы на неё нажал.

Так есть же вроде. Конечно не из разряда "сделай мне все хорошо", но довольно удобно. По крайней мере в том GUI для git который я использую. Пара нажатий и какие-то коммиты объедены и для них переписан комментарий, какие-то изменены местами и т.д. и т.п.

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

Так GUI для git все время показывает контекст, никуда ходить не надо.
Смотришь список коммитов для "interactive rebase", когда выбираешь что объединить, разъеденить и т.д. и т.п., нажимаешь Enter и видишь сбоку "diff". Переписываешь комментарий к коммиту, в правой половине экрана отображается "diff" и т.п.
Всегда доступен контекст, никуда ходить и смотреть код не надо.

А если у тебя 40 файлов изменено в каждом коммите?

А в чем сложность с 40 файлами?
Буфер/окно с "diff" конечно прокручивается.

Вникать надо. Для меня это напряжно. Понятно, что в итоге вникать всё равно придётся — но это когда пуллреквест будет готов, и никаких промежуточных решений там не осталось. А если сделал кусочек работы, сразу описал коммит — вникать не надо. Все в голове есть
Хотите метаться по кодовой базе и вносить измения случайным образом, не постаравшись сформулировать, чем же вы занимаетесь, пожалуйста. Это ваш выбор. Но вот писать статью о том, как вы спорили с лидером команды и доказывали, что так должны делать все, неприлично. Как и сам спор.

Вполне можно быть хорошо оплачиваемым специалистом на таком уровне. И даже уважаемым, если вы в конечном итоге решаете поставленные задачи и ваш код не создает проблем остальным. Но не самым лучшим, никакими аргументами вы этот разрыв не компенсируете.
А самый лучший программист это кто?
Торвальдс что-ли систематично работал с четко очерченными и детально описанными коммитами?

У этого "надо вникать" есть польза: смотришь на собственный код свежим взглядом, и получается self code review.


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

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

К чему они? Если не отвлекаться на другую ветку, что бывает очень редко, то один талон — один коммит. И девлид не придерется(=
эмм, зачем? --amend не? ноут?

А зачем тратить силы ревьюера на понимание ваших промежуточных шагов?


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


А большую фичеветку без атомарных коммитов ревьюить довольно адово.

Большую ветку проще ревьювить, не видя промежуточных шагов, если эти шаги были в итоге отменены. Если бьешь свою работу на логичные шаги — тогда да, ревьювить по комитам проще. Но я свою не бью.

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


Interactive rebase позволяет разбить на логичные шаги постфактум — так, чтобы ревьюер видел PR в таком состоянии, как будто я изначально идеально все спланировал, и мог последовательно идти по коммитам.


Я это делаю прежде всего из уважения ко времени коллег, которые точно не порадуются необходимости ревьюить PR на несколько тысяч строк за один заход. История коммитов для будущих git blame — тоже хорошо, но вторично, скорее полезный побочный эффект.

Ну звучит кстати довольно разумно, попробую

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

Я обычно делаю amend до тех пор пока не получу работабщий кусок кода, и именно то что заработало/изменилось я и пишу в загаловке.
У меня получается коммит атомарный, и главное — всегда работающий состояние, если у меня что-то пошло не так я к нему могу откатиться. Если что-то по итогу изменено что никак не касается этого коммита то эту часть я не включу/выкину из него.

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

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

Да подзадачи чделать не проблема, проблема разделить эту работу с кодом, чтобы сделать отдельный коммит для этого "рефакторинга"

так в чём проблема то? =) проделал работу — закоммить и опиши что сделал, так и история блужданий сохранится и лиду будет понятно что тебе пришлось перерыть и что затронуть ради выполнения таски

Я про ситуации типа:


  1. начал делать фичу, изменил кучу файлов в рамках фичи
  2. понял, что лучше изменить сигнатуру и тело какого-то метода изменения которого в рамках фичи не предполагалось
  3. сделал изменения, в том числе изменил все места использования
  4. доделал фичу и убедился что всё работает

Если коммитить всё сразу, то изменений из п.3, неотносящихся к фиче может быть очень много. А цельная рабочая систем атолько после шага 3, на шаге 1 она разломана

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


Ага, тебя забыл спросить
улучшить какой-то модуль, часто с изменением сигнатур/контрактов

Это уже очень серьезный звоночек, но если так надо, то вот рецепт:


  • ветка 1: изменения, добавляющие недостающие сигнатуры
  • ветка 2, основанная на 1: ваша имплементация новой фичи
  • ветка 3 (я считаю, что это прямой путь в ад, но вам виднее), основанная на 2: удаление легаси

Все можно туда-сюда раскатывать, ветка на подзадачу, история коммитов нахрен не нужна.

Ну как-то так да приходится делать, если требуют такой атомарности

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

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

Очень круто. Прям как хороший фильм который не даёт ответов, а только появляется больше вопросов.

Если бы у меня были ответы, я бы тут не сидел)
Думаю вы увидите достаточно ответов, только они будут с обеих сторон… :)
О комментариях в моей теме пишу:
мой стиль c# cs & qbasic bas & c# cs:

комментарии смещены вправо относительно строк ниже
повторяю:
комментарии смещены вправо относительно строк ниже

1-я строка имя файла
комментарии смещены вправо отдельно от строк ниже
фигурная скобка открывающаяся: в начале строки
фигурная скобка закрывающиеся: подряд несколько
однотипные команды: несколько в 1-й строке как qbasic и др…

мой стиль удобнее:
	// daprimer.cs
	if (lessThan100) 
		// данный код работает
		// код работает данный 
		// работает данный код 
	{ consumeNumberLessThan100(lessThan100); 
		// ошибка компиляции: функция ждёт число > 100.
	consumeNumberMoreThan100(lessThan100); // в конце коммент нормально 
	}
действительно удобнее

даже без форматирования цветом:
	// daprimer.cs
	if (lessThan100) 
		// данный код работает
		// код работает данный 
		// работает данный код 
	{ consumeNumberLessThan100(lessThan100); 
		// ошибка компиляции: функция ждёт число > 100
	consumeNumberMoreThan100(lessThan100); // в конце коммент нормально 
	}

обычный ваш стиль НЕудобный:
    if (lessThan100) { // неужели место скобки здесь?
        // вот этот код работает
        // но где же сам код?
        // почему код потерялся в комментариях?
        consumeNumberLessThan100(lessThan100); 

        // а здесь - ошибка компиляции, функция ждёт число
        //для которого доказано, что оно ("оно"?)> 100 
        consumeNumberMoreThan100(lessThan100);
    }

НЕудобный стиль ваш без цвета:
    if (lessThan100) { // неужели место скобки здесь?
        // вот этот код работает
        // но где же сам код?
        // почему код потерялся в комментариях?
        consumeNumberLessThan100(lessThan100); 

        // а здесь - ошибка компиляции, функция ждёт число
        //для которого доказано, что оно ("оно"?)> 100 
        consumeNumberMoreThan100(lessThan100);
    }
Неудобно особенно в книгах без цвета. Жуть?

Однако никому ничего никогда НЕ рекомендую

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

блин я почитал. У меня теперь мозг болит
ps: никого не хочу обидеть. Я не знаю в чём причина столь витееватого стиля изложения мыслей.
Из-за вас с Ritan я тоже почитал. Спасибо вам, у меня теперь глаз дергается

жеееесть, мне видосы доставляют и комменты в стихотворном виде. Интересно, может это такая умелая симуляция поехавшего (помню тут была статья про одного типа, что Божественную ОС делал), вот и пытается человек импортозамещение обеспечить. Ну либо пожелаем ему поскорее добраться до врача…
, и стал писать сверхдетальные коммиты. Мой девлид — настоящий вампир. Он требует не просто описание
Пример приведите, а то не очень понятно как оно выглядит.

Основная проблема это не включать капитана очевидность (также как и в комментариях), это отдельный навык и для некоторых более сложный чем писать код.

У нас есть тикет, добавляем его номер и заголовок, этого достаточно. По изменениям видно что делается и зачем. Надо детали, сходи в тикет и посмотри.
Ну, с проекта пример нельзя по идее, а выглядит примерно так

#TicketNumber
implemented X request memorisation
reworked Y

Some.cs: added internal validation methods
SomeTest.cs: covered Some validation with tests

коммиты у меня большие, и файлов там под 50 может быть
Мне тут сложно хороший пример выдумать, и получается это у меня не очень-то хорошо, но гайд примерно такой: объяснять, зачем нужны изменения, а не что они делают
В каком нибудь хорошем опен-соурс проекте вы видели подобный стиль? Если да — дайте ссылку, если нет — то это звоночек, что может быть не всё так радужно.

Проблема с подобным подходом, это ассиметричность усилий. Т.е. тебе надо потратить много усилий на создание комментарий, а поиспользуют их исчезающе мало. И альтернативные способы, которые обходятся фактически без усилий и они «good-enough».

Если есть code review то описание зачем сделано то-то и то-то резко облегчает ревью. Также написание таких комментариев тренирует мозги, бывает пока опишешь зачем ты все это делал именно так, поймёшь, что все можно сделать проще.


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


Когда работа закончена этот «пост» идёт в документацию, а в PR идут ссылки на него и дополнительные описания граблей, по которым я ходил и как они влияют на результат.


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

Я вместо таких больших description-ов к commit-ам просто открываю новосозданный merge-request, и пишу уже по месту. Обычно ничего нигде писать не приходится, ибо стараюсь делать всё просто. Но сами понимаете, удаётся не всегда. В таких случаях просто в webUI merge-request-а gitlab-а точечно (применимо в конкретным строкам и diff-ам) задаю свои комментарии уже не стесняясь в размере комментариев, и используя markdown разметку. Мне кажется это гораздо удобнее, чем что-то большое оторванное от контекста писать в самом коммите.


Из недостатков (или наоборот преимуществ) вся эта писанина уходит в никуда после совершения merge-request-а. Как и сами коммиты (ибо да будет squash). Я трактую этот как преимущество, хотя понимаю, что тут может быть много мнений.

Хах, хорошие коммиты кучу раз меня спасали. Любой код когда-нибудь может стать legacy-кодом (достаточно не трогать его около двух лет). И тогда только git blame сможет объяснить что имел ввиду разработчик.

я бы после недели такой дичи пошел бы работу менять)
Когда мне ярые сторонники атомарнейших коммитов с подробнейшими commit message предлагают делать так, я в ответ обычно предлагаю поднять историю откатов коммитов (потому что это главный кейс экономии времени с атомарными коммитами). Если выясняется, что откатов исчезающе мало (а в энтерпрайзе обычно именно так и оказывается) — самое время подумать про потери времени на описание коммитов и перестройку работы на атомарные задачи.

Работает оно как угодно, но про это Фил уже написал. И так работает, и с PR работает, и даже работает, когда все тупо фигачат в мастер без ревью. Вопрос исключительно в том, насколько плохо может быть поставлен процесс разработки, чтоб при этом всё не развалилось и не поимело проблем. Про границы применимости тех или иных best practices обычно мало кто думает (впрочем, я про это даже статейку тиснул): небольшой продукт, разрабатываемый небольшой командой — легко может быть свалкой коммитов без каких-либо проблем для себя, а если там еще и тестами всё хорошо покрыто — то и не небольшой. Что-то большое и/или сложное, да еще и если от этого требуется повышенное качество и хороший bus factor — … тоже может, но уже может и поиметь крупные проблемы из-за неорганизованного принятия кода.

А вот у опенсорса совсем другие реалии, например, и там я бы хорошие атомарные коммиты ценил гораздо выше.
Я согласен. Но вообще, есть и такой поинт: если тебе не дорого обходится увеличить количество документации, и не гадить при этом в сорцы — почему бы и нет. Конфлюенс, комиты, пуллреквесты, ридми файлики в решении — писать текст то не долго, а помочь может. Именно с комитами проблема есть у меня — меняет структуру работы, и мне от этого очень некомфортно. Кстати с докой в коде тоже есть проблемы — по моему, хороший код на статически типизированном ЯПе читабельней, когда не обернут в тонну текста
историю откатов коммитов (потому что это главный кейс экономии времени с атомарными коммитами)

Ну вообще-то главный кейс это анализ истории — когда и по какой задаче это было сделано и что еще поменялось вместе с ним.

Анализ истории нужен не «просто так», а ради решения проблем.

Да, но в большинстве случаев это не откаты коммитов.

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

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

Да. И это не гарантия отсутствия багов. И тем более не гарантия отсутствия изменений требований.
А еще можно делать и то и другое, а не заменять одно другим.


вы боретесь со следствиями, а не с причинами

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


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

Если вам не нужно анализировать историю, то вам и система контроля версий не нужна.

Конечно. И идеал — именно такой, а стремление к идеалу — минимизация количества причин, по которым нужно анализировать историю.

Причина анализа истории это предыдущие изменения в коде. Причина внесения изменений в код это рабочие задачи.

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

И да, одно из мнений — это то, что вести архив подобных вещей как раз и нужно именно в истории коммитов, а не где-то еще. Но это не «единственное правильное» решение, а всего лишь компромисс — ведение хорошей истории коммитов постоянно жрет человеко-часы, рытьё в коммитах (если мы не ведем хорошей истории) — аналогично, только не постоянно, а в момент возникновения проблем. В разных ситуациях выгодность первого и второго пути будут сильно различаться.

А зачем вообще рыться в коммитах? Почему нельзя сразу пойти рыться в коде? Как надо сейчас — мы знаем, в чем проблема?


Вместо того, чтобы искать кто виноват — у нас уже есть четкое что делать.

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

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

Знакомо.


Быть задокументировано — должно́, угу. Но почему-то примерно никогда и нигде оно — нет :)


Я не пускаю в транк ничего, что ломает обратную совместимость. Но и вокруг меня мир не идеален (ненавижу это его свойство!) — поэтому если вдруг ломает — вот тут я потребую прямо эпос написать, размером с «Войну и Мир», и положить его внезапно не в коммит, а в README в соответствующую папку. С легко нагреппываемыми ключевыми словами и номерами задач в жире, или где там нынче модно задачами управлять.

Вместо того, чтобы искать кто виноват

Никто не ищет, кто виноват.


у нас уже есть четкое что делать

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

То есть, условно говоря, когда ничего не задокументировано

История изменений это и есть часть документации. В частности, там номера задач в коммитах написаны.


нет ТЗ, и вообще не очень понятно, что мы тут все делаем

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


ведение хорошей истории коммитов постоянно жрет человеко-часы

Если у вас на это уходит много времени, значит вы делаете что-то не так.

Если у вас на это уходит много времени, значит вы делаете что-то не так.

На это уходит значительно больше времени, чем на подробное документирование целых PR, а не отдельных коммитов.
Понятно, что не дни. Но по часу-другому в неделю на разработчика вполне себе может набраться. У вас 10 разработчиков? Ну вот — оп, и 10-20 часов в неделю уходит на причёсывание коммитов.
Ну вот — оп, и 10-20 часов в неделю уходит на причёсывание коммитов.

Так можно тогда вообще коммиты не делать, еще больше времени можно сэкономить. Только почему-то в конечном счете оказывается, что это время не экономит, а совсем наоборот. А если делать, то на фоне этого 10 минут в день не так уж много. Если у вас разработчики настолько заняты, что надо экономить 10 минут, то проблема не в истории коммитов.


На это уходит значительно больше времени, чем на подробное документирование целых PR, а не отдельных коммитов.

Если есть отдельные коммиты, PR можно документировать менее подробно.


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

Только почему-то в конечном счете оказывается, что это время не экономит, а совсем наоборот.

Или не оказывается. У вас есть какие-то конкретные случаи, или это всё умозрительно?

К примеру

Примеры у вас, конечно же, все тривиальные. Про более сложные случаи в таких обсуждениях вспоминать почему-то не любят — скажем, как выделять в коммитах изменение внешних API каких-то модулей вследствие их внутренних изменений.
У вас есть какие-то конкретные случаи, или это всё умозрительно?

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


скажем, как выделять в коммитах изменение внешних API каких-то модулей вследствие их внутренних изменений.

Если изменение API связано с внутренними изменениями, они должны быть в одном коммите. Зачем их разделять?

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

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

Если изменение API связано с внутренними изменениями, они должны быть в одном коммите. Зачем их разделять?

Затем, что такие правки с легкостью порождают огромные (по объему) коммиты, в которых потом будет долго разбираться при анализе истории.
Я так до сих пор не понял, почему вы обсуждаете дихотомию

Я говорил про способ экономии времени путем отсутствия коммитов. Вы попросили пример, я его привел. Отсутствие коммитов на первый взгляд экономит время, но в результате времени уходит больше из-за следствий этого отстутствия. С экономией времени на нормальной истории то же самое, просто в меньшем масштабе.


Затем, что такие правки с легкостью порождают огромные коммиты

Я не очень понимаю, что вы имеете в виду, ну да ладно.

они должны быть в одном коммите

APIv1APIv2.
Files changed: 42


Ну да, ну да. С таким подходом могут потребоваться и комментарии к комментариям коммитов.

они должны быть в одном коммите
APIv1 → APIv2
Ну да, ну да.

Да. В данном случае это будет мерж-коммит одной ветки в другую. А внутри ветки с новым API коммиты разделены по модулям или фичам или еще по какому-то признаку. Изменение сигнатуры одного конкретного эндпойта находится в одном коммите с его внутренними изменениями. Удалили параметр из сигнатуры — удалили и его обработку в коде. Или вы хотите это отдельными коммитами делать? Ну дело ваше, просто зачем.

Человека, который может выкатить для CR ветку, в которой изменены 42 файла — надо не просто увольнять, надо на столбе в назидание прохожим вешать.

Человека, который может выкатить для CR ветку, в которой изменены 42 файла

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

Это чтобы пока самый распоследний эндпоинт не вмерджится, вся команда считала ворон и гадала, когда же оно попадет в транк? Не, спасибо.


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

Это чтобы пока самый распоследний эндпоинт не вмерджится

А вы хотите, чтобы у вас в продакшене половина APIv2 работала, а половина нет? Ну дело ваше, обычно так не делают.

обычно так не делают

Обожаю экспертные мнения от ноунеймов.

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

обычно так не делают

Я предполагал, что у нас аргументированное обсуждение

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


Иначе очень велик риск получить в ответ то, что вы получили. Тут интернет, знаете ли.

Когда в публичных местах люди, полагающие, что тут «аргументированное обсуждение», пишут что-то наподобие «обычно так не делают»

У нас было обсуждение организации коммитов, а не подходов к разработке новой версии API. Фраза "Обычно так не делают" сама является аргументом в этом обсуждении, пояснением почему я не рассматриваю такой вариант. Если вам были интересны подробности касательно конкретно этого аргумента, вы могли про них спросить. Если не интересны, то не спрашивать. Вместо это вы предпочли оскорбить собеседника, хотя он вас не оскорблял, тем самым понизив уровень дискуссии до уровня базарных бабок. Или обезьян, которые кидаются известно чем.


либо используют обороты «я обычно так не делаю»

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


Тут интернет, знаете ли.

Мне без разницы, интернет тут или нет. Оскорбление мне написал не интернет, а лично вы.

У нас было обсуждение организации коммитов [...]

С тех пор, как я ответил на вопрос «зачем их разделять», мы обсуждаем именно что подходы к разработке новой версии API.


Если не интересны, то не спрашивать.

Не интересны, не спрашивал. Просто указал на то, что вы несете ерунду — вдруг дети зайдет почитать, и ненароком подумают, что вас имеет смысл слушать?


Вы сами додумали и сами обиделись.

Я? Обиделся? На очередную глупость на хабре? Ну у вас и фантазии!


Мне без разницы, интернет тут или нет. Оскорбление мне написал не интернет, а лично вы.

Во-первых, я уже объяснил, что кисо зря принимает прямоту за оскорбления. А во-вторых — и чё?

С тех пор, как я ответил на вопрос «зачем их разделять», мы обсуждаем именно что подходы к разработке новой версии API.

Вы возможно. А я говорил про коммиты. Можете нажать Ctrl+F и поискать.


Просто указал на то, что вы несете ерунду

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


Я? Обиделся?

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


Во-первых, я уже объяснил, что кисо зря принимает прямоту за оскорбления.

Прямота в данном случае это нейтральная фраза "Я не согласен, что так обычно делают".


А во-вторых — и чё?

Ничё. Вы мне привели аргумент "Тут интернет, знаете ли", я выразил свое отношение к нему.

Человека, который может выкатить для CR ветку, в которой изменены 42 файла

Так это не от программиста зависит. Если поставлена задача, для которой надо поменять 42 файла — значит, будет в пр ветка, в которой поменялись 42 файла.

Отнюдь. Программист — не бессловесная березовая чурка. Увидев и проанализировав такую задачу, он обязан дать в морду указать тому, кто поставил такую задачу, что ее необходимо разбить на подзадачи.


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

В команде/компании может быть правило, что перед выкаткой всё должно быть протестировано QA. А протестирована может быть только законченная фича — или выкатывается целиком, или не выкатывается вовсе — непротестированный код не должен выкатываться

перед выкаткой всё должно быть протестировано QA

Разумеется.


протестирована может быть только законченная фича

С чего это? Протестировано может быть все, что угодно. Если надо называть это «фича» — разбейте оригинальную «мегафичу» на «фичу» — и обтестируйтесь. Я об этом ровно и говорю.

QA не могут протестировать фичу, у которой нет UI или хотя бы public API. Я могу тесты написать, но это не будут end-to-end тесты, максимум какие-то интеграционные.

фичу, у которой нет UI или хотя бы public API

Если у кода нет взаимодействия с внешним миром, которое может протестировать QA — этот код можно совершенно невозбранно полностью выбросить. Это настолько очевидно, что (если вы не Иммануил Кант, конечно) тут и обсуждать нечего.

Или этот код (для простоты в 1 файле) ещё не готов к выкатке и надо внести изменения в ещё 41 файл, чтобы получить атомарную фичу, по которой QA могут однозначно сказать сделана фича или нет. А пока изменения лишь в 41-м файле, а не в 42, они вынесут вердикт "не готова".

Это вы предлагаете всякие сервисно-системные штуки выкинуть? Как QA будет тестировать сборщик мусора например или реализацию некоего контейнера и т.п.?
Если я правильно понял мысль VolCh, то вот пример:
Делаем фичу автодополнения в некотором поле формы ввода(UI). Для реализации, нужно поменять контракт и реализацию некоторой коллекции(скажем учитывать расстояние Левенштейна при поиске вместо обычного сравнения). По идее можно было разбить это на два PR — первый с изменением коллекции, а второй с самой фичей. Но QA не может протестировать первый PR без второго, поэтому согласно политики компании, это должен быть один PR.
Подозреваю, что ответ будет — меняйте процессы/не работайте в такой компании, но в реальном мире все несколько сложнее.

Да, хороший пример.

Сложный целебный рефакторинг может и 300 файлов зацепить. И далеко не всегда дробить такое на разные merge-request-ы — разумное дело, ибо промежуточных рабочих состояний просто нет. Да это больно ревьювить, но что ж поделать, ведь "жизнь это боль". Бывает и такое нужно. Плохо если такое норма.


В таких случаях надо помочь коллегам с ревью… Но как не крути, но 300 файлов останутся 300 файлов.


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


Как это правильно организовывать? Как это ревьювить? Да кто ж его знает...

Сложный целебный рефакторинг может и 300 файлов зацепить.

Позовите разработчика с головой и хоть каким-то опытом, и он вам расскажет, как такой рефакторинг разделить на 30. Это заодно в качестве бонуса снимет проблему «надобно теперь пойти третьим путём».


Я победил не в одном десятке споров про то, что «вот это дальше на кусочки не порезать», поэтому знаю, о чем говорю.

Порезать то всегда можно, вопрос, насколько это целесообразно. Если мы например изменили кодстайл, и теперь во всех файлах надо заменить _field на field — я бы это на кусочки дробить не стал. Резать надо не количеством файлов, и даже не количеством работы — а контекстом задачи. У меня есть убежденность, что любой пулл реквест должен отдавать рабочее, и в каком то смысле законченное решение.

Синтетическими примерами я тоже сыпать умею.


в каком то смысле законченное решение

Несомненно, и тут никаких разногласий нет. Но. Во-первых, даже ваш синтетический пример можно сформулировать более корректно отображающим реальный мир: не field на _field, а field на _field, shield на _shield, ......, и yield на _yield, — вот и нарисовались три подзадачи в одном эпике.


Заметьте, что для CR сложность понизилась не втрое, а в миллиард раз — отследить замену одного терма гораздо проще, чем трех (а девять — не смог бы и гений, если верить Эйнштейну).


Бонус трек: так как первые вмерджены по ходу пьесы, когда ревьюрер завернет последний (yield — это ключевое слово, его не нужно менять на _yield) — нужно будет просто закрыть PR, а не возиться с ребейзингом, правкой коммитов, правкой мессаджей, и т. п.

Не встречал таких людей в живую, к сожалению. Кажется они записаны в красную книгу. Полагаю, единственно правильным решением для нас будет, похитить вас из Испании, привезти в Мюнхен, и посадить на цепь. Иначе так и будем, "безопытные", мучаться. Вам самому не смешно? :)


А в Барселоне такой уровень токсичности это норма? ;)

Я в Мюнхен не поеду за в десять раз бо́льшую зарплату, так что не вариант.


Ну а если серьезно, то «я не встречал» — так себе аргумент. Я встречал, и довольно часто. Не нужно думать, что если кто-то никогда не видел дрель, и сверлит дырки пальцем — это нормально.

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


не field на _field, а field на _field, shield на _shield, ......, и yield на _yield, — вот и нарисовались три подзадачи в одном эпике.

И теперь вместо одного диффа на файл у вас по три. Какой в этом смысл? Это же только делает все хуже. Делить задачу на подзадачи — это не самоцель, это инструмент. Само по себе такое деление не нужно — более того, оно вредно.

Боюсь показаться токсичным, но хотел бы показать, как бы на Ваш спор про random(0, 1000) посмотрел бы отдел обеспечения качества:


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

Насколько я понял из статьи, команда понимала плюсы рандомизации, но не могла её принять из-за "объективной реальности", обусловленной проблемами из п. 3. Лично для меня это выглядит достаточно странным, потому что обычно, когда кто-то говорит об улучшении процесса, обязательно вспоминают словосочетания типа "шаг за шагом", "baby steps" и "итеративно". И в данной ситуации рандомизация — это такой же "baby step", который не ухудшает ситуацию сейчас и улучшит процесс, когда билды будут быстрее и надёжнее, но команда не готова его принять. Я понимаю, это связано ещё и с


Ты должен сесть, и посчитать, как долго просуществует проект, в какую сторону он пойдёт ...

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


К сожалению, часто вижу подобную ситуацию. Иногда мне кажется, что разработчики считают себя достаточно компетентными в (авто)тестировании только потому, что они пишут юнит-тесты. Зачастую оказывается, что это даже не тесты, а код, который просто вызывает функции, модули и компоненты для обеспечения 80% покрытия продуктового кода. На моей практике был случай, когда разработчики увлеклись mock'ами настолько, что в юнит-тестах одни mock'и тестировали другие. Естественно, пользы от такого "тестирования" очень мало.


Прошу прощения, если задел кого-нибудь подобным комментарием. Посыл не в том, чтобы сказать: "команда автора — сплошь джуны и не умеют работать", а в том, что в разных областях есть специалисты и эксперты, и важно понять, когда нужно делегировать принятие решения им. И к сожалению, зачастую отделы разработки и управления не понимают, что тестировщики и отдел качества — это не просто люди для нахождения багов и приёмочного тестирования по stories в Jira.

У каждого из нас есть своя философия — она не описывается одним словом, это сложный набор паттернов для принятия решений

Ну, да, у каждого языка программирования есть своя «философия», иначе их не было бы так много. Но «философия» звучит слишком размыто, можно сказать что есть наиболее присущий языку, идиоматичный способ написания кода на нем, и есть все остальные, «неправильные», «чуждые». Если я на Java буду писать библиотеки с public static методами, а потом комбинировать их вызовы процедурно, то мне резонно скажут «ты на Java пишешь как на Паскале, а это неидиоматично для Java. Пиши, моделируя каждую сущность как объект, и используй полиморфизм». А если я стану возражать «да зачем же мне городить тут целый класс, когда у меня тут массив из трех int и рядом строка», то мне скажут «ну тогда пиши на C вообще».

все будут глушить твой гард с помощью каста к эни

Ну, за всех не скажу, но я бы именно так и делал )
Ну, за всех не скажу, но я бы именно так и делал )
Против такого можно custom code analysis применять. Можно конечно обойти, если хитро извернуться, но когда затраты на реализацию выверта будут больше затрат на следованию внутреннему стандарту, то должно быть вполне приемлемо.

На самом деле для языков типа c#, где с приходом roslyn-a custom code analysis делать достаточно просто, можно в какой-то мере его считать динамическим расширением системы типов, в некоторых случаев даже более мощным и очень хорошо интегрированным в IDE. И точно также упадёт на этапе компиляции.
Ну, за всех не скажу, но я бы именно так и делал )

Можете как развернуто ответить — а почему?
Ответы «потому что и без этого работает» я слышал часто, а какие-то аргументы — нет. Ведь чем больше проект, тем лучше такие вот проверки времени компиляции окупаются в плане трудозатрат. Сам TypeScript не на пустом месте появился и стал востребован, а исходя из того что на чистом JS писать большое сложно.

P.S. Зачем делать конкретное ограничение <100 мне сложно придумать, но точно помню, что какие-то подобные if'ы писал…
Ну… мы упремся в диалектику. С одной стороны статическая типизация улучшает читаемость кода и спасает проект от скатывания в нечитаемое черт-те что. С другой стороны, чем больше статической типизации, тем больше там все «прибито гвоздями» и вот уже ты обнаруживаешь, что для того, чтобы поменять сигнатуру метода, надо влезть в 6 интерфейсов и 12 классов, которые их реализуют. А при этом по опыту уже известно, что это изменение кода локальное, оно нигде больше, кроме вот этого конкретного места не пригодится, и генерализовать его вверх по всей архитектуре никакого практического смысла нет. И проще добавить еще одно значение в Map-аргумент функции, чем лезть в проект и менять там все интерфейсы.

Хотя, конечно, с точки зрения «архитектурной строгости» и «красоты» надо было бы все интерфейсы… как это сказать… переспецифицировать.
что для того, чтобы поменять сигнатуру метода, надо влезть в 6 интерфейсов и 12 классов, которые их реализуют


Да, при динамической тоже надо, но ты об этом узнаёшь только в багтрекере
Так и получается спор остроконечников с тупоконечниками. Статическая типизация лучше, потому что серверный бэкэнд и все, связанное с транзакциями, пишут на строго типизированных языках, в основном. Нет, динамическая типизация лучше, потому что почти весь клиентский UI сейчас пишут под браузеры, в котором JS. Может, обе лучше, каждая под свой спектр задач?..
Мой вопрос был не про статическую типизацию против динамической. Раз мы выбрали TypeScript, а не vanilla JavaScript, значит на данном проекте посчитали, что статическая нам подходит больше. И тут fillpackart предлагает эту самую типизацию усилить, а вы предлагаете это усиление игнорировать с помощью средств языка доставшихся в наследство, хотя на мой взгляд оно может быть очень полезно, например есть функция:
function foo( input:number ) {
    if (input >= 100) {
        throw new Error();
    }
    //some valuable code...
}

function foo2( input:lessThan<100>) {
    //some valuable code...
}


ИМХО, вторая функция и выглядит лучше, потому что по сигнатуре сразу понятно, что ей надо передавать и самое главное — будет ошибка компиляции, а не в упавшем тесте или вообще в боевом режиме.
Повторюсь, в голову нормальный пример когда это нужно не приходит, но люди на подобных вещах доказательства корректности делают(см. Idris, лет через 5 я до него доберусь).

P.S. Наверное я могу предположить почему команда fillpackart так реагирует, они писали на JS и тут с неба свалился TS, потому что модно и молодежно, но не все понимают зачем, тогда они и проверки самого TS будут глушить с помощью any в любой непонятной ситуации.
Формально мне возразить вам на это нечего. Мне даже кажется, что вы меня переубедили :) И конечно же, вторая приведенная вами функция выглядит лучше первой, вряд ли кто будет с этим спорить. Но, как сказано в статье, и с чем я полностью согласен,
Получается дилемма — удобство разработки, или надёжность. Вот тут мы попадаем в ловушку, мы начинаем думать, что надо посчитать, что там за удобство и что там за надёжность. Но удобство и надёжность в разработке, очень, очень сложные вещи. Они состоят из тысяч параметров.

В данном случае мне (чисто субъективно) показалось, что увеличение надежности не стоит уменьшения удобства разработки, поэтому я и сказал про any. Но если бы в реальности я попал на проект, где приняты подобные ограничения, и вся команда их соблюдает, то я бы тоже соблюдал, никуда бы не делся.
Тут вот какой поинт — кастить к эни можно, только если точно знаешь, что значение валидное. Потому что если ты не знаешь — а функция защищена типом — внутри неё скорее всего не будет рантайм проверок, и скормив ей эни ты создашь баг.
По приведенной цитате, я с ней не до конца согласен, буду совсем согласен, если будет противопоставлять не удобство и надёжность, а скорость и надёжность.
Т.е. можно мой пример дополнить третьей функцией:
function foo3( input:number ) {
   //some valuable code...
   // crashes if input>=100
}

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

Вот это новость.

говнокодеры, которые пишут голанг


Разработка Go началась в сентябре 2007 года, его непосредственным
проектированием занимались Роберт Гризмер, Роб Пайк и Кен Томпсон[5]


Ну извинииите )

Да, чуваки, прославившиеся системой, снискавшей поистине мировую славу — Plan9. Вот что нам услужливо подсовывает википедия:


[t]he foundations of the system are built on two ideas: a per-process name space and a simple message-oriented file system protocol. — Rob Pike et al.

Алан Кей родил эту идую в середине 60-х. В 1992 виртуальная машина эрланга, которой до операционной системы — в принципе, рукой подать., вовсю обслуживала миллионы станций. И тут —  опа! — Plan9.




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

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

Джон Хьюз и Коэн Клэссен в 1999 году придумали Property Based Testing. random(0, 100) — это жалкое его подобие, с неконтролируемым количеством проходов, без шринка, и, разумеется, неповторяемое. Лучше, чем ничего, конечно, в той же степени, в какой лапти в пургу лучше, чем босиком.


Что касается подробных коммитов — они нужны только эффективным менеджерам, как и количество строк кода, в качестве KPI. Если что-то не работает, я не пойду читать коммиты. Я пойду читать код. И любой адекватный человек сделает так же. Потому что сообщения в коммитах могут соответствовать коду, а могут и не очень (ну, пока мы не научили AI генерировать машинный код напрямую из сообщений в коммитах). Код читать проще, быстрее, и эффективнее.


Поэтому я лично стою на трех китах при работе с системами котроля версий:


  • маленькие бранчи
  • squash-merge
  • все время, которое я мог бы потратить на бессмысленное описание своей работы где-то в недрах посторонней системы, я трачу на написание и поддержку документации в коде, по которой потом генерируется HTML.

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

Если зафиксировать seed — то random станет повторяемым. Разумеется, чтобы до этого додуматься — нужно поставить целью решение проблемы, а не участие в споре.

Нет, нельзя. Смысл в том, что спустя сто тестов мы покроем примерно 66% диапазона. Я выше давал ссылку на property-based testing, сходите, почитайте для общего развития.

мой ответ был на замечание, что можно было в примере сделать повторяемый рандом, а не "настоящий". Тогда в рандоме как таковом и смысла нет, и можно было бы подставить N раз разные числа, записанные в атрибуте [InlineData(1)]. Это пример из xUnit для .NET

Либо вы не поняли смысл замечания, на которое отвечали, либо я подумал о его авторе слишком хорошо.


Смысл seed в том, что он дает возможность повторить тот pseudo-random ввод, на котором тест повалился. Зная сид, можно сгенерировать тот же случайный набор. Но пока все зелененькое, каждый раз будет новый сид и новый рандом.

Да, если число одно — так будет проще. Но обычно всё-таки случайных чисел требуется больше.

Ну, например с того, что чтобы знать про seed — надо это знание где-то (а главное — зачем-то) благоприобрести. И в процессе обогащения этим знанием — нужно особо социально изолироваться, чтобы не наткнуться на проперти тестинг.


А уж если человек на него наткнулся, и на следующий день не заставил всю команду на него перейти в таких случаях — такого человека, наверное, лучше уволить вчера.

Э-э-э, а в документации к стандартной библиотеке про seed вычитать совсем нереально?

К стандартной библиотеке чего? Ну не знаю, может и реально; я не думал, что кто-то читает документацию к стандартным библиотекам.

Если работаешь в команде — работаешь над общим делом. Некоторые считают, что конкуренция — дело хорошее, но на практике выливается в работу «лебедь, щука и рак». Если человек принципиально делает все как ему нравится и пропихивает свои идеи наперекор команде — от такого токсичного элемента нужно избавляться

Или команду, которая жалуется на «токсичность» — разогнать к херам. Не всегда ясно, какой вариант разумнее, проще и дешевле.

Можно предложить решение, из-за которого разработчики не будут спорить, что оно говно))
Но если не будет философии, а только чистая объективная логика, то любой спор сведется к проблеме всемогущего творца и неподнимаемого камня.


Всё верно. Для этого и существуют лиды — вовремя сказать «всем спасибо за высказанные мнения, а теперь мы будем делать вот так». И вобщем-то абсолютно всё-равно какое «вот так» будет выбрано, главное чтобы процесс высказывания мнений прекратился и перешел в работу.
Вот только частенько лиды — самые лютые холиварщики
примеры решений — docker, k8s, MQ — давай пиво или спорь (P.S. заголовок кликбейтный и тема спора сформулирована размыто, поэтому так) но только аргументирванно, а не как с девлидом
а по поводу подкаста, с самых первых секунд какая-то неприязнь… то ли из-за потребительского отношения к исскуству программирования «самое главное — бабло» то ли из-за самой манеры речи…
ну такое, не похоже на спор)

По шкале от «1» до «мы используем k8s» оцените количество бессмысленных проблем, которые вам приходится решать ежедневно.


:)

Надо раз в квартал переопубликовывать статью habr.com/ru/company/infopulse/blog/330708

Может быть тогда прекратятся «kill a mouse with an elephant gun», надо инструмент использовать там где он даёт отдачу превышающую затраты. Хотя если эта цель не стоит, то можно и кубернетить.

Тут проблема в том, что даже постфактум сложно бывает определить и отдачу, и затраты.

Лучше перейти на пул реквесты, и тогда будет одно детальное описание сквошнутого комита. Сделать такое описание обычно несложно, т.к. во время код ревью, изменения пул реквеста обмусолятся 100500 раз, и они привязаны к одной единственной задаче.
UFO just landed and posted this here
Обработчик исключений в Котлине — это выражение, вполне себе функциональный и надёжный подход. Вот только обрабатывать ошибки не обязательно. Что роняет всю надёжность на ноль.

Возможно, напишу банальщину и вызову массу споров, но выскажу свое мнение. Проблема checked / unchecked исключений хорошо прослеживается в разработке на java.
Архитекторы java следовали простой логике:
checkеd исключения рассматриваются как ошибки, обрабатывая которые систему можно вернуть в консистентное состояние: например, не найден файл настроек по какому-то пути, давайте найдем его по другому пути, или при чтении произошла ошибка на сети, давайте переподключимся к удаленному хосту и попробуем снова; такие ошибки разработчик должен или явно обработать, или прокинуть на уровень выше;
unchecked исключения рассматриваются как ошибки уровня виртуальной машины (Error) или ошибки разработчика, который не выполняет контракт при использовании некоторого api (RuntimeException); такие ошибки не надо обрабатывать явно, поскольку нет гарантий, что их можно исправить.
И вроде в этом разделении все выглядит хорошо, пока дело не доходит до массового использования. Чем больше подключаемых библиотек, тем больше своих checked исключений, тем больше вопросов: — А можем ли мы вообще что-то исправить, если отловим? Чаще всего ответ: — Нет, — и разработчики прокидывают исключения на уровень выше, а там на уровень выше и т.д. Писать длинные определения throws у методов с перечислением десятков типов исключений мало кто хочет, и тогда, поддавшись соблазну, люди пишут throws Exception. Все, идея разделения исключений сходит на нет.
Кроме того, единожды объявив метод в какой-то библиотеке, вы обязаны поддерживать его сигнатуру, иначе клиенты вашей библиотеки не смогут безопасно ее использовать.
По этой и другим причинам все больше библиотек и фреймворков стали определять свои типы исключений как unchecked, наследуясь от RuntimeException. Это упрощает поддержку, это упрощает рефакторинг, это упрощает разработку кода.
Скорее всего потому Kotlin, как развитие яп java, и придерживается этой идеологии.
UFO just landed and posted this here
Внутренние исключения нужно или обработать или преобразовать в доменное исключение.

Все верно, нужны исключения уровня приложения, и мои тезисы не противоречат этому. Разница лишь в том, делать ли ваш AppException checked или unchecked?
Сделав его checked, вы обязаны обрабатывать свои исключения или прокидывать выше. Это хорошо работает на небольшой кодовой базе. Но когда у вас тысячи классов с сотней методов, то выясняется, что ВСЕ они throws AppException. А потом еще выясняется, что в подавляющем большинстве методов идет простая обертка исключений вида:
try {
...
} catch (SQLException e) {
   throw new AppException(e);
}

Удобно ли это при разработке? Стоит ли надуманное разделение checked / unchecked такого шаблонного кода? Кроме того, checked исключения вы не сможете использовать внутри стримов (stream api), а это явное упущение.
Как я и упомянул, многие фреймворки (тот же spring) перешли на unchecked исключения уровня приложения, и в этом я с ними солидарен.
Написано ещё Страуструпом, что программист должен быть философом. О чём программисты не спорят? О необходимости абстракции — в целом. Никто, я полагаю, не будет спорить о том, нужен ли был ассемблер (или что-то иное, но сходное по сути) над нулями и единицами. Конечно, есть случаи, когда абстрагирование — оверкилл. И они — абстракции — будут (и должны!) вызывать споры. Но необходимость абстракции (в целом для программирования) бесспорна.
Так, вот ты точно заслужил пиво. Если никто не оспорит за 2 дня, приезжай в Иваново на пиво. Король слов на ветер не бросает
Хм… Выбираю пиво, долго и тщательно, редкое и вкусное. Не царское это дело — за «условной Балтикой» ехать. Ну и король, я думаю, «Балтикой» не проставляется: официальный визит, приём, все дела… :)
Моё подчиненное положение сыграло свою роль, совковскую привычку соглашаться с главным нелегко заткнуть

и главное, не я в этом виноват..
― Да. Тиран-деспот, коварен, капризен, злопамятен. Кто-нибудь, поди сюда, ну ты, ну поди сюда, я говорю. Ну! Поздоровайся с ними.
― Здравствуйте.
― Видите, что делаю? О! И самое обидное, не я в этом виноват. Правда?
― Правда.
― Ну иди, все, свободен. Не виноват! Предки виноваты! Прадеды-прабабки, внучатые дяди-тети разные, праотцы, ну, и праматери, угу.
В жизни вели себя как свиньи последние, а сейчас я расхлебывай их прошлое.
Ну паразиты, вот, одно слово, извините за тонкость такую грубость выражения, резкость, сейчас сказать, паразиты, вот и все.
к/ф Обыкновенное чудо
Sign up to leave a comment.

Articles