Обновить
1

Пользователь

Отправить сообщение
Для большей безопасности. При локе на this нет гарантий, что кто-то ещё не решит также использовать ваш объект в качестве ключа, что может привести к внезапным дедлокам.
А вы пропустили теги, я полагаю?
Когда придумаешь хорошую абстракцию, которая хорошо подходит к обоим функциям. )

То есть не всегда или, как минимум, не сразу.
Это лишнее по вашему?

Зависит от контекста и от наполнения этих самых строк. Собственно, в этом и была моя изначальная мысль — всё не так просто. При этом статья не приводит примеров, где надо делить, где не надо, а лишь говорит «маленькие функции — хорошо». Отличный посыл новичкам, которые ринутся выносить приват методы на каждый чих, ведь так Мартин сказал.
А можно сделать одну функцию из 20 строк и 20 функций по 50+ строк.

Тут, кстати, занятный вопрос — а функция, у которой внутри 50 функций на 20 строк, это всё ещё функция на 1000 строк?
Других причин писать большие функции нет.

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

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

Я воспринимаю не «эти книги», я воспринимаю эту конкретную книгу и этого конкретного автора. Есть куда более полезные и сдержанные в своей подаче материалы, а в тысячный раз обсасывать «чистый код» мне лично не хочется. Не исключаю, что я в меньшинстве.
Возможно, я старый и пессимистичный, но я понимаю смысла подобных статей. Автор показывает простейшие примеры на уровне «давайте не смешивать генерацию html вёрстки с высокоуровневой генерацией тегов» и рассказывает, что, внезапно, понятные функции лучше непонятных.
При этом не проводится разбор обратных сценариев и нюансов: а когда, собственно, имеет смысл делать большие функции и чем мы жертвуем (опуская производительность), разбивая и вынося подсчёт высоты в отдельный метод. Каким образом и почему в продакшне таки появляются огромные функции? Неужели, все, кто их пишут — некомпетентны и не читали Clean Code?
Пункт про размер функции непонятно как работает со вложенными функциями, но я подозреваю, что в основном языке автора их на тот момент не было.
Пункт про количество аргументов — абсурд, ведь любой набор из Х аргументов эквивалентен объекту с Х полями. Так что, станет лучше, если мы везде вынесем DTO?

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

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

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

Вернёмся к утверждению: «кто-то осознаёт неравноправное положение, но не считает его угнетённым». Т.е. человек считает, что положение неравноправное, но в плюс, а не минус. При этом он так же считает его правильным. Он сексист?
Проверяем не вызвался ли метод add, а появился ли пользователь в «базе» после вызова сервиса

Да, такое делали, в случае .NET просто через EF InMemory. Хороший подход и, в целом, более правильный, на мой взгляд.
Такие случаи бывают когда сложные условия, циклы.

Были куски логики посложнее, но там по итогу всё переписывалось на легковесную state machine и уже она тестилась. Традиционное «закинем моки и проверим вызовы» показалось не оптимальным.
Как пример: в зависимости от того, обращался пользователь ранее к сервису или нет, надо было вести себя по-разному. Сам вызов метода на получение информации о предыдущих обращениях не тестили, а вот логику в виде условной функции (currentState, userRequest) -> newState покрыли на ура. Пока что коллегам нравится.
Очень похоже на формальную верификацию, так что вряд ли с минимальными усилиями получится

