.NET Разработчик
6.52K subscribers
442 photos
3 videos
14 files
2.12K links
Дневник сертифицированного .NET разработчика. Заметки, советы, новости из мира .NET и C#.

Для связи: @SBenzenko

Поддержать канал:
- https://boosty.to/netdeveloperdiary
- https://patreon.com/user?u=52551826
- https://pay.cloudtips.ru/p/70df3b3b
Download Telegram
День семьсот пятьдесят четвёртый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
77. Начинайте с «Да»
Однажды я бродил по супермаркету, пытаясь найти эдамаме (что, по моему представлению, должно быть каким-то овощем). Я не был уверен, искать его в овощном, в заморозке или в консервах. Я сдался и попросил продавщицу помочь, но она тоже не этого знала!

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

Сотрудница в этом случае рассмотрела запрос и исходила из того, что надо решить проблему и удовлетворить запрос. Она начала с «да», а не с «нет».

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

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

Эта простое понимание радикально изменило мой подход к работе. Оказывается, есть много способов сказать «да». Когда кто-то говорит вам: «Слушай, единственное, чего не хватает этому приложению - это сделать все окна круглыми и полупрозрачными!», - вы можете сразу отвергнуть это предложение, а также поставить вопрос о психической вменяемости коллеги. Но часто вместо этого лучше начать с вопроса: «А почему?». Часто существует какая-то реальная и веская причина, по которой этот человек ставит во главу угла круглые полупрозрачные окна. Например, возможно, вы собираетесь заключить контракт с новым крупным клиентом, который требует именно этого.

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

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

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

Начать с «да» означает работать вместе с коллегами, а не против них.

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Alex Miller
День семьсот пятьдесят девятый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
78. Шаг назад и автоматизация, автоматизация, автоматизация
Я работал с программистами, которые, когда их просили произвести подсчёт строк кода в модуле, вставляли все файлы в один текстовый редактор и использовали его функцию подсчёта строк. Затем они делали это снова на следующей неделе. И через неделю. Это было плохо.

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

Итак, почему люди выполняют одну и ту же задачу снова и снова, вместо того чтобы остановиться, сделать шаг назад и потратить время на её автоматизацию?

Распространённое заблуждение №1: автоматизация предназначена только для тестирования
Конечно, автоматизация тестирования - это здорово, но зачем останавливаться на достигнутом? В любом проекте изобилуют повторяющиеся задачи: контроль версий, компиляция, упаковывание, создание документации, развёртывание и отчетность. Для многих из этих задач скрипт окажется мощнее, чем мышь. Выполнение утомительных задач станет быстрее и надёжнее.

Распространённое заблуждение №2: у меня есть IDE, поэтому мне не нужно автоматизировать
Вы когда-нибудь использовали аргумент «Но это работает на моей машине?» в спорах с товарищами по команде? Современные IDE имеют тысячи потенциальных настроек, и практически невозможно гарантировать, что все члены команды имеют одинаковые конфигурации. Системы автоматизации сборки дадут вам контроль и повторяемость результата.

Распространённое заблуждение №3: чтобы автоматизировать это, мне нужно изучить экзотические инструменты
Вы можете пойти по длинному пути, используя полноценный консольный язык, например, bash или Power-Shell, и систему автоматизации сборки. Если же вам нужно взаимодействовать с веб-сайтами, можно использовать такие инструменты, как Selenium.

Распространённое заблуждение №4: я не могу автоматизировать эту задачу, потому что не могу работать с этим форматом файлов
Если для части вашего процесса требуются документы Word, электронные таблицы или изображения, это действительно может быть сложно автоматизировать. Но действительно ли это необходимо? Можете ли вы использовать обычный текст? CSV файлы вместо таблиц? XML/JSON? Часто небольшая подгонка процесса под автоматизацию может дать хорошие результаты и значительно снизить трудозатраты.

Распространённое заблуждение №5: у меня нет времени разбираться в этом
Вовсе не обязательно зазубрить все команды bash. Учитесь на ходу. Когда у вас есть задача, которую, по вашему мнению, можно и нужно автоматизировать, узнавайте об инструментах автоматизации ровно столько, сколько вам нужно. И делайте это на ранних этапах проекта, когда обычно легче найти время. Как только вы добьетесь успеха, вы (и ваш начальник) увидите, что имеет смысл инвестировать в автоматизацию.

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Cay Horstmann
👍1
День семьсот шестьдесят девятый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
79. Используйте Анализаторы Кода
Ценность тестирования - вот что вбивают в головы разработчикам ПО с ранних этапов их пути в программировании. В последние годы рост модульного тестирования, разработки, основанной на тестировании, и agile методов свидетельствует о всплеске интереса к максимальному использованию тестирования на всех этапах цикла разработки. Однако тестирование - это лишь один из многих инструментов, которые можно использовать для улучшения качества кода.

В далеком прошлом, когда C был ещё новинкой, процессорное время и память любого типа были в дефиците. Первые компиляторы C знали об этом и поэтому сокращали количество проходов через код, которые они выполняли, исключая некоторые семантические проверки. То есть компилятор проверял только небольшое подмножество ошибок, которые могли быть обнаружены во время компиляции. Чтобы компенсировать это, Стивен Джонсон написал инструмент под названием lint (он удалял мусор из вашего кода), который реализовал некоторые статические проверки, удалённые из компилятора. Однако инструменты статического анализа приобрели сомнительную репутацию из-за того, что выдавали большое количество ложноположительных предупреждений и замечаний о стилистических соглашениях, которые не всегда необходимо соблюдать.

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

Более сложные инструменты, такие как Splint для C, Pylint для Python или анализаторы Roslyn для .NET настраиваются. То есть вы можете выбрать, какие ошибки и предупреждения будет выдавать инструмент, с помощью файла конфигурации, в командной строке или в вашей IDE. В некоторых случаях можно писать аннотации для анализатора прямо в коде.

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

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

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Sarah Mount
День семьсот семьдесят четвёртый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
80. Проверяйте Требуемое, а не Случайное Поведение
Распространённая проблема тестирования - предположение, что реализация делает именно то, на что вы хотите проверить. На первый взгляд, это скорее хорошо, чем плохо. Однако проблема становится очевидной, если перефразировать это предложение: распространённая ошибка при тестировании заключается в привязке тестов к особенностям реализации, когда эти особенности являются случайными и не имеют отношения к желаемой функциональности.

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

Например, для метода CompareTo(object obj) интерфейса IComparable, требования к результату заключаются в том, что:
- он отрицательный, если экземпляр класса стоит по порядку раньше, чем объект, переданный в аргументе метода,
- он положительный, если экземпляр класса стоит позже,
- он равен нулю если объекты считаются равными.
Этот стиль сравнения используется во многих API, включая компаратор для функций сортировки. И хотя конкретные значения –1 и +1 обычно используются в реализациях для обозначения отрицательного и положительного результатов, соответственно, программисты часто ошибочно предполагают, что эти значения и представляют фактическое требование, и, следовательно, пишут тесты, которые публично подтверждают это предположение.

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

Чрезмерно определённые тесты часто являются проблемой при использовании метода «белого ящика» в модульном тестировании. Тесты методом «белого ящика» используют структуру кода для определения необходимых тестовых случаев. Типичный отказ при таком тестировании происходит, когда тесты проверяют в буквальном смысле, что код делает именно то, что написано в коде. Простое повторение того, что уже очевидно из кода, не добавляет ценности тесту и ведёт к ложному чувству прогресса и безопасности.

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

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Kelvin Henney
День семьсот восемьдесят первый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
81. Тестируйте Точно и Конкретно
Важно проверять желаемое, существенное поведение кода, а не случайное поведение конкретной реализации. Но, помимо этого, тесты должны быть точными и конкретными.

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

Когда программистов спрашивают: «Что бы вы тут протестировали?», - наиболее частым ответом является что-то вроде: «Что в результате сортировки получается отсортированная последовательность элементов». Хотя это правда, это не вся правда. Если спросить, что ещё, то многие программисты добавят, что результирующая последовательность должна быть той же длины, что и исходная. И это тоже правильно, но всё равно недостаточно. Например, если взять последовательность:
3 1 4 1 5 9
То ответ ниже удовлетворяет обоим условиям (результат отсортирован и той же длины):
3 3 3 3 3 3

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

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

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

Как заметил Тони Хоар: «Есть два варианта проектирования ПО: сделать его настолько простым, чтобы в нём очевидно не было недостатков, либо сделать его настолько сложным, чтобы в нём не было очевидных недостатков.»

Использование конкретных примеров позволяет избавиться от случайной сложности и случайных ошибок. Например, для той же самой последовательности:
3 1 4 1 5 9
Результат сортировки будет:
1 1 3 4 5 9
Никакой другой ответ не годится!

Конкретные примеры помогают проиллюстрировать общее поведение доступным и однозначным образом. Результатом добавления элемента в пустую коллекцию является не просто то, что она не пуста: теперь в коллекции есть единственный элемент, и этот элемент является добавленным элементом. Два или более элементов будут удовлетворять условию непустой коллекции, но этот тест будет неверен. Один элемент с другим значением – тоже. Результатом добавления строки в таблицу заключается не просто то, что в таблице становится на одну строку больше. Нужно также проверить, что первичный ключ этой строки совпадает с первичным ключом строки, которую мы добавили. И так далее.

При определении поведения тесты должны быть не просто правильными: они также должны быть точными.

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Kelvin Henney
День семьсот восемьдесят восьмой. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
82. Тестируйте во Сне и в Выходные
Расслабьтесь. Я не говорю о рабском труде или даже о сверхурочной работе по выходным или ночью. Скорее, я хочу обратить ваше внимание на то, сколько вычислительных мощностей имеется в вашем распоряжении. В частности, как много всего мы не используем, чтобы немного облегчить свою программистскую жизнь. Вам постоянно не хватает времени или вычислительных ресурсов в течение рабочего дня? Если да, то почему бы не запускать тесты в нерабочее время?

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

У вас достаточно возможностей, чтобы проверить стабильность вашего продукта? Длительные тесты жизненно важны для выявления утечек памяти и других проблем со стабильностью. Они редко запускаются в дневное время, так как это требует времени и ресурсов. Вы можете автоматизировать тест утечки памяти и запустить его ночью, а то и на выходных. С 6 вечера пятницы до 6 утра понедельника на тестирование у вас будет целых 60 часов.

Вам достаточно времени для тестирования производительности? Я видел, как команды спорили друг с другом, чтобы заполучить на время среду тестирования производительности. В большинстве случаев ни одна из команд не получает достаточно времени в течение дня, в то время как среда практически простаивает в нерабочее время. Серверы и сеть не так загружены ночью или в выходные дни. Это идеальное время для проведения качественных тестов производительности.

Слишком много вариантов для проверки вручную? Во многих случаях ваш продукт предназначен для работы на различных платформах. Например, как в 32-, так и в 64-битных системах Linux, MacOS или Windows, или просто в разных версиях одной и той же операционной системы. Что ещё хуже, многие современные приложения используют множество различных транспортных механизмов и протоколов (HTTP, gRPC, SOAP и т.п.). Ручное тестирование всех этих вариантов занимает очень много времени и, скорее всего, выполняется незадолго до выпуска продукта из-за нехватки ресурсов. Увы, это может быть слишком поздно, чтобы отловить и исправить некоторые неприятные ошибки. Автоматизированные тесты, выполняемые в ночное время или в выходные дни, гарантируют, что все эти варианты будут проверяться чаще. Немного разобравшись в сценариях, вы можете запланировать несколько назначенных заданий, чтобы начать тестирование ночью и на выходных. Есть также много инструментов для тестирования, которые могут помочь. Некоторые организации создают матрицы серверов, объединяющие сервера различных отделов и команд в общий пул для более эффективного их использования. Если это доступно в вашей организации, вы можете отправлять туда наборы тестов для выполнения ночью или в выходные дни.

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Rajith Attapattu
День семьсот девяносто пятый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
83. Тестирование – Это Строгость в Разработке Программного Обеспечения
И снова о тестировании.

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

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

Тестировать материальные вещи сложно, потому что нужно физически построить то, что вы хотите протестировать. Не очень заманчиво строить что-то только для того, чтобы посмотреть, что произойдет. Но процесс создания программного обеспечения обходится значительно дешевле. Мы разработали целую экосистему инструментов, которые упрощают это: модульное тестирование, mock-объекты, платформы для тестирования и многое другое. Инженеры из других областей могут только мечтать иметь возможность что-то построить и протестировать в реальных условиях. Как разработчики ПО, мы должны рассматривать тестирование как основной (но не единственный) механизм проверки программного обеспечения. Вместо того, чтобы производить какие-то предварительные расчёты поведения программы, в нашем распоряжении уже есть инструменты для реализации лучших практик разработки. То есть у нас есть противоядие против менеджеров, которые говорят: «У нас нет времени на тестирование». Строитель моста никогда не услышит от своего начальника: «Не беспокойтесь о проведении структурного анализа этого объекта - у нас очень сжатые сроки». Признание того, что тестирование - это действительно путь к воспроизводимости и качеству программного обеспечения, позволяет нам, разработчикам, отвергать аргументы против тестирования, как непрофессиональные и безответственные.

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

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Neal Ford
День восемьсот девятый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
84. Мыслите Состояниями
У людей в реальном мире странные понятия состояний. Утром я зашёл в кофейню, чтобы подготовиться к очередному дню преобразования кофеина в код (купить латте). Но девушка ответила: "Извините, у нас вообще, совсем нет никакого молока, ни капли."

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

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

Рассмотрим простой интернет-магазин, который работает только по предоплате. Класс заказа, может содержать такой метод:
public bool IsComplete() => IsPaid() && HasShipped();

Вроде логично. Но, даже если это выражение аккуратно извлечено в метод, а не продублировано повсюду, такого выражения не должно существовать вообще. Тот факт, что оно существует, говорит о проблеме. Почему? Потому что заказ не может быть отправлен до оплаты. Таким образом, HasShipped() не может быть true, если IsPaid() не true, что делает эту часть выражения избыточной. Возможно, вам всё равно нужен метод IsComplete() для ясности кода, но тогда он должен выглядеть так:
public bool IsComplete() => HasShipped();

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

Эти состояния важны, т.к. нужно убедиться, что:
1. вы находитесь в ожидаемом состоянии, прежде чем выполнять операции,
2. вы можете перейти только в одно из доступных состояний.
То есть, вы должны тщательно защитить свои объекты в нужных местах.

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

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

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Niclas Nilsson
День восемьсот тридцать шестой. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
85. Простые системы и закон Галла
Когда вам нужно будет создать новую большую систему, чтобы заменить старую, помните о законе Галла и о пользе эволюционного развития и частой обратной связи.

Закон Галла гласит:
Всегда обнаруживается, что сложная работающая система произошла от простой работающей системы. Сложная система, созданная с нуля, никогда не работает и невозможно заставить её работать, как надо. Вы должны начать с работающей простой системы.

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

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

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

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

Экстремальное программирование
Одна из ключевых ценностей экстремального программирования (XP) - это простота в сочетании с практикой простого дизайна. По сути, практика XP вращается вокруг частой доставки работающего ПО и его изменения по мере необходимости для удовлетворения текущих потребностей клиентов или пользователей. Экстремальное программирование серьезно относится к закону Галла и встраивает его в процесс разработки.

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

Что проще и быстрее построить: монолит или набор микросервисов? Монолит, всегда. Так что сначала подумайте о создании модульного монолита и рассмотрите микросервисы, когда у вас будет простая рабочая система.

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

Источник: https://ardalis.com/simple-systems-galls-law/
День восемьсот пятьдесят первый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
86. Одна Голова Хорошо, а Две (Зачастую) Лучше
Программирование требует много обдумывания и сосредоточенности, а глубокие мысли требуют уединения. Таков стереотип программиста.

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

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

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

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

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

Парное программирование популярно, но не только среди сторонников гибкой разработки программного обеспечения. Скептики объединения в пары, задают вопрос: «Почему я должен платить двум программистам, чтобы они выполняли работу одного?» Вы действительно не должны. Однако объединение в пары повышает качество, понимание предметной области, технологий и методов (например, трюков IDE) и снижает последствия «риска лотереи» (когда один из ваших опытных разработчиков выигрывает в лотерею и увольняется на следующий день).

Какова долгосрочная ценность изучения нового сочетания клавиш? Как измерить общее улучшение качества продукта в результате объединения в пары? Как измерить вклад вашего партнёра, который не позволил вам пойти по тупиковому пути к решению сложной проблемы? В одном исследовании говорится об увеличении эффективности и скорости на 40%*. Какова ценность снижения последствий «риска лотереи»? Большинство из этих преимуществ трудно измерить.

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

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

*“The Case for Collaborative Programming”, J. T. Nosek - Communications of the ACM, 1998

Источник:
https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Adrian Wible