.NET Разработчик
6.51K subscribers
427 photos
2 videos
14 files
2.04K links
Дневник сертифицированного .NET разработчика.

Для связи: @SBenzenko

Поддержать канал:
- https://boosty.to/netdeveloperdiary
- https://patreon.com/user?u=52551826
- https://pay.cloudtips.ru/p/70df3b3b
Download Telegram
День 1094. #Карьера
Стрижка Яка: Краткий Урок, Как Оставаться Сосредоточенным
«Стрижка яка» — это термин, придуманный Карлин Вьери, доктором философии MIT, в 1991 году после просмотра эпизода «The Ren and Stimpy Show». Это то, чем вы занимаетесь, когда выполняете какую-то глупую, занудную задачу, не имеющую очевидного отношения к тому, над чем вы должны работать, но тем не менее цепочка из множества причинно-следственных связей связывает то, что вы делаете, с выполнением исходной метазадачи.

Вот отличный пример в исполнении Брайана Кренстона https://www.youtube.com/watch?v=AbSehcT19u0

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

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

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

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

Короче говоря, сосредоточьтесь на поставленной задаче и не стригите яка!

Источник: https://betterprogramming.pub/10-tips-to-write-effective-code-reviews-c25c25aa22c5
👍6
День 1095. #юмор
День 1096. #Карьера
Лучший Совет в Вашей Карьере
Снова возьму контент из твиттера))) На этот раз очень известный в узких кругах Ник Чапсас задал простой вопрос: «Какой лучший совет вам когда-либо давали как программисту?»
Лучшие ответы (вне всякого порядка) привожу ниже. А вы пишите ваши варианты в комментариях.

- Компьютер делает то, что вы ему скажете, и только то, что вы ему скажете.

- Когда залезаешь в какой-то код, всегда оставляй его в лучшем виде, чем он был, когда ты его нашёл.

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

- Если ты не знаешь, как это назвать, ты не понимаешь, для чего это нужно.

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

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

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

- Не переживай из-за того, что не знаешь всего, не жди, что сможешь всё запомнить и не бойся потерпеть неудачу.

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

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

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

- Пишите предложение WHERE перед DELETE.

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

Источник: https://twitter.com/nickchapsas/status/1486768911622320131
👍28
День 1097. #BestPractices
Лучшие Практики Разработки в C#. Начало
Написанию кода можно научиться из онлайн документации или учебника. Однако навыки анализа и проектирования так просто не получить. В этой серии постов рассмотрим некоторые передовые методы проектирования, которые на практике доказали свою эффективность.

1. Унифицированный возвращаемый объект
Иногда нужно как-то описать данные, возвращаемые методом. Мы называем это метаданными, так как это не собственно данные, а некоторая важная информация, которая может быть использована позже.

Иногда понятно, что метод возвращает какие-то данные, например коллекцию объектов, и некоторые метаданные (общее количество объектов и текущую страницу). Но иногда наличие метаданных не очевидно. Например, метод void RenameFile(string newName) принимает новое имя файла и ничего не возвращает. В реальном мире это может быть проблемой, потому что операция может завершиться неудачей, и тогда метод должен что-то вернуть, чтобы сообщить об этом вызывающей стороне.

Я уже слышу ваши варианты: вернуть булевый результат, вернуть новое имя файла в случае успеха или пробросить исключение вызывающему коду. Эти решения могут работать, однако лучше всего здесь вернуть унифицированный объект с некоторыми данными, описывающими, что на самом деле произошло:
public enum FileRenameFailureReason {
None = 0,
ExistingName = 1,
PathTooLong = 2
}

public class FileRenameResult
{
public FileRenameFailureReason FailureReason { get; }
public string FinalName { get; }
public bool Succeeded =>
FailureReason == FileRenameFailureReason.None;
}

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

2. Разбиение на страницы
Разбиение на страницы — один из широко используемых паттернов, но почти никто не говорит о нём с точки зрения практики проектирования. Когда вы создаёте API, вы должны контролировать объём данных, проходящих через него. Поэтому при разработке API полезно спроектировать стратегию регулирования объема трафика. Вы можете сказать, что у вас нет лимитов, но скорее всего они просто настолько большие, что вы их не осознаёте. Например, если у вас есть метод GetAllEmployees, вы можете разрешить вызывающей стороне получать данные всех сотрудников. А что, если когда-нибудь в системе будет 10 000 сотрудников. Сейчас самое подходящее время вернуть только первые 1000 или 5000 и предоставить вызывающей стороне объект метаданных, сообщающий, что произошло и как получить следующую порцию.

3. Делегаты вместо Func<>
Когда нужно определить ссылку на метод, иногда полезнее явно определить делегат, а затем его использовать:
public delegate bool MessageHandler(int id, string msg);

public class Module1
{
public MessageHandler Handler { get; set; }
}
public class Module2
{
public Func<int, string, bool> Handler { get; set; }
}

Отличие в том, что вы получите более информативные подсказки в IntelliSense в виде имён параметров вместо arg1, arg2 в случае использования Func<>.

Продолжение следует…

Источник:
https://levelup.gitconnected.com/design-best-practices-in-net-c-8e37b7c3500a
👍4
День 1098. #BestPractices
Лучшие Практики Разработки в C#. Продолжение
Начало

4. Не злоупотребляйте внедрением зависимостей
Представьте, что вы определяете класс Car и из метода Accelerate хотите записать в лог текущую скоростью автомобиля. Вы бы внедрили ILogger, верно? Да, это сработает, и по сегодняшним стандартам дизайна это идеально. Однако, вот такой вопрос: можем ли мы сказать, что класс Car на самом деле зависит от ILogger до такой степени, что без него он не сможет выполнять свою работу?

Ответ прост: Car не должен зависеть от ILogger. Вы можете возразить, что даже если он не полностью зависит от него, он все равно нуждается в нём. Не совсем так. На самом деле ILogger нужен основному приложению, которое знает и о Car, и о ILogger. Основное приложение должно получить некоторую информацию от класса Car, а затем использовать ILogger для регистрации этой информации. Поэтому правильной реализацией будет удалить эту зависимость и реализовать события. В нашем примере класс Car должен определить событие SpeedChanged, а основное приложение должно подписаться на него:
public delegate void SpeedChangedEventHandler(object sender, double speed);

public class Car
{
public event SpeedChangedEventHandler SpeedChanged;

public void Accelerate()
{
var speed = …;


OnSpeedChanged(speed);
}

protected virtual void OnSpeedChanged(double speed)
{
SpeedChanged?.Invoke(this, speed);
}
}
Заметьте, что мы не вызываем событие напрямую из метода Accelerate, а оборачиваем вызов в виртуальный метод, который, во-первых, безопасно вызывает событие, а во-вторых, может быть переопределён (например, если для каких-то типов наследников не нужно вызывать это событие).

5. Использование моментальных снимков (Snapshot)
Продолжая пример выше, допустим, мы захотели отображать значение скорости на экране. Создадим объект трекера, который будет подписан на событие SpeedChanged:
public class Tracker
{
private double currentSpeed = 0;

public Tracker(Car car)
{
car.SpeedChanged += (o, speed) =>
{
currentSpeed = speed;
ShowOnScreen(speed);
};

ShowOnScreen(currentSpeed); // здесь будет 0
}

}
Проблема в том, что к моменту создания трекера объект Car уже может быть создан, запущен и иметь некоторую постоянную скорость. Тогда до изменения скорости трекер будет выводить на экран 0. Здесь поможет шаблон «Моментальный снимок» (Snapshot). Это неизменяемый объект-значение, хранящий состояние объекта Car. Для него как нельзя лучше подойдёт тип записи:
public record CarState(double speed, double temperature, …);

public class Car
{
public CarState Snapshot { get; private set; } = new CarState(0,0,…);

public void Accelerate()
{
var speed = …;

Snapshot = Snapshot with { Speed = speed };

OnSpeedChanged(Snapshot.Speed);
}

}
Тогда при создании трекера его можно инициализировать данными из моментального снимка объекта Car:
public Tracker(Car car)
{
currentSpeed = car.Snapshot.Speed;
car.SpeedChanged += (o, speed) =>
{

}
}

Окончание следует…

Источник:
https://levelup.gitconnected.com/design-best-practices-in-net-c-8e37b7c3500a
👍10
День 1099. #BestPractices
Лучшие Практики Разработки в C#. Окончание
Начало
Продолжение

6. Отделяйте состояние от поведения
Раньше понятие класса в ООП языках объяснялось как шаблон, используемый для создания объекта, и что этот шаблон определяет состояние и поведение объекта. Следуя этой концепции, мы привыкли определять классы буквально со всем, что может принадлежать объекту, включая и состояние, и поведение. Однако со временем этот метод работы оказался неэффективным, особенно в области разработки игр. Там объекты чаще, а иногда и по отдельности, меняют своё состояние и поведение. Поэтому возникла потребность в новом методе работы:
- Состояние должно легко сохраняться, копироваться и дублироваться.
- Поведение должно легко переключаться во время выполнения в соответствии с потребностями и изменениями.
Для этих целей существует паттерн «Стратегия».

7. Неиспользование IoC-контейнеров — не оправдание
Допустим, по какой-то причине вы не используете контейнеры внедрения зависимостей в своём проекте. Но это не оправдание раскидывать создание объектов через new по всему коду.
Разработчики иногда путают внедрение зависимостей (DI), инверсию управления (IoC) и IoC-контейнеры. Это три разные, независимые вещи. Здесь не подходит принцип использовать либо всё, либо ничего. IoC-Контейнеры — это лишь способ сопоставления абстракции зависимости с её реализацией.
Поэтому, если вы не используете IoC-контейнеры, это не означает, что ваши зависимости должны создаваться беспорядочно, без какого-либо планирования и проектирования. Да, в итоге вам придётся использовать new, но есть большая разница между использованием его в некоторых изолированных местах (корне композиции) и ​​по всему коду проекта.

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

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

Источник: https://levelup.gitconnected.com/design-best-practices-in-net-c-8e37b7c3500a
День 1100. #ЧтоНовенького
Новые Функции Visual Studio 2022

Очистка кода при сохранении
Начиная с VS 2022 Preview 2 разработчики могут автоматически выполнять очистку кода при сохранении файла. Это поможет очистить ваш файл кода, правильно отформатировать его и применить ваши настройки стиля кодирования. Некоторые настраиваемые параметры включают: форматирование документа, сортировку и удаление ненужных директив using и т.п. Чтобы включить эту функцию сначала перейдите в раздел Analyze > Code Cleanup > Configure Code Cleanup (Анализ > Очистка кода > Настроить очистку кода), чтобы персонализировать желаемые настройки в профилях очистки кода. Затем перейдите в Tools > Options > Text Editor > Code Cleanup (Инструменты > Параметры > Текстовый редактор > Очистка кода) и отметьте флажок "Run Code Cleanup profile on Save" (Выполнять очистку кода при сохранении). Убедитесь, что при этом вы выбрали нужный профиль очистки.

Ускорение поиска по коду
Поиск в файлах в Visual Studio 2022 уже более чем в 2 раза быстрее для 95% поисковых запросов по сравнению с Visual Studio 2019. В VS 2022 Preview 3 представлен индексированный поиск в файлах, который ещё быстрее! Предварительные замеры производительности показывают, что индексированный поиск в 95% случаев выполняется чуть дольше 1 секунды!
Чтобы убедиться, что индексированный поиск включен, перейдите в Tools > Options > Environment > Preview Features (Инструменты > Параметры > Среда > Предварительный просмотр функций) и убедитесь, что установлен флажок "Enable indexing for faster find experience" (Включить индексирование для более быстрого поиска).
С этого момента при загрузке решения или открытии папки Visual Studio будет запускать вспомогательный процесс ServiceHub.IndexingService.exe и передавать ему список файлов для индексации. Затем индексатор будет просматривать файлы и создаст индекс всех n-грамм, содержащихся в каждом файле.
Когда пользователь выполняет поиск, этот индекс используется для удаления файлов из результатов, чтобы поиск выполнялся быстрее. Процесс индексирования не влияет на загрузку решения, сборку и действия пользователей, поскольку выполняется с приоритетом операционной системы ниже нормального и вне основного процесса Visual Studio.

Источники:
-
https://devblogs.microsoft.com/visualstudio/bringing-code-cleanup-on-save-to-visual-studio-2022-17-1-preview-2/
-
https://devblogs.microsoft.com/visualstudio/code-search-in-visual-studio-is-about-to-get-much-faster/
👍2
$1 млн. - и вы больше никогда не трогаете код (не писать, не ревьюить, не читать и т.п.). Согласитесь?
Anonymous Poll
53%
да
47%
нет
День 1102. #Карьера
Ошибки Прошлых Поколений
Ник Кравер недавно написал в твиттере:
«Вчера я потратил 5 часов на отладку того, как, чёрт возьми, это происходит, только для того, чтобы проснуться в 5 утра и понять: пропущена строка кода. Её нет уже 8 лет. Это никогда не работало. Но из-за маскировки в другом слое это просто не имело значения.»
Вот изменение, которое он добавил в код.

У меня тоже такое случалось. Как-то попросили добавить столбец в результаты поиска (основной функционал нашего сервиса). Код был ещё на классическом ASP. Вызываю я какой-то метод на объекте RecordSet – и ловлю NullReference. Посреди кода, активно обращающегося к этому RecordSet. Прилично офигеваю и лезу дебажить. Оказывается, результаты скидываются в другой объект, RecordSet уничтожается, а ошибки маскировались вызовом «On Error Resume Next» где-то выше по стеку вызовов – я его закомментировал, пока делал изменения. Этот код только при мне «работал» лет 6, и примерно ещё лет 10 до меня.

Бывали у вас подобные истории в практике?
👍11
День 1102. #ЗаметкиНаПолях #AsyncTips
Параллельный Вызов

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

Решение
Класс Parallel содержит простой метод Invoke, спроектированный для таких сценариев. В следующем примере массив разбивается надвое, и две половины обрабатываются независимо:
void Process(double[] arr)
{
Parallel.Invoke(
() => ProcessPartial(arr, 0, arr.Length/2),
() => ProcessPartial(arr, arr.Length/2, arr.Length)
);
}
void ProcessPartial(double[] array, int begin, int end)
{
// Обработка, интенсивно использующая процессор...
}

Методу Parallel.Invoke также можно передать массив делегатов, если количество вызовов неизвестно до момента выполнения:
void DoActions(Action action)
{
Action[] actions = Enumerable.Repeat(action, 20).ToArray();
Parallel.Invoke(actions);
}

Parallel.Invoke поддерживает отмену, как и другие методы класса Parallel:
void DoActions(Action action, CancellationToken token)
{
Action[] actions = Enumerable.Repeat(action, 20).ToArray();
Parallel.Invoke(
new ParallelOptions { CancellationToken = token },
actions);
}

Метод Parallel.Invoke — отличное решение для простого параллельного вызова. Отмечу, что он уже не так хорошо подходит для ситуаций, в которых требуется активизировать действие для каждого элемента входных данных (для этого лучше использовать Parallel.ForEach), или если каждое действие производит некоторый вывод (вместо этого следует использовать Parallel LINQ).

Источник: Стивен Клири “Конкурентность в C#”. 2-е межд. изд. — СПб.: Питер, 2020. Глава 4.
👍5
День 1103. #Карьера
7 Методов Повышения Продуктивности: Какой Подходит Вам? Начало
Существуют жаворонки, совы, ненавистники понедельников, прокрастинаторы, микроменеджеры, бездельники, успешные люди, командные игроки, рабочие пчёлы и множество других типов характеров. Вопрос: какой вы работник, какие методы повышения продуктивности подходят именно вам и как (и когда) вы работаете лучше всего? Вот некоторые способы выяснить это и повысить свою продуктивность.

1. Поедание лягушек: для прокрастинаторов больших задач
Марк Твен однажды сказал: «Если ваша работа состоит в том, чтобы съесть лягушку, лучше всего делать это первым делом с утра. Если нужно съесть двух лягушек, лучше сначала съесть самую большую».
Определите самую важную и самую большую задачу в своем списке дел и сделайте её первой. Вероятно, это задача, о которой вы думали какое-то время и откладывали её, перенося с вчера на сегодня или завтра. Это ваша лягушка, и вы должны собраться и съесть её. Не позволяйте вашей лягушке сидеть рядом с вами и выводить вас из себя, покончите с ней.
Самые успешные лидеры и предприниматели следуют этому методу повышения продуктивности, потому что он работает. Сколько драгоценного времени и энергии вы потратили на беспокойство или откладывание самых больших, самых неприятных и, чаще всего, важных задач? Прокрастинация — убийца продуктивности. Пока вы не съедите свою дневную лягушку, она будет висеть над вами, убивая продуктивность и способность выполнять дела.

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

2. Блокировка времени: для составления графика занятости
Записывать список ежедневных задач — отличная привычка. Кроме того, приятно отмечать выполненные пункты (привет, выброс дофамина!). Но что, если ваш день насыщен встречами, звонками, письмами, обедами, перерывами и другими неприятностями? Что, если вы настолько заняты, что дедлайны приходят и уходят?
Блокировка времени, в отличие от простого списка задач, учитывает затраченное время. Например, если у вас запланировано двухчасовое утреннее совещание, выделите это время в своем расписании. Затем, согласно правильному управлению энергией, вам потребуется 20-минутный перерыв для перезарядки, так что заблокируйте и его. Выделите, скажем, 30 минут для проверки электронной почты и 90 минут для сосредоточенной и продуктивной работы. Распишите весь ваш день и наблюдайте, как растёт ваша продуктивность начинают соблюдаться реалистичные сроки.

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

3. Помидорный график: для спринтов целенаправленной работы и перерывов
Это для тех, кто часами работает без перерывов, чтобы завершить проект, но для них это будет вызов. Помидорный график — это метод тайм-менеджмента, когда вы работаете быстро и целенаправленно, а затем делаете перерыв (название он получил от кухонного таймера, который часто выглядит, как помидор).
Идея состоит в том, что вы работаете по таймеру: 25 минут работы и 5 минут перерыва. Примерно после четырёх таких рабочих спринтов и перерывов — 120 минут — вы делаете более длительный перерыв до 20 минут, прежде чем вернуться к спринтам.
В перерыве можно сходить в туалет, освежить стакан с водой, потянуться, потанцевать, пообщаться и так далее. В течение 25-минутного интервала продуктивности сосредоточьтесь на одной задаче и посмотрите, сколько вы сможете сделать до того, как сработает таймер. У вас может возникнуть соблазн игнорировать перерывы, но не делайте этого. Наблюдайте, как повышается ваша продуктивность и качество работы, а уровень стресса и склонность к выгоранию снижаются.

Совет: установите таймер на 25 минут и сосредоточьтесь на одной задаче, чтобы посмотреть, сколько вы можете сделать, прежде чем сделать 5-минутную передышку.

Продолжение следует…

Источник:
https://blog.trello.com/7-productivity-methods
👍7
День 1104. #Карьера
7 Методов Повышения Продуктивности: Какой Подходит Вам? Продолжение
Начало

4. Биологический прайм-тайм: время лучшей продуктивности
Это ваше личное лучшее время дня для выполнения работы. Оно основано на ваших спадах и пиках уровня энергии, продуктивности, мотивации и сосредоточенности в течение дня. Что вы ели и когда, как вы спали, сколько вы занимались спортом и т. д. — всё это внешние факторы. Думайте о своем биологическом прайм-тайме как о константе.
У «жаворонков» повышенная активность и сосредоточенность по утрам и спад во второй половине дня. «Совы» чувствуют себя немотивированными до позднего вечера. В течение следующих нескольких недель записывайте свой уровень энергии каждый час. Вы увидите, как паттерн обретает форму. Как только вы узнаете своё лучшее время, сфокусируйте моменты высокой энергии на важных проектах, а моменты низкой энергии — на отдыхе, восстановлении или более простых задачах.

Совет: записывайте уровень своей энергии в течение дня. Запланируйте энергичные и сосредоточенные задачи на лучшее время своего биологического благополучия и отдыхайте во время спадов.

5. Zen To Done: продуктивные привычки, которых вы будете придерживаться
Zen To Done (ZTD) — это простая система, основанная на выборе одной из десяти привычек, предназначенных для повышения вашей продуктивности и организованности, и концентрации на ней в течение 30 дней, прежде чем переходить к следующей привычке. Это отлично подходит для тех, кто не может сосредоточиться и хочет получить простой совет, как это сделать.
10 привычек метода продуктивности Zen To Done:
1) Собирайте: записывайте идеи, задачи и мысли по мере их появления, чтобы перенести их из головы на бумагу.
2) Обрабатывайте: принимайте решения и отвечайте на электронные письма быстро, чтобы они не накапливались и не откладывались на потом.
3) Планируйте: запишите свои самые важные дела на неделю, составьте график их выполнения и выполняйте их в первую очередь каждый день.
4) Делайте: сосредоточьтесь на одной задаче за раз — выключите телефон и не проверяйте электронную почту и не переключайтесь между задачами до установленного времени или до тех пор, пока она не будет сделана.
5) Создайте простую надёжную систему: ведите простые списки, отмечайте задачи по мере выполнения и придерживайтесь ежедневных списков.
6) Организуйте: наведите порядок и организуйте своё рабочее пространство, свой почтовый ящик и свой разум — это означает, что нужно решать задачи по мере их возникновения и удалять остальные.
7) Делайте обзоры: делайте еженедельный обзор своих целей и своего прогресса, соответствующим образом корректируя свои системы и цели.
8) Упрощайте: сократите свои задачи и цели до самого необходимого и сосредоточьтесь на них.
9) Соблюдайте распорядок: установите и соблюдайте распорядок дня, который даёт вам время, чтобы сосредоточиться, продуктивно работать и отдыхать.
10) Найдите свою страсть: ищите работу, которой вы увлечены, и обратите внимание, как мало вы прокрастинируете (и как вы счастливы).

Совет: выберите наиболее полезную для вас продуктивную привычку (или начните с первой), пробуйте её в течение 30 дней, прежде чем переходить к следующей.

Окончание следует…

Источник:
https://blog.trello.com/7-productivity-methods
👍13
День 1105. #Карьера
7 Методов Повышения Продуктивности: Какой Подходит Вам? Окончание
Начало
Продолжение

6. Непрерывная серия: для визуализации ваших ежедневных побед
Комик Джерри Сайнфелд поставил перед собой цель писать по одной шутке в день. Шутка даже не должна быть смешной! Он мог тратить всего пять минут в день на своё ремесло. Но это была его цель, простая и ясная: каждый день работать над тем, что он любил.
Чтобы держать себя под контролем, он взял большой ярко-красный маркер и вычёркивал день в календаре, как только писал свою ежедневную шутку (или больше одной, если было вдохновение). Вскоре в его календаре появилась серия ярко-красных крестиков. Это визуальное напоминание о приложенных усилиях и хороший мотиватор для продолжения работы. В конце концов, практика – путь к совершенству.

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

7. Перечень обязательств: для тех, кто делает всё вышеперечисленное
Для тех из вас, кто испробовал все методы повышения продуктивности, но всё ещё не может сосредоточить своё внимание, «Перечень обязательств» Марка Форстера может подойти как нельзя лучше. Это идеально подходит для тех, кто пытается сделать всё и не может выбирать задачи или расставить приоритеты. Вы на всё соглашаетесь. В результате у вас большой список задач, слишком много обязательств, и вы слишком напряжены, чтобы делать свою работу хорошо. Надо ведь избежать выгорания и полного разрушения, не так ли?

6 шагов перечня обязательств:
1) Составьте список: запишите полный список того, как вы проводите своё время (включая работу по дому, время с семьей, встречи, упражнения и составление списка задач на день).
2) Комбинируйте и классифицируйте: разбейте задачи из списка по категориям и посчитайте процент времени, потраченный на каждую. Здесь для визуализации помогут круговые диаграммы!
3) Сделайте обзор: убедитесь, что у важных обязательств есть достаточно времени, чтобы выполнить их хорошо, сократите остальные задачи и скорректируйте свои итоги до 100%.
4) Составьте расписание: в зависимости от того, сколько времени вы хотите (или нужно) потратить на каждую категорию, спланируйте свой день.
5) Ведите контрольные списки: наряду с простыми списками дел, составьте контрольные списки для повторяющихся задач. Контрольные списки более детализированы, разбивают задачу на более мелкие части и позволяют не забыть ни одной детали.
6) Работайте порциями: сосредоточьтесь на одном деле в течение определённого периода времени, прежде чем переключаться на другое, чередуя работу и отдых.

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

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

Источник: https://blog.trello.com/7-productivity-methods
👍9
День 1106. #Tools
Швейцарский Армейский Нож Разработчика
В последнее время твиттер (как англоязычный, так и русскоязычный) завален ссылками на эту утилитку, которую все называют именно так: «Swiss Army Knife for developers».

https://devtoys.app/

Решил опробовать, раз уж так хвалят, тем более, распространяется она в официальном Windows Store.

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

Доступно множество инструментов:
1. Преобразователи
- Из JSON в YAML и обратно
- Преобразование чисел в разные системы счисления

2. Кодеры/декодеры
- HTML
- URL-адрес
- Base64
- GZip
- JWT-декодер

3. Форматеры
- JSON
- SQL
- XML

4. Генераторы
- Хэш (MD5, SHA1, SHA256, SHA512)
- UUID 1 и 4
- “Рыбы” текста (Lorem Ipsum)
- Контрольной суммы

5. Работа с текстом
- Конвертация регистра (строчные/заглавные/camelCase/PascalCase/…)
- Тестер Regex (хотя, должен отметить, простенький, regex101 сильно лучше)
- Text Diff (находит различия между двумя текстами)
- Превью Markdown

6. Графика
- PNG/JPEG компрессор
- Конвертер изображений PNG/JPEG/BMP
- Симулятор дальтонизма (в исходном изображении убирает цвета, которые не видят дальтоники разных типов)

В общем, много мелких полезных утилит, хотя многие на самом базовом уровне. Но разработчики обещают дальнейшие усовершенствования.
👍23
День 1107. #ЗаметкиНаПолях
DateTime как Объект-Значение
Объекты-значения являются ключевой частью предметно-ориентированного проектирования (DDD) и моделей предметной области. Однако разработчики используют их не так часто, как следовало бы, и часто неправильно их понимают. Тип DateTime в .NET является полезным примером объекта-значения.

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

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

Разработчики спрашивают что-то вроде: «Могу ли я иметь список объектов-значений в моей модели», - и ответ почти всегда - нет. Опять здесь может помочь DateTime. Имеет ли смысл иметь список объектов DateTime в модели? DateTime сам по себе, без контекста, не имеет значения в модели предметной области. Только когда он используется для описания чего-то (обычно Сущности) он становится полезным. Вот пример:
07.02.2022
08.02.2022
09.02.2022

Если вы обнаружите этот список в модели, что он значит? Нет способа это узнать. А вот так:
var article = new Article {
CreationDate = new DateTime(2022,2,7),
PublicationDate = new DateTime(2022,2,8),
LastModifiedDate = new DateTime(2022,2,9)
};

Те же три значения DateTime теперь имеют контекст, так как они используются для описания сущности статьи.

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

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

Если вы попытаетесь создать DateTime с недопустимыми значениями, например, с месяцем 13, вы получите исключение ArgumentOutOfRangeException:
var someDate = new DateTime(2022,13,1);

А если вы попытаетесь изменить значение свойства, вы получите ошибку компиляции, т.к. оно доступно только для чтения:
someDate.Month = 13;

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

Так как же их изменить?
Объекты-значения могут предоставлять методы, которые «кажутся» изменяющими их, но на самом деле создают новые экземпляры. Это относится как к DateTime, так и к String в .NET. AddDays(), ToLower() и т.п. возвращают новый экземпляр.

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

Итого
Хотя объекты-значения чаще всего обсуждаются в контексте DDD, есть примеры их использования в фреймворках, с которыми вы работаете каждый день. В .NET типы DateTimestring) являются примерами объектов-значений, и знание их особенностей может помочь при проектировании таких типов в ваших приложениях.

Источник: https://ardalis.com/datetime-as-a-value-object/
👍18
День 1108. #ЧтоНовенького
Новинки System.Text.Json в .NET 6. Начало

1. Игнорирование циклических ссылок
В .NET 5 при обнаружении циклических ссылок выдавалось исключение JsonException. В .NET 6 их можно игнорировать:
JsonSerializerOptions options = new()
{
ReferenceHandler = ReferenceHandler.IgnoreCycles
};
string json = JsonSerializer.Serialize(myObj, options);

2. Уведомления при сериализации/десериализации
Появилось 4 новых интерфейса, которые можно реализовать в соответствии с вашими потребностями:
- IJsonOnDeserialized
- IJsonOnDeserializing
- IJsonOnSerialized
- IJsonOnSerializing

class Product : IJsonOnDeserialized, IJsonOnSerializing
{
public string Name { get; set; }
public string Test { get; set; }

void IJsonOnDeserialized.OnDeserialized()
=> Validate();
void IJsonOnSerializing.OnSerializing()
=> Validate();

private void Validate()
{
if (Name is null)
throw new InvalidOperationException(
"Name can't be null."
);
}
}

3. Порядок сериализации свойств
Атрибут JsonPropertyOrder позволяет контролировать порядок сериализации свойств:
class Product
{
// после Price
[JsonPropertyOrder(2)]
public string Category { get; set; }

// после свойств с порядком по умолчанию
[JsonPropertyOrder(1)]
public decimal Price { get; set; }

// порядок по умолчанию - 0
public string Name { get; set; }

// перед свойствами с порядком по умолчанию
[JsonPropertyOrder(-1)]
public int Id { get; set; }
}

Вывод:
{
"Id": 1,
"Name": "Surface Pro 7",
"Price": 550,
"Category": "Laptops"
}

4. Сериализация из/в поток
В .NET 6 добавлены перегрузки синхронных методов Serialize/Deserialize для потоков:
// десериализация из потока
using MemoryStream ms = new MemoryStream(bytes);
MyClass ex =
JsonSerializer.Deserialize<MyClass>(ms);

// сериализация в поток
JsonSerializerOptions options = new() {
WriteIndented = true
};

using Stream output = Console.OpenStandardOutput();

MyClass ex = new() { Value = "Test" };
JsonSerializer.Serialize<MyClass>(output, ex, options);

Окончание следует…

Источник:
https://blog.okyrylchuk.dev/system-text-json-features-in-the-dotnet-6
👍10
День 1109. #ЧтоНовенького
Новинки System.Text.Json в .NET 6. Окончание
Начало

5. Поддержка IAsyncEnumerable
Сериализация IAsyncEnumerable преобразует его в массив.
static async IAsyncEnumerable<int> GetAsync(int n)
{
for (int i = 0; i < n; i++)
{
await Task.Delay(1000);
yield return i;
}
}

JsonSerializerOptions options = new() {
WriteIndented = true
};
using Stream output =
Console.OpenStandardOutput();

var data = new { Data = GetAsync(5) };

await JsonSerializer.SerializeAsync(
output, data, options);

Для десериализации JSON-массивов корневого уровня добавлен метод DeserializeAsyncEnumerable:
// оборачивает текст в IAsyncEnumerable<T>
using MemoryStream stream =
new(Encoding.UTF8.GetBytes("[0,1,2,3,4]"));

await foreach (int item in
JsonSerializer.DeserializeAsyncEnumerable<int>(stream))
{
Console.WriteLine(item);
}

6. Работа с JSON как с DOM
.NET 6 предоставляет типы для произвольного доступа к элементам JSON в структурированном представлении данных. Новые типы из пространства имён System.Text.Json.Nodes:
- JsonArray
- JsonNode
- JsonObject
- JsonValue

// Парсим объект JSON
var node = JsonNode.Parse(
"{\"Value\":\"Text\",\"Array\":[1,5,13,17,2]}"
);

string value = (string)node["Value"];
// либо
value = node["Value"].GetValue<string>();
Console.WriteLine(value); // Text

int item = node["Array"][1].GetValue<int>();
// либо
item = (int)node["Array"][1];
Console.WriteLine(arrayItem); // 5

// Создаём JsonObject
var obj = new JsonObject
{
["Value"] = "Text",
["Array"] = new JsonArray(1, 5, 13, 17, 2)
};
Console.WriteLine(obj["Value"]); // Text
Console.WriteLine(obj["Array"][1]); // 5

// преобразуем в строку
string json = obj.ToJsonString();
Console.WriteLine(json);
// {"Value":"Text","Array":[1,5,13,17,2]}

Источник: https://blog.okyrylchuk.dev/system-text-json-features-in-the-dotnet-6
👍12
День 1110. #юмор
👍38
День 1111.
20 Лет .NET
Сегодня исполняется 20 лет с выпуска Visual Studio .NET и первой версии платформы .NET.

20 лет инноваций
Корни разработки ПО в Microsoft уходят в DOS и BASIC в 90-х годах. Тогда был большой набор инструментов разработчика со множеством различных утилит и языков для создания самых разных приложений. Каждый инструмент был хорош для решения своих задач. Однако приложениям было трудно обмениваться данными, особенно между машинами.

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

.NET всегда был в авангарде преобразований Microsoft и когда в Microsoft провели ещё одну крупную трансформацию, на этот раз в сторону открытого исходного кода. К 2012 году исходный код веб-фреймворка ASP.NET MVC был полностью открыт и стали приниматься предложения сообщества. В 2014м началось создание кроссплатформенного .NET с открытым исходным кодом на GitHub, и он получил невероятную поддержку и вклад сообщества разработчиков открытого исходного кода. Первая версия была представлена на конференции Red Hat DevNation в 2016 году и её работа была продемонстрирована в Red Hat Enterprise Linux, что было неслыханно в первые дни. .NET не только для Windows. Установились прочные партнерские отношения с такими компаниями, как Red Hat и IBM, чтобы внедрить .NET в RHEL, IBM Z и IBM LinuxONE.

Что дальше?
.NET 6 выпущен в ноябре 2021 года и полным ходом идёт работа над созданием .NET 7. Первая предварительная версия .NET 7 выйдет на этой неделе. В скором времени будет выпущена .NET Multi-platform App UI (.NET MAUI). Она позволит вам создавать нативные приложения для Windows, macOS, iOS и Android с единой кодовой базой. Сейчас самое время попробовать предварительную версию и оставить отзыв.

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

Присоединяйтесь к Скотту Хантеру, Скотту Хансельману и их гостям, которые поделятся своими историями и отправят нас в путешествие в прошлое, настоящее и будущее .NET на www.dot.net сегодня в 20:00 по Москве.

Источник: https://devblogs.microsoft.com/dotnet/happy-20th-anniversary-net/
👍14
День 1112. #ЧтоНовенького
Правило Анализатора для Улучшенной Конкатенации Строк
В SDK .NET 6 добавили новое правило анализатора CA1845. Правило находит выражения конкатенации строк, которые содержат вызовы Substring.

Чтобы избежать ненужного выделения строк, предлагается заменить конкатенацию строк методом Concat и заменить Substring методом AsSpan.

Чтобы включить последнюю версию набора рекомендаций, добавьте следующий параметр в свой проект:
<AnalysisLevel>latest-Recommended</AnalysisLevel>

Источник: https://twitter.com/okyrylchuk/status/1491861969070338049
👍10
День 1113. #Testing
Вы Неправильно Называете Тесты! Начало
Важно давать тестам выразительные имена. Правильное наименование помогает понять, что проверяет тест и как ведёт себя система.

Существует множество соглашений именования тестов. Одним из наиболее известных и, вероятно, одним из наименее полезных является:
[MethodUnderTest]_[Scenario]_[ExpectedResult]

Здесь
- MethodUnderTest – имя тестируемого метода,
- Scenario – условия проведения теста,
- ExpectedResult – ожидаемый в этих условиях результат.

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

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

Это верно, но только до определенной степени. Загадочные имена налагают когнитивный налог на всех. Требуются дополнительные мозговые усилия, чтобы выяснить, что именно проверяется тестом и как это соотносится с бизнес-требованиями. Может показаться, что разобрать имя не так уж и сложно, но нагрузка со временем увеличивается. Это медленно, но верно, увеличивает стоимость обслуживания всего набора тестов. Особенно это заметно, если вы возвращаетесь к тесту после того, как забыли о специфике фичи, или пытаетесь понять тест, написанный коллегой. Читать чужой код уже достаточно сложно. Любая помощь в его понимании очень полезна.

Первоначальное имя, написанное простым языком, читается гораздо проще. Это простое описание тестируемого поведения.

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

Использование символов подчёркивания не касается имён тестовых классов, они обычно не такие длинные. Также обратите внимание, что хотя часто используется шаблон [ClassName]Tests при именовании тестовых классов, это не означает, что тесты ограничены проверкой только этого ClassName. Модуль в модульном тестировании — это модуль поведения, а не класс. Эта единица может охватывать один или несколько классов, фактический размер не имеет значения. Тем не менее, нужно откуда-то начинать. Рассматривайте класс в [ClassName]Tests просто как точку входа, API, с помощью которого вы можете проверить единицу поведения.

Продолжение следует…

Источник:
https://enterprisecraftsmanship.com/posts/you-naming-tests-wrong/
👍8