Вот, у меня такие же мысли. Звучит хорошо, но на практике не так легко.
С другой стороны, на каком-нибудь gherkin в секции given можно написать что-то вроде «user with email test@example.com is(n't) registered», но нужно будет написать хэндлер для этого паттерна, приводящий систему в нужное состояние.

К сожалению, не работал с gherkin и вообще BDD не щупал на реальных проектах. Не исключаю, что в итоге оно может оказаться ещё более затратным, чем «тупой» тест с моками.
Спасибо. Именно такой вариант я наблюдал и практиковал у себя.
Что заметил из интересного:
  1. Приходится заглядывать в реализацию, дабы знать, какой именно метод IUserRepository вызывается и какой надо мокать. Когда классы разрастаются, это начинает напрягать и концептуально я не сторонник тестировать, зная реализацию (classical TDD мне по душе больше, чем mockist). В принципе, решается дроблением Repository на более атомарные операции.
  2. Если вы используете строгие моки, то вы также убеждаетесь, что ничего кроме этих зависимостей не вызвали. Звучит неплохо, но на практике у нас вылилось в невероятно хрупкие тесты. Без строгих моков тоже не идеально, но я лично готов это стерпеть.
  3. При увеличении количества вызываемых методов и классов, сетап моков становится сложнее и сложнее. Частично решается так же, как в пункте 1, но не до конца.
  4. Признаться, не уверен, стоит ли действительно тестировать такую логику. Я не припомню ни одного случая, когда у нас вызовы функций исчезали или дублировались, при этом написание таких тестов в более сложной системе это не пара минут.

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

Что меня очень интересует, это то, можно ли с минимальными усилиями описать спецификацию «мы делаем Б и В (publish, add) только если условие А истинно, в противном случае возвращаем ошибку». То есть, вместо того, чтобы императивно проверять, что и когда вызывается, выразить правила декларативно с гарантией того, что они не нарушатся разработчиком случайно.

Из того, что встречал — вместо непосредственно выполнения этих действий вернуть структуру, описывающую, что и как делать, наподобие AST:
blog.ploeh.dk/2017/07/31/combining-free-monads-in-f
Правда, и ASТ также придётся валидировать на корректность тестами.
Вопрос того, насколько с этим удобно работать конкретно в .NET на C# для меня пока открыт.
В одном проекте будет нормой минимальный набор юнит-тестов, в другом надо будет покрывать почти все.

Абсолютно согласен. К сожалению, в индустрии защитить мнение «мы не будем писать юнит тесты т.к. конкретно здесь они не оправданны» куда сложнее, чем обратное. В итоге получается некий карго-культ, когда тесты пишутся потому что циферки красивые и «смотрите, вот у нас несколько сотен тестов, мы серьёзные квалифицированные люди».
P.S. А дальше извините, у меня работа а я и так уже три часа тут торчу.

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

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

С другой стороны, это сильно зависит от домена и характера разработки. Когда я ради интереса набрасывал простейший лексер в относительно ФП стиле с чистыми функциями, тестировать его было одно удовольствие. Никаких километровых моков, простые чистые функции input-output. Можно пойти дальше и попробовать описать некоторые свойства системы не в виде простого юнит-теста, а в виде property-based testing. Если пойти и ещё дальше, то вместо тестов у нас появятся типы и compile-time доказательства корректности программы.
(это конечно не best practices, когда сначала пишут тесты, а потом код)

Почему же? Есть целая методология под это — Test Driven Development.
Я отдельные модули по одному пишу

Приведите, пожалуйста, парочку примеров.
Вот, скажем, стандартный пример из моей практики: приходит ХТТП реквест на регистрацию, надо сделать следующие действия (happy path):
1. Сходить в базу проверить, нет ли пользователя.
2. Создать пользователя в базе
3. Закинуть в message bus сообщение, что новый пользователь был создан
4. Ответить 200 клиенту

Предположим, мы вынесли эту логику на некий бизнес-слой, т.е. у нас есть функция SignUpUser, которая внутри вот это всё делает. Что и как мы будем тестить?
Ваше право, но, насколько я знаю, пока что большинство англоговорящих предпочитает were.
Ок, так как правильно в случае трансгендерного Криса — Chris was angry или Chris were angry?

Я бы использовал was, потому что they тут в предложении даже не участвует. Если участвует — множественное. Chris was angry. It's not the first time they were.
относиться как к представителям противоположного пола

В каких контекстах относиться? Я определённо не осилю отношения с mtf трансом, особенно интимные. Надеюсь, это за дискриминацию пока что не считается.
Не гнать, не насмехаться, не отталкивать в общении

Эти вещи кажутся более важными, imo.
Программисты визуалы, им нафиг ваши созвоны не сдались.

Во-первых, крайне смелое обобщение. Во-вторых, смотря что понимать под созвоном. Митинги на часы мне не сдались не потому что я, как вы говорите, «визуал», а потому что мне больно от их КПД — 90% времени приходится выслушивать кого-то, попивая чай и не особо вникая в тему.

Тем не менее, быстрый созвон на 15 минут, лично для меня, в разы эффективнее и продуктивнее переписки. Вот не могу я улавливать/объяснять текстом так же хорошо, как голосом. Если это что-то более-менее формальное — после обсуждения подводим итоги и закидываем minutes, дабы не потерять информацию.
Признаться, это самый безобидный пример. Для меня they даже как-то более естественно, потому что неизвестный пол не значит мужской (и женский тоже не значит, впрочем). Сам использую singular they в речи более восьми лет и не чувствовал, чтобы он был forced. Более того, как уже сказали, конструкция существует давно — это не что-то, выдуманное на волне толерантности.

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

Интересно, не накинулись ли ещё на mankind.
Не придирки ради, разве не clustered index определяет то, является ли таблица кучей? Соответственно, можно создать таблицу с PK, но без индекса и наоборот.
my 2 cents:
Много лет придерживался и до сих придерживаюсь мнения, что многие статьи и книги Боба крайне категоричны и, местами, откровенно опасны для новичков. С другой стороны, опытному разработчику они не сильно и нужны. Куда больше они подходят для инициации обсуждения и холиворов.
rant
А утверждение Боба, что типизация не нужна, так как есть юнит тесты вызывает у меня целую бурю не очень хороших эмоций.

Тут рядом упоминали Code Complete — поддержу. Хорошая, обстоятельная книга, перекосов и абсолютизма не припомню.

Одна из причин, почему ООП в целом выглядит хорошо — его часто противопоставляют спагетти на 4000 строчек. Крайне сложно утверждать, что между «красивой иерархией классов» и «монстром на 4000 строк» ты выберешь монстра. Однако, это ложная дихотомия.
Во-первых, существует то же ФП, которое местами показывает очень интересные результаты и вообще функции это классы для бедных и наоборот. Во-вторых, мейнстрим ООП на «сервисах» это по сути glorified процедурное программирование.

Очень хорошее и в некотором смысле inspiring выступление по ООП можно наблюдать у Sandi Metz:
www.youtube.com/watch?v=OMPfEXIlTVE
Что интересно, в процессе разбиения получился набор более мелких классов, каждый из которых старается выполнять одну вещь и при этом не хранить состояния. Что, внезапно, эквивалентно передаче функций без замыканий.
Также отмечу фрагмент про наследование и его опасность, мой личный опыт в целом подтверждает.
А вот если оставить ситуацию по умолчанию, то черные вообще скорее всего не смогут претендовать на эти позиции.

С чего бы это? У нас 5 вакансий, в выборке 10 белых и 1 чёрный. Кто этому чёрному мешает соревноваться?
Более того, возникает ещё один интересный вопрос — а зачем нам в штате чёрный, если он проигрывает борьбу без квот? Почему наличие работника с определённым цветом кожи является преимуществом (кроме virtue signalling)? Так же, если говорим о расах, то давайте поговорим и об азиатах, а ещё вспомним национальности. Я искренне не вижу, как эта модель работает и производит что-либо продуктивное.

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность