Результаты поиска
ITVDN: курсы программирования
Видеокурсы по
программированию
Подписка

300+ курсов по популярным IT-направлениям

Выбери свою IT специальность

Подписка
Подписка

300+ курсов по популярным IT-направлениям

Результаты поиска по запросу: design pattern
Что такое паттерны проектирования в программировании

Автор: Влад Сверчков

Что такое паттерн (шаблон) проектирования. Когда используют шаблоны. Какими бывают паттерны проектирования. Порождающие. Структурные. Паттерны поведения. Как выбрать шаблон? Выводы. Начинающие программисты всегда приходят к точке, когда их код превращается в "спагетти". Его трудно читать, он содержит массу повторений, лишних функций, а добавление нового функционала превращается в десятый круг ада. Одно из лучших средств предотвращения этого – использовать паттерны проектирования (Design Patterns). Является ли это серебряной пулей, какие преимущества и недостатки паттернов существуют, и какие из них необходимо знать разработчикам? Ответы разбираем ниже. Что такое паттерн (шаблон) проектирования? Паттерны – это типичные архитектурные решения проблем, которые часто встречаются при разработке ПО. Их другое название – шаблоны, и что интересно – человечество очень часто окружает себя шаблонами в повседневной жизни: одинаковые гнезда розетки и формы вилок в помещениях – универсальное решение для электропитания; вилки и ложки – инструменты потребления почти любой пищи; чашки – емкости для размещения любой жидкости и так далее. Человек всегда стремится упростить традиционную деятельность, и это не могло обойти стороной программирование. Идеи создания универсальных правил для качественной разработки существовали ещё до 90-х годов прошлого века, но действительно прорывной стала работа "Design Patterns: Elements of Reusable Object-Oriented Software" (1994) авторства Эриха Гамма, Ричарда Хелма, Ральфа Джонсона и Джона Влиссидеса, которые именуют себя как "Банда четырех" (Gang of Four, GoF). В книге описано 23 паттерна и их применение в объектно-ориентированном дизайне. Этот труд стал фундаментальным и теперь паттерны gof составляют костяк многих обсуждений качественного кода. Когда используют паттерны В разработке шаблоны используют при необходимости приведения кода к следующим критериям: Читабельность – другие разработчики должны без труда понимать написанное. Масштабируемость – легкость в создании нового функционала. Поддерживаемость – обновление кодовой базы должно проходить как можно более плавно. Также они способны повысить скорость и производительность разработчика – паттерны это действительно обеспечивают. Они хорошо справляются и со следующими задачами: уменьшение количества потенциальных ошибок и узких мест; упрощение рефакторинга; уменьшение технического долга; улучшение коммуникации девелоперов с другими программистами, проектными менеджерами, владельцами и т. д. Необходимость использовать шаблоны проектирования растет вместе с увеличением кодовой базы, особенно при коммерческой разработке – когда создаваемое ПО должно приносить прибыль. Важно помнить, что использование паттернов иногда вовсе неуместно. Оно может значительно усложнить читабельность, громоздкость и масштабируемость кода. Например, несложный функционал, который нечасто используется и занимает немного места в коде, не требует pattern-вмешательства. А вот репетативный код, решающий классические задачи (сортировка, перебор данных и т. д.) – идеальный претендент на применение шаблона. Чтобы не ошибиться сначала выясните контекст вашей проблемы, а уже потом выбирайте паттерны программирования, которые лучше всего удовлетворяют требованиям. Какими бывают паттерны проектирования В своей книге GoF выделяют три больших семейства: Семейство Краткое описание Порождающие паттерны или Creational Patterns Предоставляют лучшие способы создания объектов. Они абстрагируются от процесса конкретизации и делают вашу систему независимой от создания, компоновки и представления ее объектов. Популярные примеры: "Абстрактная фабрика" (Abstract Factory), "Одиночка" (Singleton), "Прототип" (Prototype), "Фабричный метод" (Factory Method). Структурные паттерны или Structural Patterns Фокусируются на композиции объекта. Помогают убедиться в том, что изменение части системы не повлечет за собой необходимость изменений в других ее составляющих. Популярные примеры: "Прокси" (Proxy), "Адаптер" (Adapter), "Компоновщик" (Composite), "Фасад" (Facade). Паттерны поведения или Behavioral Patterns Зона ответственности – алгоритмы и обмен информацией между объектами. Популярные примеры: "Посетитель" (Visitor), "Итератор" (Iterator), "Цепочка обязанностей" (Chain of Responsibility), "Стратегия" (Strategy). Рассмотрим более подробно некоторые из них. Порождающие Порождающие паттерны – это надежные помощники в создании объектов таким образом, чтобы в будущем с ними было максимально легко работать. Дадим краткое описание некоторых шаблонов: Паттерн Одиночка / Синглтон обеспечивает наличие только одного экземпляра класса с глобальной точкой доступа. Singleton распространен в задачах конфигураций или логирования в приложениях, где нужен единый контролируемый доступ. Шаблон Прототип позволяет создавать новые объекты путем копирования существующих экземпляров. Используется Prototype в ситуациях, когда создание объекта слишком дорого, например, при клонировании сложных или ресурсоемких объектов. Фабричный метод определяет интерфейс для создания объектов, но позволяет подклассам самостоятельно определять тип создаваемых объектов. Fabric Method полезен во многофункциональных приложениях, где классы должны иметь возможность выбирать тип объектов, например, при работе с различными форматами документов, системами онлайн платежей и т. д. Абстрактная фабрика определяет интерфейс для создания семейств связанных объектов без указания их конкретных классов. Используют Abstract Factory для создания различных компонентов пользовательского интерфейса, которые должны работать вместе и обеспечивать единый стиль (светлая/темная тема веб-сайта и т. д.). Рассмотрим пример на паттерне Singleton. Представьте себе простое приложение – музыкальный плеер. Он позволяет пользователям воспроизводить музыкальные файлы. Однако одновременно должен работать только один экземпляр плеера – возможность открытия нескольких одновременно надо пресечь. Этого можно достичь с помощью шаблона Singleton. Простой пример кода на языке C#: public class MusicPlayer {             private static MusicPlayer _instance;             private MusicPlayer()             {             // Инициализируем музыкальный плеер (например, загружаем плейлисты)             }             public static MusicPlayer Instance             {             get             {             if (_instance == null)             {                        _instance = new MusicPlayer();             }             return _instance;             }             } ​            public void PlaySong(string songPath)             {             // Запустить песню             }             public void PauseSong()             {             // Поставить на паузу             }             public void StopSong()             {              // Остановить воспроизведение             } } // Получаем экземпляр MusicPlayer MusicPlayer player = MusicPlayer.Instance; // Используем функционал MusicPlayer player.PlaySong("C:\\Users\\yourUsername\\Music\\mySong.mp3"); player.PauseSong(); player.StopSong(); Каждый раз, когда в разных участках проекта вам нужно будет создавать экземпляр плеера для соответствующего взаимодействия, вы всегда будете работать только с одним и тем же экземпляром, избегая дублирования. Если вы программируете на языке си шарп, подробно разобрать популярные паттерны проектирования C# с примерами вы можете по ссылке. Структурные Из краткого описания в таблице легко сделать вывод, что структурные паттерны позволяют сформировать надежную, масштабируемую и поддерживаемую архитектуру проекта. Краткое знакомство: Прокси обеспечивает объект-посредник для контроля доступа к другому объекту. Обычно шаблон Proxy используют для реализации "ленивой" загрузки, когда объект создается или инициализируется только при обращении к нему (например, загрузка картинок с высоким разрешением). Адаптер позволяет объектам с несовместимыми интерфейсами работать вместе. Применяется паттерн Adapter для интеграции новых компонентов в существующую систему без изменения ее кода. Подходит для использования новой библиотеки в старом приложении. Компоновщик используется для иерархической компоновки объектов для дальнейшей работы с ними как с единым объектом. Используется для создания древовидных структур, таких как файловые системы или GUI, где каждый узел может быть как простым, так и Composite объектом. Фасад (Facade) предоставляет упрощенный интерфейс для взаимодействия со сложной системой или набором классов. Он уменьшает сложность работы с подсистемами и предоставляет пользователям единый входной интерфейс для выполнения рутинных операций. Изучить именно структурные паттерны проектирования C# (с примерами) вы можете по ссылке. Поведенческие Паттерны поведения в первую очередь определяют связи между объектами и то, как они осуществляют обмен информацией. Например: Паттерн Посетитель (Visitor) позволяет добавлять новые операции к объектам без изменения их оригинальных классов. Используется для взаимодействия с объектами со сложной структурой, когда внесение дополнительной логики в оригинальные классы неоправданно усложняет код. Итератор / Iterator предоставляет удобный механизм последовательного и простого доступа к элементам коллекции, несмотря на сложность ее построения. Данный паттерн поведения популярен при обходе элементов контейнеров, например списков или массивов – он предоставляет универсальный интерфейс для различных типов коллекций. Цепочка обязанностей или же паттерн Chain of Responsibility позволяет передавать запрос цепочкой обработчиков, пока один из них не обработает запрос. Незаменим при обработке запросов на сервере, где каждый обработчик может передать запрос следующему обработчику в цепочке: проверка при авторизации на сайте, обработка событий в GUI и тому подобное. Для входа в паттерны проектирования книга от Gang of Four будет хорошей точкой отсчета. Вы познакомитесь с классикой и академическим раскрытием темы, используя паттерны gof. Если же вы хотите обогатить свои знания шаблонов, но предпочитаете язык Java, рекомендуем видео курс "Паттерны проектирования Java". Как выбрать паттерн? Сначала вы должны проанализировать задачу – для большей понятности выполните ее декомпозицию, разбив на несколько составляющих. При этом используйте системный подход: просчитайте, как ваше решение повлияет на весь проект, какие элементы оно затронет сейчас, и какое влияние оно окажет на добавление нового кода. Если вы уже работаете в IT-компании, ваши коллеги, тимлид или архитектор могут подсказать вам целесообразность использования того или иного паттерна, раскрыть нюансы уже существующей архитектуры, кодового стиля и многое другое. Только после тщательного анализа можно переходить к подбору шаблона, учитывая все преимущества и недостатки. Кстати, в этих задачах хорошими помощниками будут бесплатные AI-ассистенты вроде ChatGPT, Gemini и др. Также не забывайте об использовании других методик улучшения кодовой читабельности, масштабирования и чистоты: SOLID принципы – они регламентируют 5 основных принципов создания структурированного, качественного кода. Недавно мы проводили вебинар, на котором разбирали каждый принцип в деталях, приглашаем к просмотру! А если вас интересует прикладной характер SOLID принципов на Java, можете пройти данный видео курс. GRASP (General Responsibility Assignment Software Patterns) – паттерны для объектно-ориентированного проектирования. Они не имеют выраженной структуры и носят более абстрактный характер, чем паттерны gof. DRY (Don't Repeat Yourself) – главная идея данного принципа заключается в создании кода, который не будет иметь дубликаций в проекте. KISS (Keep It Simple, Stupid) – регламентирует написание как можно более простого кода, чтобы его можно было легко читать и понимать. Рефакторинг – возвращение к уже написанному коду с целью его улучшения без изменения функциональности. Другие техники, зависящие от проектов. Выводы Паттерны играют ключевую роль в современной разработке. Они аккумулируют в себе лучшие практики создания кодовой базы таким образом, чтобы достичь максимальной легкости и эффективности разработки, особенно на больших проектах. Конечно, не всегда их использование уместно – нужно анализировать задачи и продумывать последствия применения того или иного шаблона, чтобы не получить огромный чемодан без ручки. Развивайте вашу экспертизу в области паттернов – это win-win стратегия. С одной стороны перед работодателями вы предстанете как опытный и высококвалифицированный специалист, а с другой – ваши программные решения будут иметь элегантный характер, легкость в чтении, поддержке и масштабировании. Используете ли вы паттерны во время разработки? Возможно, только изучаете? Оставляйте в комментариях ваши ответы!
Нововведения в С# 7.0

Автор: Mads Torgersen

В этой статье мы расскажем о нововведениях в языке C# 7.0, которые были представлены в марте 2017 года как часть релиза Visual Studio 2017. В C# 7.0 появился целый ряд нововведений и основное внимание уделяется использованию данных, упрощению кода и улучшению производительности. Возможно, самой главной особенностью являются кортежи, которые упрощают получение различных результатов, и сопоставление с шаблоном, что упрощает код, который зависит от формы данных. Существует также множество других нововведений, как значительных, так и не очень. Надеемся, что в совокупности они сделают ваш код более эффективным и точным, а вы при этом будете работать продуктивнее и останетесь довольны результатом. Если вас интересует процесс разработки, который привел к этому набору функций, вы можете найти заметки, предложения и множество обсуждений на эту тему на сайте C# language design GitHub. Если данная информация кажется вам знакомой, это только потому, что релиз предварительной версии состоялся в августе прошлого года. В окончательной версии C# 7.0 изменились некоторые детали, некоторые из них - из-за отличных отзывов на указанную ранее статью. Получайте удовольствие от C# 7.0 и удачного хакинга! Out переменные В более ранних версиях C# использование out параметров является не таким легким, как нам хотелось бы. Прежде чем вызвать метод с out параметрами, сначала необходимо объявить переменные, чтобы перейти к нему. Поскольку вы обычно не инициализируете эти переменные (они все равно будут перезаписаны методом), вы также не можете использовать ключевое слово var, но вам нужно указать полный тип: public void PrintCoordinates(Point p) { int x, y; // have to "predeclare" p.GetCoordinates(out x, out y); WriteLine($"({x}, {y})"); } В C# 7.0 мы добавили out переменные, что позволяет объявлять переменную прямо в точке, где она передается как out аргумент: public void PrintCoordinates(Point p) { p.GetCoordinates(out int x, out int y); WriteLine($"({x}, {y})"); }  Обратите внимание, что переменные находятся в области видимости в окружающем блоке, поэтому последующая строка может их использовать. Многие виды утверждений не устанавливают свою собственную область действия, поэтому out переменные, объявленные в них, часто вводятся в область видимости. Поскольку out переменные объявляются непосредственно в качестве аргументов для out параметров, компилятор может обычно указывать, каков должен быть их тип (если только не существует конфликтующих перегрузок), поэтому вместо типа можно использовать ключевое слово var: p.GetCoordinates(out var x, out var y);  Общим использованием out параметров является шаблон Try..., где логическое возвращаемое значение указывает на успех, а out параметры переносят полученные результаты: public void PrintStars(string s) { if (int.TryParse(s, out var i)) { WriteLine(new string('*', i)); } else { WriteLine("Cloudy - no stars tonight!"); } }  Мы также допускаем «сбрасывание» в качестве out параметров в виде «_», что позволит вам проигнорировать параметры, которые вам не нужны: p.GetCoordinates(out var x, out _); // I only care about x Соответствие с шаблоном В C# 7.0 вводится понятие шаблонов, которые являются синтаксическими элементами, позволяющими проверить соответствие значения определенной «форме» и извлечь информацию из значения, если такое соответствие имеется. Примеры шаблонов в C# 7.0: • Константные шаблоны c (где c – константное выражение в C#), которые проверяют, равняется ли переменная этой константе. • Шаблоны типа T x (где T – тип и x – идентификатор), которые проверяют, имеет ли переменная тип T, и если да, то извлекают значение в новую переменную x типа T. • Var шаблоны var x (где x – идентификатор), которые всегда совпадают и просто помещают значение ввода в новую переменную x с тем же типом. Это только начало; шаблоны являются новым типом элемента языка C#, и в будущем мы обязательно добавим новые шаблоны в C#. В C# 7.0 мы улучшаем две существующие языковые конструкции с шаблонами: • is теперь может использоваться не только с типом, но и с шаблоном; • case в операторе switch теперь может использовать шаблоны, а не только константы. В будущих версиях C#, вероятно, мы добавим больше мест, где можно использовать шаблоны. Шаблоны с is Рассмотрим пример использования is с константным шаблоном и шаблоном типа: public void PrintStars(object o) { if (o is null) return; // constant pattern "null" if (!(o is int i)) return; // type pattern "int i" WriteLine(new string('*', i)); } Как видно из примера, переменные шаблона, представленные шаблоном, аналогичны out переменным, описанным ранее, поэтому могут быть объявлены в середине выражения и использоваться в ближайшей окружающей области. Также как out переменные, переменные шаблона изменяемы. Мы часто ссылаемся на out переменные и переменные шаблона совместно как «переменные выражения». Шаблоны и Try-методы часто используются вместе: if (o is int i || (o is string s && int.TryParse(s, out i)) { /* use i */ } Шаблоны с выражениями switch Мы обобщаем варианты использования switch: • Вы можете использовать любой тип (не только простые типы). • Шаблоны могут использоваться в выражениях case. • Вы можете добавлять дополнительные условия к выражениям case. Вот простой пример: switch(shape) { case Circle c: WriteLine($"circle with radius {c.Radius}"); break; case Rectangle s when (s.Length == s.Height): WriteLine($"{s.Length} x {s.Height} square"); break; case Rectangle r: WriteLine($"{r.Length} x {r.Height} rectangle"); break; default: WriteLine(""); break; case null: throw new ArgumentNullException(nameof(shape)); } Существует несколько особенностей, которые следует отметить в этом новом расширенном выражении switch: • Порядок выражений case теперь имеет значение: как и в случае с выражениями catch, у выражений case выбирается первое по порядку выражение, удовлетворяющее условию. Поэтому важно, чтобы условие квадрата было перед условием прямоугольника. Кроме того, как и в случае с выражениями catch, компилятор поможет вам пометить явные недостижимые условия. До этого вы не могли определить порядок выполнения, так что это не является нарушением существующего поведения. • Условие по умолчанию (default) всегда вычисляется последним: несмотря на то, что после него идет условие null, условие default будет проверено после него. Это сделано для совместимости с существующей семантикой. Однако, как правило, вы помещаете условие default  в конце. • Условие null в конце достижимо, потому что шаблоны типов следуют примеру текущего is  и не срабатывают для null. Это гарантирует, что null значения не будут случайно сопоставлены с первым шаблоном типа; вы должны явно указать, как им управлять (или оставить логику для условия default). Переменные шаблона, объявленные ключевым словом case..., находятся в области видимости только в соответствующем разделе switch. Кортежи Обычно хочется вернуть несколько значений из метода. Все доступные варианты в существующих версиях C# являются менее оптимальными: • Out параметры: использование является неэффективным (даже при использовании рассмотренных нововведений) и они не работают с асинхронными методами. • System.Tuple <...>: выглядит многословным для использования и требует выделения кортежного объекта. • Специальный вид переноса для каждого метода: слишком много кода для типа, единственной целью которого служит временная группировка нескольких значений. • Анонимные типы, возвращаемые через тип возврата dynamic: потери в производительности и отсутствие проверки статического типа. Для упрощения этой задачи в C# 7.0 были добавлены кортежи и литералы кортежей: (string, string, string) LookupName(long id) // tuple return type { ... // retrieve first, middle and last from data storage return (first, middle, last); // tuple literal }  Теперь метод эффективно возвращает три строки, объединенные как элементы кортежа. Вызывающий код метода получит кортеж и может индивидуально иметь доступ к элементам: var names = LookupName(id); WriteLine($"found {names.Item1} {names.Item3}."); Имена полей Item1 и т. д. являются именами по умолчанию для элементов кортежа и могут использоваться всегда. Но они не очень наглядны, поэтому вы можете добавить лучшие имена: (string first, string middle, string last) LookupName(long id) // tuple elements have names Теперь получатель этого кортежа имеет более описательные имена для дальнейшей работы: var names = LookupName(id); WriteLine($"found {names.first} {names.last}."); Вы также можете указать имена элементов непосредственно в литералах кортежей: return (first: first, middle: middle, last: last); // named tuple elements in a literal Как правило, вы можете назначать типы кортежей друг для друга, независимо от их имен: при условии, что отдельные элементы будут присваиваемыми, типы кортежей могут свободно преобразовываться в другие типы кортежей. Кортежи – это типы значений, а их элементы – общедоступные изменяемые поля. Они имеют значение равенства, а это значит, что два кортежа являются равными (и имеют одинаковый хэш-код), если все их элементы попарно равны (и имеют одинаковый хэш-код). Это делает кортежи полезными для различных ситуаций, а не только для возвращения нескольких значений из метода. Например, если вам нужен словарь с составным ключом, используйте кортеж в качестве ключа, и все будет работать правильно. Если вам нужен список с несколькими значениями в каждой позиции, также используйте кортеж для корректной работы. Кортежи полагаются на базовые структурные типы, которые называются ValueTuple <...>. Если вы выявите модель, что еще не включает эти типы, вы можете вместо этого выбрать их с помощью NuGet: • Щелкните правой кнопкой мыши проект в обозревателе решений и выберите «Manage NuGet Packages…». • Выберите вкладку «Browse» и выберите «nuget.org» в качестве «Package source». • Найдите «System.ValueTuple» и установите его. Распаковка кортежей Еще один способ использования кортежа – это его распаковка. Объявление распаковки является синтаксисом для разделения кортежа (или другого значения) на его части и назначения этих частей по отдельности новым переменным: (string first, string middle, string last) = LookupName(id1); // deconstructing declaration WriteLine($"found {first} {last}."); В объявлении распаковки можно использовать ключевое слово var для отдельных переменных: (var first, var middle, var last) = LookupName(id1); // var inside Или даже поместить var перед скобками как аббревиатуру: var (first, middle, last) = LookupName(id1); // var outside Вы также можете распаковать в уже существующие переменные с помощью присвоения распаковки: (first, middle, last) = LookupName(id2); // deconstructing assignment Распаковка выполняется не только для кортежей. Любой тип может быть распакован, если у него есть метод распаковки (образец или расширение): public void Deconstruct(out T1 x1, ..., out Tn xn) { ... } Out параметры соответствуют значениям, которые будут присвоены в результате распаковки. (Почему используются out параметры, а не кортежи? Чтобы можно было иметь несколько перегрузок метода с разным количеством параметров). class Point { public int X { get; } public int Y { get; } public Point(int x, int y) { X = x; Y = y; } public void Deconstruct(out int x, out int y) { x = X; y = Y; } } (var myX, var myY) = GetPoint(); // calls Deconstruct(out myX, out myY); Это будет обычный шаблон для создания «симметричных» конструкторов и методов распаковки таким способом. Так же, как и для out переменных, мы разрешаем «сбрасывать» в распаковке параметры, которые вам не нужны: (var myX, _) = GetPoint(); // I only care about myX Локальные функции Иногда вспомогательная функция имеет смысл только внутри одного метода, в котором вызывается. Теперь вы можете объявить такие функции внутри других функций как локальную функцию: public int Fibonacci(int x) { if (x < 0) throw new ArgumentException("Less negativity please!", nameof(x)); return Fib(x).current; (int current, int previous) Fib(int i) { if (i == 0) return (1, 0); var (p, pp) = Fib(i - 1); return (p + pp, p); } } Параметры и локальные переменные из области видимости доступны для локальной функции так же, как и для лямбда-выражений. В качестве примера рассмотрим методы, реализованные как итераторы, что обычно нуждаются в неитераторном методе-оболочке для точной проверки аргументов в момент их вызова (так как сам итератор не запускается, пока не будет вызван MoveNext). Локальные функции идеально подходят для этого сценария: public IEnumerable Filter(IEnumerable source, Func filter) { if (source == null) throw new ArgumentNullException(nameof(source)); if (filter == null) throw new ArgumentNullException(nameof(filter)); return Iterator(); IEnumerable Iterator() { foreach (var element in source) { if (filter(element)) { yield return element; } } } } Если бы Iterator был приватным методом рядом с Filter, то мог быть доступен для других членов в использовании напрямую (без проверки аргументов). Кроме того, необходимо было бы передавать все те же аргументы, что и Filter, вместо того, чтобы иметь их только в области видимости. Улучшения литералов В C# 7.0 появилась возможность добавлять «_» в качестве разделителя в числовые литералы: var d = 123_456; var x = 0xAB_CD_EF;  Вы можете поместить разделитель в любом месте между цифрами, чтобы улучшить читабельность. Они не влияют на значение. Кроме того, C# 7.0 представляет бинарные литералы, так что вы можете указывать битовые шаблоны непосредственно вместо того, чтобы знать шестнадцатеричную систему наизусть. var b = 0b1010_1011_1100_1101_1110_1111;  Локальные переменные и возвращаемые значения по ссылке Теперь можно не только передать параметры в метод по ссылке в  С# (с помощью ключевого слова ref), но и возвратить данные из метода по ссылке, а также сохранить в локальной переменной тоже по ссылке. public ref int Find(int number, int[] numbers) { for (int i = 0; i < numbers.Length; i++) { if (numbers[i] == number) { return ref numbers[i]; // return the storage location, not the value } } throw new IndexOutOfRangeException($"{nameof(number)} not found"); } int[] array = { 1, 15, -39, 0, 7, 14, -12 }; ref int place = ref Find(7, array); // aliases 7's place in the array place = 9; // replaces 7 with 9 in the array WriteLine(array[4]); // prints 9 Очень удобно передавать ссылки на определенные места в больших структурах данных. Например, в игре информация содержится в большом заранее выделенном массиве структур (во избежание пауз на сбор мусора). Теперь методы могут вернуть ссылку непосредственно на одну из таких структур, с помощью которой вызывающий код может читать и изменять эту структуру. Существуют некоторые ограничения для обеспечения безопасности: • Можно возвращать только ссылки, которые возвращать безопасно: ссылки, переданные в метод и ссылки на поля объектов. • Локальные переменные инициализируются определенной ячейкой памяти и в будущем не меняются. Обобщенные типы асинхронных возвратов До сегодняшнего дня асинхронные методы могли возвращать только void, Task или Task. В C# 7.0 позволяется создавать типы, которые также могут быть возвращены асинхронным методом. Например, можно создать структуру ValueTask, которая поможет избежать создания объекта Task в случае, когда результат асинхронной операции уже доступен в ожидаемое время. Для многих асинхронных сценариев, например, где используется буферизация, такой подход может значительно уменьшить число выделений памяти и таким образом значительно повысить производительность. Конечно, можно придумать и другие ситуации, в которых task-подобные объекты будут полезны. Правильное создание таких типов не будет простой задачей, поэтому мы не ожидаем, что большое количество разработчиков будут создавать их. Однако мы полагаем, что они будут появляться в различных моделях и прикладных интерфейсах, и вызывающий код сможет просто использовать await, как сейчас для Task. Больше членов в виде выражений Методы и свойства в виде выражений используются в C# 6.0, но не все типы членов можно было так объявлять. В C# 7.0 к списку членов в виде выражений добавилась поддержка аксессоров, конструкторов и финализаторов: class Person { private static ConcurrentDictionary names = new ConcurrentDictionary(); private int id = GetId(); public Person(string name) => names.TryAdd(id, name); // constructors ~Person() => names.TryRemove(id, out _); // finalizers public string Name { get => names[id]; // getters set => names[id] = value; // setters } } Это пример функции, которая была предоставлена сообществом, а не командой компилятора Microsoft C#. Ура, открытый код! Throw выражения Выбросить исключение в середине выражения очень легко: достаточно вызвать метод, который это сделает! Но в C# 7 теперь можно использовать throw как часть выражения в определенном месте: class Person { public string Name { get; } public Person(string name) => Name = name ?? throw new ArgumentNullException(nameof(name)); public string GetFirstName() { var parts = Name.Split(" "); return (parts.Length > 0) ? parts[0] : throw new InvalidOperationException("No name!"); } public string GetLastName() => throw new NotImplementedException(); } Источник
Валидация форм средствами HTML5

Автор: Редакция ITVDN

Введение  Используя формы в HTML5, Вы часто используете методы проверки (валидации) данных, ведь их игнорирование может привести: к потерям пользователей,к мусору в базе данных или к взлому сайта. Исторически сложилось, что создание форм с хорошей валидацией – сложная задача. В HTML5 есть инструменты обработки данных для форм, с их помощью можно производить валидацию, включающую в себя специальные атрибуты и новые типы входных данных. Давайте разберем их детальнее. 1. Специализированные типы входных данных В HTML5 введены несколько новых типов ввода. Они используются для создания поля ввода, принимающего только определенные типы данных. Новые типы входных данных выглядят следующим образом: color date datetime datetime-local email month number range search tel time url week Пример: <input type="email"/> Если браузер не поддерживает данный тип ввода, поле будет вести себя, как обычное поле ввода текста.  2. Обязательные поля для заполнения  Просто добавив атрибут "required" к <input>, <select> или <textarea>. , Вы говорите браузеру, что значение должно быть заполнено. <input type="checkbox" name="terms" required >   3. Лимиты Мы можем установить некоторые ограничения и лимиты, например, максимальные и минимальные значения для числовых полей. Чтобы ограничить длину поля ввода надо использовать атрибут "maxlength".  <input type="text" name="name" required  maxlength="15"> Поле <input type="number" />  использует атрибуты "max"и "min", чтобы создать диапазон возможно-допустимых значений (в примере минимально допустимый возраст 18)  <input type="number" name="age" min="18" required>   4. Стилизирование CSS3 псевдо-классы позволяют украсить форму в не зависимости от ее состояния. Это: :valid :invalid :required :optional :in-range :out-of-range :read-only :read-write В примере мы объединили селекторы "valid" и "invalid" с псевдо-классом "focus" для закрашивания поля формы в красный или зеленый, в зависимости от того, что делает пользователь: выбирает или печатает.  input:focus:invalid, textarea:focus:invalid{     border:solid 2px #F5192F; } input:focus:valid, textarea:focus:valid{     border:solid 2px #18E109;     background-color:#fff; }   5. Подсказки Вы замечали всплывающее окно с подсказкой при отправлении неправильно заполненной формы? Установив атрибут "title" для поля ввода, можно добавить подсказки, указывающие на ошибки при нарушении тех или иных правил валидации. Обратите внимание, что разные браузеры отображают всплывающие подсказки по-разному. В браузере Chrome значение названия атрибута будет отображаться мелким шрифтом, под основным сообщением об ошибке. В Firefox другая проблема: использовав атрибут “pattern” после того как он берется в качестве шаблона, Вы не получите всплывающую подсказку.  <input type="text" name="name" title="Пожалуйста введите имя пользователя.">   6. Шаблоны Атрибут "pattern", разрешает разработчикам задавать регулярное выражение, которое браузер сравнивает с данными ввода, прежде чем отправить форму заявки. Вот как это можно использовать: <input type="email" name="email" required pattern="^\S+@\S+\.\S+$" title="example@mail.com">  С функцией фильтрования входных данных мы можем принимать только полный e-mail адрес. Источник: http://tutorialzine.com/2014/12/quick-tip-easy-form-validation-with-html5/
Валидация AngularJS

Автор: Редакция ITVDN

Введение Валидация достаточно часто вызывает затруднения с работой в веб-приложениях. Во многих случаях фреймворки должны быть использованы для валидации значений формы. Кроме того, эти фреймворки часто не работают во всех браузерах. AngularJS приходит с проверкой, построенной так, что теперь гораздо легче создать валидацию, которая работает во всех браузерах. На практике Использование angular-message Чтобы использовать angular-message, нужно внести в ваш проект модуль:  angular.module("realestateApp", ["ngMessages"]); Теперь ng-message будет доступен для использования. Формы Для инициализации процесса валидации, Вы должны начать с формы контейнера: <form name="tenantForm"> Теперь внутри тега можно добавить управление и логику на их проверку. В сценариях валидации, как правило, есть несколько основных атрибутов. Те, которые стоит использовать: Required, Minimum, Maximum, Pattern, Email, Number, и URL. Required Этот атрибут заставляет form быть недействительным, если обязательное поле не вводится. <input type="text" required /> Minimum Length Этот атрибут указывает минимум символов для ввода до того, как значение будет принято. <input type="text" ng-minlength=5 /> Maximum Length Этот атрибут указывает максимальную длину или проверка будет неверна. <input type="text" ng-maxlength=20 /> Pattern Matching Эта функция позволяет согласовать совпадения при использовании Regex. <input type="text" ng-pattern="[a-zA-Z]" /> Email Matching Angular обеспечивает пользовательские функции по электронной почте. <input type="email" name="email" ng-model="user.email" /> Number Этот требует ввода в цифровом формате перед проверкой. <input type="number" name="age" ng-model="user.age" /> URL Этот требует ввода в ссылочном формате перед проверкой. <input type="url" name="homepage" ng-model="user.url" /> Сообщение об ошибке Ранее использовался error-container, но теперь можно использовать директиву ng-message: <div ng-messages="tenantForm.Email.$error" ng-messages-include="messages.html" class="errors"></div> Также нужен файл messages.html для хранения сообщений об ошибках: <div class="messages"> <div ng-message="required">Required</div> <div ng-message="minlength">Too short</div> <div ng-message="maxlength">Too long</div> <div ng-message="email">Invalid email address</div> <div ng-message="compareTo">Must match the previous entry</div> <div ng-message="number">Must be a number</div> <div ng-message="url">Must be in URL format</div> </div> Сообщение об отмене ошибки Иногда Вы должны иметь пользовательские сообщения об ошибках, не охватываемых messages.html. Вы можете сделать это, добавив тег span в диапазон для любого сообщения об ошибке. То, что должно отобразиться: <div ng-messages="tenantForm.FirstName.$error" ng-messages-include="messages.html" class="errors"> <span class="messages" ng-message="minlength">Must be more than 3 characters</span> <span class="messages" ng-message="maxlength">Must be more than 20 characters</span> </div> Собираем всё вместе Теперь, объединив messages.html с index.html. <form name="tenantForm" novalidate style="width: 500px">     <div class="row">         <div ng-repeat="tenant in tenant">             <div class="form-group">                 <label>First Name: label>                 <input type="text"                        placeholder="First Name"                        name="FirstName"                        ng-model="tenant.FirstName"                        ng-minlength=3                        ng-maxlength=20 required />                 <div ng-messages="tenantForm.FirstName.$error"                      ng-messages-include="messages.html" class="errors">                     <span class="messages"                     ng-message="minlength">Must be more than 3 charactersspan>                     <span class="messages"                     ng-message="maxlength">Must be more than 20 charactersspan>                 div>             div>             <div class="form-group">                 <label>Home Phone: label>                 <input type="number"                        placeholder="Phone Number"                        name="HomePhone"                        ng-model="tenant.HomePhone"                        ng-minlength=7                        ng-maxlength=10 required />                 <div ng-messages="tenantForm.HomePhone.$error"                      ng-messages-include="messages.html" class="errors">                     <span class="messages"                     ng-message="minlength">Must be more than 7 digitsspan>                     <span class="messages"                     ng-message="maxlength">Must be less than 11 digitsspan>                  div>             div>             <div class="form-group">                 <label>Email: label>                 <input type="email"                        placeholder="Email"                        name="Email"                        ng-model="tenant.Email"                        required />                 <div ng-messages="tenantForm.Email.$error"                      ng-messages-include="messages.html" class="errors">div>             div>             <div class="form-group">                 <label>Webpage: label>                 <input type="url"                        placeholder="Webpage"                        name="Webpage"                        ng-model="tenant.Webpage"                        required />                 <div ng-messages="tenantForm.Webpage.$error"                      ng-messages-include="messages.html" class="errors">                 div>             div>         div>     div>               form> Этот подход кажется чище, чем использование директивы ng-show. Кроме того, это уменьшит дублирование кода путем центрального места хранения ваших сообщений об ошибках, но в то же время используется для пользовательских сообщений. Источник: http://www.codeproject.com/Articles/992545/AngularJS-Validation
Карьера в IT: кто такой Embedded-разработчик, задачи и обязанности

Автор: Влад Сверчков

Кто такой Embedded-разработчик? Сферы применения Embedded-разработки. Что должен знать Embedded-разработчик. Как стать Embedded-разработчиком. Где получить знания. Мягкие навыки. Ключевые тренды в Embedded. Карьерные перспективы и зарплата Embedded Engineer. Количество вакансий. Конкуренция. Заработная плата. Карьерные возможности. Выводы. Подавляющее большинство новичков в Украине выбирают тестирование или разработку с привлечением C#./NET, Java, Python, JavaScript (фронтенд и Node.js). Эти направления имеют наибольшее количество вакансий в IT, низкие требования к высшему образованию, мощную распиаренность почти во всех учебных центрах, а также относительно простой переход в IT с любой не-айтишной профессии. Специальность, которую мы будем сегодня рассматривать, не является столь популярной, трендовой. Однако она не менее важна, чем другие IT-направления. Герой нашей статьи занимается разработкой встроенных (embedded) систем, и его называют Embedded-разработчик. Что это за специальность, насколько она важна и где используется, что нужно учить для её овладения, как выглядит день Embedded-ера, какие карьерные перспективы и зарплаты у специалистов этого направления – разбор этих и других интригующих вопросов читайте ниже. Кто такой Embedded-разработчик? Начнём с понятия “Embedded система”. Трактовка в разных источниках отличается, но если свести всё под один знаменатель – это компьютеризированная система, которая встроена в механическую или электронную систему и выполняет определенную функциональность. То есть это система, в которой компьютер (как правило микроконтроллер или микропроцессор) является неотъемлемой частью другой системы. Как пример: микроконтроллер в вашей кофейной машине, микроволновке или стиральной машине; устройство, обеспечивающее срабатывание подушек безопасности в автомобиле, контроллер в самолете, который собирает определенные данные о полёте – даже Bluetooth-наушники содержат свою собственную встроенную систему. Соответственно, Embedded-разработчик – это специалист, занимающийся разработкой подобных встроенных систем, используя программирование (software) и навыки работы с "железом" (hardware). Жизненный цикл продукта очень тесно связан с разработчиком встроенных систем. Обязанности Embedded-разработчика могут различаться в зависимости от микроконтроллеров / микросхем / устройств и т. п., с которыми он работает, но основные фазы, где ощутима роль этого специалиста, следующие: Анализ требований. Коммуникация с клиентами, дизайнерами и инженерными командами для определения функциональных и технических требований к встроенной системе. Проектирование системы. Разработка архитектуры и дизайна встроенной системы, выбор аппаратных и программных компонентов. Проверка базовой работоспособности. Перед началом работы Embedded разработчик должен проверить функционирование платы, обновить драйвера при необходимости и убедиться, что “железо” исправно. Программирование. Написание программного кода, встроенных программ и системных протоколов. Тестирование и отладка. Проведение тестов для проверки работоспособности embedded-системы. Интеграция. Обеспечение взаимодействия встроенной системы с аппаратурой, внешними устройствами и другими составляющими системы. Оптимизация производительности. Усовершенствование эффективности и производительности встроенной системы, учитывая ограниченные ресурсы. Документация. Формирование диагностических отчётов, технических инструкций и документации по разработке ПО. Также чтение форумов, статей и инструкций к платам и компонентам, с которыми ведется работа. Сотрудничество с другими командами. Взаимодействие с hardware и software разработчиками, участие в различных митингах, обсуждениях, коммуникациях с заказчиком и т. д. Безопасность и надежность. Обеспечение высокого уровня безопасности, надежности и работоспособности встроенной системы. Типичный рабочий день разработчика Embedded состоит из всего понемногу: написание и отладка кода, поиск багов; работа с аппаратной начинкой – иногда приходится и паяльником поколдовать, и что-то мультиметром измерить, и осциллограф применить и т.п.; чтение документации, поиск информации на форумах; тестирование встроенных систем и их составляющих; код-ревью; рефакторинг; взаимодействие с командой, руководством: митинги, деловая переписка, созвоны по определенным вопросам (или живое общение) и т. д. Сферы применения Embedded-разработки Embedded в XXI веке имеет хороший прирост востребованности в связи с развитием IT-индустрии, в особенности сетевых технологий, операционных систем, языков программирования и в результате модернизации “железа”. В настоящее время область применения встроенных систем достаточно объемна: Бытовая электроника. Встроенные системы являются неотъемлемыми атрибутами уютного жилья: это смарт-телевизоры, холодильники, мультиварки и другая кухонная электроника, устройства безопасности, смарт-девайсы для дома. Машиностроительная промышленность. Embedded технологии являются ключевыми для современных транспортных средств, начиная от гражданского автопрома и заканчивая мощными строительными гулливерами. Они входят в состав двигателей, навигационных систем, климат-контроля, развлекательных блоков и т. д. Медицина. Современная медицина невозможна без комплексного цифрового оборудования, включая устройства мониторинга пациентов, системы визуализации, диагностические инструменты и т. д. Промышленная автоматизация. Встроенные системы используются в промышленных системах управления, программируемых логических контроллерах (PLC) и робототехнике для автоматизации и управления процессами. Телекоммуникации. Встроенные системы – неотъемлемая часть сетевого оборудования, маршрутизаторов, коммутаторов и коммуникационных устройств для эффективной передачи данных. Аэрокосмическая промышленность. Современная авионика использует эмбеддед для управления функциями самолета, системами навигации и связи. Если кто-то хочет терраформировать Марс – без Embedded будет очень трудно. Военное дело. Встроенные системы играют решающую роль в оборонных программах как в мирное время (наблюдение, анализ, прогнозирование, наведение и т. д.), так и во время войны (вспомните те же джавелины, дроны, хаймарсы, пэтриоты и т. д. – там очень много электроники). Умные сети. Развитие интеллектуальных сетей (smart grid) увеличивает эффективность и надежность распределения электроэнергии. IoT (Интернет вещей). Устройства IoT в значительной степени зависят от встроенных систем сбора, обработки и передачи данных для различных программ. Примеры: умный дом, автоматизированные системы полива, умные города и т. д. Что должен знать Embedded-разработчик В Embedded-е целая палитра специальностей. Например, приставки “Software”, “Firmware” указывают на фокус именно на создании ПО, а “Hardware” и “Hardware Design” – на аппаратной части. Тайтл вроде "Embedded Systems Engineer" говорит о необходимости иметь одинаково хорошие hardware и software знания. Также надо понимать, что в разных компаниях один и тот же тайтл может иметь под капотом совершенно разные технологии в зависимости от аппаратной начинки, разновидности встроенной системы и т. д. Наше описание необходимых технологий будет охватывать и аппаратное, и программное крыло требований, что делает его более близким к тайтлу "Embedded Systems Engineer". Если вы хотите больше в software, изучайте глубже технологии, направленные на разработку софта; если же в hardware – больше внимания уделяйте аппаратным навыкам. Итак, мы проанализировали тематические статьи, мнения популяризаторов эмбеддеда и вакансии украинского рынка, а на выходе получили следующий технологический стек Embedded девелопера. Математика, физика, электроника Прежде всего, эмбеддед-разработчики должны хорошо знать математику и физику – особенно темы, связанные с электротехническим направлением, чтобы хорошо понимать принципы функционирования hardware: разбираться в начинке плат, уметь правильно разводить все сигналы на плате, правильно считать все дорожки, перекрытия сигналов, их целостность и т. д. Эти знания важны как при разработке, так и на момент проектирования, тестирования, коммуникации с другими коллегами и не только. Какие разделы нужно знать: базовая математика и вычисления; дискретная математика; электрические цепи; основы электроники; цифровая и аналоговая микросхемотехника; цифровые и логические схемы; компьютерная архитектура. Тестовое оборудование Следующее оборудование вы будете широко использовать для проверки работоспособности микросхем, поиска неисправностей и прочего. Вам понадобятся следующие инструменты: мультиметр; логический анализатор; осциллограф. Мультиметр является довольно известным прибором среди “электротехнарей” – им измеряют ряд физических величин, таких как сила тока, сопротивление, напряжение и другие. Логический анализатор используется для работы с цифровыми сигналами в электронных системах, а осциллограф – для визуализации и исследования электрических сигналов, а также отображения их параметров в режиме реального времени. Микроконтроллеры Одни из главных объектов заинтересованности разработчиков Embedded. Под них и пишется код на языках C/C++ и не только. МК представляет собой небольшое электронное устройство с большим количеством "ножек", которыми отправляются/принимаются соответствующие электрические сигналы. Что важно знать по этой теме: GPIO ADC DAC Таймеры PWM Прерывания Сторожевой таймер (watchdog) Управление тактовой системой (clock management) Каждая модель МК имеет свои особенности, с которыми вам придется знакомиться через соответствующую документацию. Также вам нужно знать периферию выбранного вами микроконтроллера и библиотеки для управления ею. Самым популярным семейством МК является STM32. Опыт работы с Arduino также приветствуется. RTOS Real Time OS – операционная система настоящего времени. Предоставляет среду выполнения для программ, имеющих строгий график выполнения задач. Embedded-разработчики используют RTOS для обработки задач с высокой точностью и низкими задержками. Linux Если вы планируете работать со встроенными устройствами на базе Linux (а их сейчас очень много), вам следует знать и эту операционную систему. Она имеет открытый исходный код и является бесплатной. Примеры проектов – если говорить о них, линукс использует большое количество систем IoT, промышленный, сетевой, автомобильный, медицинский Embedded и т. д. Паяльник Да, в данной профессии необходимо иногда и паяльником поработать. Какие-то компоненты могут нуждаться в пайке – где-то удалить/добавить/заменить, поэкспериментировать с макетом, собрать проект и прочее. Может возникнуть любая ситуация на “железе”, и эмбеддед-специалист должен быть готов к этому. Основы программирования Фундамент, который сделает ваш процесс программирования эффективным. Сюда отнесём следующие темы: алгоритмы и структуры данных – эмбеддерам нужны сильные знания по алгоритмике; шаблоны проектирования – да, в эмбеддеде есть свои паттерны, облегчающие жизнь девелоперам, например Opaque Pointer pattern; UML (диаграмма состояния, state machine) – для моделирования и анализа поведения системы. Программирование на C/C++ C/C++ – это мощные мастодонты в мире программирования. По сравнению с другими языками сложнее в изучении, дают возможность писать низкоуровневый код с высокой степенью контроля “железа”. Также C/C++ позволяют напрямую управлять памятью (а это очень важно при работе с hard-элементами, имеющими достаточно ограниченный ресурс), контролировать большое количество low-level процессов, а также подходят для программирования широкого спектра “железа”. Обязательный инструмент в копилке Embedded-девелопера – можно выучить либо C, либо C++, либо оба языка. Интерфейсы и протоколы Обмен информацией между Embedded-элементами и их составляющими осуществляется через специальные интерфейсы и протоколы: UART, I2C, SPI – базовые, их нужно знать обязательно; Ethernet, USB – для работы на высоких скоростях; Bluetooth – очень известная беспроводная технология; TCP/IP, UDP – для работы с сетью; CAN – система, используемая в транспортных средствах; Modbus – для работы в промышленных объектах. Git Git – система управления версиями проекта, очень популярный инструмент при написании любого кода, поскольку позволяет отслеживать изменения в коде, создавать ветки для работы над разными функциями, делиться своим кодом с другими коллегами и наоборот. Agile/Scrum Agile – это семейство гибких методологий разработки ПО, которое способствует выпуску продукта порциями, шаг за шагом расширяя и улучшая его. Как результат – команда осуществляет разработку относительно небольшими интервалами, сам продукт постоянно улучшается, качество кода – повышается. Познакомиться с Agile вам поможет подходящий манифест с подробным описанием основных принципов. Scrum является одной из самых популярных реализаций данного подхода, часто используемого во многих IT-командах, в том числе и во время работы со встроенными устройствами. Английский язык English на уровне свободного чтения документации должен быть у каждого Embedder-а, поскольку львиная доля работы приходится именно на считывание материалов к тем или иным микроконтроллерам и сопутствующим устройствам. Если же вы будете работать в команде с иностранцами, нужно подтянуть ещё и разговорный английский. Как стать Embedded-разработчиком Где получить знания Есть несколько опций для изучения разработки встроенных устройств: Можно учиться самостоятельно с помощью бесплатных ресурсов в свободном доступе: YouTube, roadmap со ссылками на GitHub, статьи, тематические форумы, бесплатные курсы и материалы (MIT OpenCourseWare, embedded.com) и т.д. На платы Arduino, паяльник, мультиметр и т.д., конечно, придется раскошелиться. Прохождение видео курсов (платно) на Udemy, Coursera, edX, Pluralsight и других платформах, покупка специализированных книг. Менторинг со стороны действующего разработчика – самый эффективный способ обучения, поскольку у вас всегда будет помощь, наставничество, советы, четкое направление движения и необходимые учебные материалы. Прохождение онлайн/офлайн обучения при компаниях. Такой формат предлагают, например, GlobalLogic, Ajax Systems и другие. Минусы: нужна база знаний перед стартом обучения, а главный плюс – возможность стажировки и полноценного трудоустройства в компании. Высшее образование в этой специальности не помешает, хотя и не есть обязательным. Нужную базу вы можете получить в школе и высших учебных заведениях на соответствующих технических специальностях – там же есть возможность попасть на стажировку, если кафедра такое практикует или имеет соответствующие связи с компаниями. Soft skills Требования к Embedded-разработчикам могут различаться в плане стека, но что 100% понадобится каждому, это следующие “мягкие” навыки: критическое, алгоритмическое, аналитическое мышление; навыки problem-solving; коммуникативность, умение работать в команде; организованность, собранность, умение эффективно распоряжаться временем; самомотивация; внимание к деталям; терпение и адаптивность; страсть к Embedded; желание постоянно развиваться и совершенствоваться. Последние три пункта очень важны в профессии, поскольку эмбеддед – это непростая отрасль, и за 3-6 месяцев "войти в IT" не получится. Требуется больше усилий, времени и выдержки. Ключевые тренды в Embedded IT-индустрия двигается вперед, и эмбеддед не отстает. Проанализировав ряд ресурсов, мы определили следующие тренды: Интеграция искусственного интеллекта и машинного обучения в Embedded-системах становится всё более привлекательней, что способствует использованию встроенными системами интеллектуальных алгоритмов и ML. Эта синергия позволяет системам адаптироваться к изменениям в реальном времени, повышая их эффективность. Развитие беспроводных технологий открывает новые перспективы для встроенных систем, особенно в областях интернета вещей (IoT) и беспилотных систем, управляемых удалённо или с помощью AI. System-on-chip решения. Интеграция всех ключевых компонентов системы на одном чипе (SoC) продолжает набирать обороты и использоваться различными бизнесами. Их компактность в совокупности с высокой производительностью, дешевизной, энергоэффективностью и интегральными микросхемами специального назначения (ASIC), например, уже успешно применяется в гаджетах, собирающих и анализирующих различные параметры здоровья. Больше внимания безопасности. Рост количества встроенных систем, имеющих выход в Интернет, приводит к увеличению количества киберугроз, что подчеркивает важность совершенствования мер безопасности для эмбеддед-устройств. Оптимизация потребления энергии embedded-системами становится актуальнее – на это влияют идеи устойчивого развития, что способствует распространению более энергоэффективных решений. Развитие AR и VR (дополненная и виртуальная реальности). Интеграция встроенных систем в AR и VR открывает новые горизонты для интерактивных интерфейсов и развлекательных приложений. Embedded-разработчики активно работают над этими технологиями для создания поразительного опыта и визуальных эффектов. Отдельно отметим и развитие встроенных устройств в военной сфере. В настоящее время растет спрос на эмбеддеров, способных работать с дронами (воздушными и морскими), БПЛА и т. д. Сегодня именно эти роботизированные системы позволяют эффективно выявлять и ликвидировать врага, разведывать, наводить и корректировать огонь и – что самое важное – беречь жизнь и здоровье личного состава. Сегодня это одно из трендовых направлений именно в нашем государстве. Карьерные возможности в IT и заработная плата Embedded Engineer Количество вакансий Для определения этого параметра используем данные из самых известных украинских ресурсов для поиска работы в IT – DOU и Djinni – и сравним результаты по самым популярным специальностям. Начнем с DOU: Embedded – 44 вакансии; QA – 167; FrontEnd – 160; DevOps – 158; PHP – 140; Python – 138; Java – 108; .NET – 104; Node.js – 101. В Djinni поиск работы кандидатами осуществляется анонимно. Количество вакансий следующее: C / C++ / Embedded – 170 вакансий; JavaScript / FrontEnd – 354; PHP – 295; DevOps – 273; Python – 208; Node.js – 191; C#/.NET – 166; Java – 161; QA Automation – 139; QA Manual – 128. Конкуренция Для определения конкуренции эмбеддеров на нашем рынке IT воспользуемся соотношением количества отзывов к количеству вакансий на DOU за ноябрь 2023 года (берем наиболее известные специальности). Вот что имеем: Конкуренция у эмбеддеров (от новичков до профессионалов) очень низкая: на 1 вакансию приходится примерно 5 претендентов, что является хорошим результатом во время нынешней ситуации на рынке IT. Настоящие "голодные игры" традиционно у QA и FrontEnd: за 1 вакансией охотятся в среднем 120.9 и 100.5 кандидатов соответственно. Согласно рыночной статистике Djinni, для новичков конкуренция усиливается: Отметим, что здесь демонстрируется количество кандидатов на вакансию, которые сейчас находятся в "онлайне". На Джине так называются те кандидаты, которые находятся в активном поиске работы. Видим, что в категории "C / C++ / Embedded" без опыта 27.75 соискателей на вакансию (отдельной категории для Embedded нет). Много, но посмотрите на аналогичную ситуацию в более популярных направлениях: JavaScript / FrontEnd – 426.55 C#/.NET – 200.5 Python – 185.6 Manual QA – 132.83 Node.js – 98 DevOps и FullStack – 83.5 Заработная плата Сначала рассмотрим зарплатную статистику на Djinni для “C / C++ / Embedded” (за последние 6 месяцев). Картина следующая: Зарплатные вилки достаточно высоки – 2300-4700 USD. При этом зарплатные ожидания кандидатов скромнее – от 700 USD до 4500 USD. А сколько получают Embedded за пределами Украины? Обратимся к аналитике Stack Overflow Developer Survey 2023 (более 90 000 респондентов из США, Индии, Германии, Соединенного Королевства, Канады и других стран). Некоторые несущественные для нашей статьи специальности были убраны из диаграммы для большей компактности изображения. Итак, медианная зарплата Embedded-специалистов из разных стран составляет 77 104 USD в год, а это примерно 6425 USD в месяц. Что интересно, разработчики веба (FrontEnd, BackEnd, FullStack), игр, мобильных и десктопных приложений получают меньшую ЗП, хотя эти специальности более распространены, а веб вообще является самым популярным в IT. Более высокое вознаграждение получают те, кто специализируется на базах данных, DevOps-процессах, больших данных, аппаратной части, блокчейне, безопасности и т. д. Карьерные перспективы Embedded разработчик – понятие достаточно размытое и обширное, поскольку девелопер этой специализации может работать над: созданием робототехнических систем; медицинской аппаратурой; автомобильными системами; аэрокосмическими аппаратами; IoT-экосистемой; AR и VR индустрией; сетевыми системами; гаджетами для гражданских нужд; безопасностью embedded-устройств; промышленными системами; военными разработками; и т. д. В каждой из этих сфер будут свои технологические стеки, микроконтроллеры, платы, интерфейсы, протоколы и т. д. Ещё не забывайте об эмбеддерском "фронтенде", "бэкенде" и "фулстеке" - в каждой отрасли вы можете концентрироваться больше на программной части, аппаратной, или же на обоих сразу. Конечно, каждое направление может иметь собственную “кухню”, и чтобы “отведать блюдо” в каждом из этих “ресторанов” целой жизни может не хватить, но согласитесь – список для самореализации скромным не назвать. Также вы можете в любой момент углубиться в Software разработку и заниматься написанием программного кода (самые популярные стеки в Embedded – C/C++, Java, Python, Go), а можете пойти в Hardware и больше внимания уделять “железу”. Если немного подкачать знания, можно переквалифицироваться и в тестировщики, и в специалиста по безопасности, сетевого специалиста и т. д. Возможности очень широкие и разнообразные. Если же говорить о вертикальном потенциале профессии, разработчик встроенных систем стартует со стандартной Intern/Trainee/Junior позиции. Далее – с увеличением опыта, навыков и знаний – получает повышение до Middle и Senior, а выше – руководящие позиции вроде Team/Tech Lead, архитектор и т. д. Выводы Embedded – очень интересная, необычная и многогранная IT специализация. Она позволяет почувствовать себя Архитектором, вдыхающим жизнь в устройства, даёт им всё необходимое для их движения, мышления, анализа окружающей среды, общения друг с другом и не только. Да, для этого нужно иметь много знаний, но кто сказал, что быть Творцом – это так просто?) Это направление даёт очень важный фундамент для других IT-отраслей, которые сегодня в зените популярности. Благодаря встроенным системам мы можем наслаждаться множеством автоматизированных процессов, начиная утренним свежемолотым кофе и осмотром нашего сна в health-трекере, и заканчивая автомобильной и медицинской аппаратурой. Эмбеддед создан для истинных любителей “железа” и его программирования. При этом он имеет много нишевых разветвлений и ежегодно растущий спрос. Сегодня в Украине разработчики встроенных устройств имеют большие возможности для реализации, а в остальном мире – тем более. Профессия непростая, но она щедро вознаграждает смелых, терпеливых и целеустремленных, которые не боятся сложностей и препятствий, а также готовы на всё, чтобы добиться желаемого. Желаем удачи и вдохновения всем, кто стремится к развитию в направлении Embedded!
6 основных тенденций, которые будут популярны в веб-разработке в 2015 году

Автор: Редакция ITVDN

Введение  Подошел к концу 2014 год и самое время спросить себя: «Какие тенденции будут преобладать в сфере веб-разработки в 2015 году?». Представляем вашему вниманию подборку трендов, которые, по нашему мнению, будут популярны в следующем году. 1. Адаптивный дизайн Вместе с ростом популярности на планшеты начал расти спрос на адаптивный дизайн, сегодня это - неотъемлемая часть любого сайта. С помощью “Responsive Design” пользователь сможет спокойно просматривать Ваш сайт на любом девайсе, будь то PC или мобильный телефон. Зачем Вам адаптивный дизайн? Ответ простой, сейчас все больше пользователей просматривают новости через разные устройства с разным расширением экрана, поэтому выбор ресурса напрямую зависит от удобства его использования на всех носителях. Главный критерий выбора – ширина контента не должна превышать ширину экрана, иначе пользователю будет неудобно воспринимать информацию и он к вам больше не вернется.  2. Плоский дизайн (Flat Design) Плоский дизайн начал набирать свою популярность после релиза Windows 8, благодаря компании Microsoft и ее Metro-стилю. Концепция плоского дизайна заключается в том, что двухмерные изображения не перегружают восприятие пользователя и уменьшают загруженность ресурса. В плоском дизайне отсутствуют лишние эффекты: тени, блики и градиенты, в противовес им выдвигаются яркие цветовые решения. 3. Карточный дизайн Карточный дизайн — это способ подачи контента на страницах сайта. Каждая карточка содержит в себе определенную информацию, это дает ресурсу возможность концентрировать внимание пользователя и легко группировать содержимое сайта.  Главное преимущество данного типа дизайна — это легкость взаимодействия пользователя с Вашим сайтом, ведь карточки легко можно опубликовать на своей странице в социальных сетях, сохранить в избранное или прокомментировать. Первопроходцами карточного дизайна считаются  Pinterest и Google+. Благодаря своей отзывчивости и адаптивности все больше сайтов переходит на карточный дизайн. 4. Фоновые изображения и видео За последнее время все большую популярность набирают ресурсы с широкоформатным изображением  или видео на фоне,  с небольшой цитатой поверх него. Этот прием идеально подходит для сайта-портфолио или сайта-визитки. 5. Рисованные иллюстрации и шрифты Сайты с рисованной типографикой или иллюстрациями подкупают своей неповторимостью. Все больше сайтов начали использовать в своем дизайне элементы, разработанные вручную, именно под определенный проект. Эти детали делают сайт уникальным и запоминающимся, пользователю приятней пользоваться таким сайтом, он захочет рассказать о нем другу и обязательно вернется сам. 6. SVG иконки и анимации SVG — это специальный язык разметки векторной графики, который разрабатывается W3C с 1999 года. Возможность создавать SVG изображения доступна в большинстве векторных редакторов: Illustrator, Corel Draw или Sketch. SVG-графика часто используется для создания иконок, они выглядят качественней и легко адаптируются под разные расширения экрана. И напоследок, с помощью SVG можно создавать анимированные иконки.  Источник: http://www.sevensignature.com/blog/articles/top-10-sign-things-come-2015-web-design-trends/
Лучшие видео курсы, статьи и вебинары по программированию на ITVDN в 2020 г.

Автор: Редакция ITVDN

Здравствуйте, друзья! Провожая очень необычный 2020 год, который для многих стал проверкой на прочность и готовность к переменам, мы подвели итоги работы ITVDN и выбрали для вас все самое лучшее. Представляем вашему вниманию ТОП-10 видео курсов ITVDN, вебинаров и статей за 2020 год.  Лучшие курсы В 2020 году мы выпустили 21 видео курс по таким направлениям как C#/.NET, Java, FrontEnd разработка, Python, C++, мобильная разработка, UX/UI дизайн и другие. ТОП-10 лучших новых видео курсов в 2020 (по количеству просмотров): C# Стартовый от Александра Шевчука ASP.NET Core Web API. Практический курс JavaScript Starter Верстка сайта на FlexBox CSS React Essential UX/UI Design Essential Django Starter Spring MVC Решение практических задач на С++ Unit тестирование в Java с JUnit Лучшие вебинары В 2020 году мы провели 61 вебинар, в которых было много практики программирования, а также особенно популярные среди новичков вебинары по выбору специальности. Топ-10 вебинаров 2020 года по количеству просмотров и “лайков”: Как стать C# разработчиком в 2021 году. .NET или .NET Core? Как стать программистом? Frontend, Java, Python или .NET - что выбрать? Что нужно знать .NET разработчику в 2020? ➤ Как стать программистом на C# c нуля? Адаптивная верстка на Flexbox и Grid Что нужно знать FrontEnd разработчику в 2020? ➤ Пошаговая инструкция для начинающих JS больше не нужен?! Blazor - революция в веб-разработке Типичные ошибки в коде на примере С++, С# и Java Как прокачать английский для собеседования в IT-компанию Создание игры “Space Invaders” на C# с нуля Пишем пошаговую боевую систему на JavaScript с нуля. На примере игры Final Fantasy в 2D. Лучшие статьи В 2020 году мы опубликовали 19 статей, вот 10 самых читаемых из них:  Как не провалить своё IT-обучение Мифы о программировании и программистах Как стать Full-Stack разработчиком Что должен знать Python разработчик в 2020 году Как стать Android разработчиком FAQ начинающего программиста Что должен знать Java разработчик в 2020 году? Как стать разработчиком игр? С чего начинается создание сайтов? Специальность верстальщик Онлайн обучение программированию: подводные камни и советы   Открывайте для себя новые возможности с ITVDN! Будьте счастливы в Новом году!
Реализация наследования перечислений с помощью расширения для Visual Studio, которая базируется на Roslyn

Автор: Редакция ITVDN

Введение В С# программировании необходима возможность расширять простое уравнение. Например, когда нужно использовать перечисления из библиотеки dll, которые невозможно изменить в коде, но и в то же время нужно использовать дополнительные значения, которых нет в библиотеке. Решить проблему можно при помощи системы Roslyn, основанной на расширении VS для создания отдельных файлов. Данный подход похож на моделирование множественного наследования в шаблоне "Implementing Adapter Pattern" и "Imitating Multiple Inheritance" в C# с использованием системы Roslyn, основанной на VS Extension Wrapper Generator. Формулировка проблематики Обратите внимание на схему EnumDerivationSample. Она содержит негенерированный код, большая часть которого будет сгенерирована позже. Схема содержит тип перечисления BaseEnum: public enum BaseEnum {        A,        B } Также в ней присутствует тип перечисления DerivedEnum  public enum DerivedEnum {        A,        B,        C,        D,        E } В перечислении DerivedEnum перечень значений А и В такие же, как в перечислении BaseEnum. Файл DerivedEnum.cs также содержит статический класс DeriveEnumExtensions для конвертации BaseEnum в DerivedEnum и наоборот: public static class DeriveEnumExtensions {        public static BaseEnum ToBaseEnum(this DerivedEnum derivedEnum)        {              int intDerivedVal = (int)derivedEnum;              string derivedEnumTypeName = typeof(DerivedEnum).Name;              string baseEnumTypeName = typeof(BaseEnum).Name;              if (intDerivedVal > 1)              {                     throw new Exception                            (                            "Cannot convert " + derivedEnumTypeName + "." +                            derivedEnum + " value to " + baseEnumTypeName +                            " type, since its integer value " +                            intDerivedVal + " is greater than the max value 1 of " +                            baseEnumTypeName + " enumeration."                            );              }              BaseEnum baseEnum = (BaseEnum)intDerivedVal;              return baseEnum;        }        public static DerivedEnum ToDerivedEnum(this BaseEnum baseEnum)        {              int intBaseVal = (int)baseEnum;              DerivedEnum derivedEnum = (DerivedEnum)intBaseVal;              return derivedEnum;        } } Преобразование значений BaseEnum в DerivedEnum всегда проходит успешно, в то время как преобразование в обратном направлении может быть проблематичным. Например, если значение DerivedEnum больше 1 (значение BaseEnum.B – наибольшее значение в типе перечисления BaseEnum). Функция Program .Main (...) используется для тестирования функциональных характеристик: static void Main(string[] args) {        DerivedEnum derivedEnumConvertedValue = BaseEnum.A.ToDerivedEnum();        Console.WriteLine("Derived converted value is " + derivedEnumConvertedValue);        BaseEnum baseEnumConvertedValue = DerivedEnum.B.ToBaseEnum();        Console.WriteLine("Derived converted value is " + baseEnumConvertedValue);            DerivedEnum.C.ToBaseEnum(); } Будет выводиться: Derived converted value is A Base converted value is B И тогда появится такое сообщение: "Cannot convert DerivedEnum.C value to BaseEnum type, since its integer value 2 is greater than the max value 1 of BaseEnum enumeration." Использование Visual Studio Extension для формирования наследования перечислений. Установите расширение NP.DeriveEnum.vsix Visual Studio из папки VSIX, дважды кликнув на файл. Откройте схему EnumDerivationWithCodeGenerationTest. Тип ее перечислений такой же, как и в предыдущей схеме: public enum BaseEnum {        A,        B } Посмотрите на файл "DerivedEnum.cs": [DeriveEnum(typeof(BaseEnum), "DerivedEnum")] enum _DerivedEnum {        C,        D,        E } Он определяет такой тип перечисления _DerivedEnum с атрибутом: [DeriveEnum (TypeOf (BaseEnum), "DerivedEnum")]. Атрибут определяет "супер-перечисления" (BaseEnum) и названия производного перечисления ("DerivedEnum»). Обратите внимание, что поскольку частичные перечисления не поддерживаются в C#, нам придется создать новый тип перечисления, объединив значение от "супер" до "суб" перечислений. Посмотрите характеристики файла DerivedEnum.cs, его "специальные инструменты (Custom Tool)" уже содержатся в "DeriveEnumGenerator": Теперь откройте файл DerivedEnum.cs в Visual Studio, попробуйте изменить его (скажем, добавив пробел) и сохраните его. Вы увидите, что сразу будет создан файл DerivedEnum.extension.cs: Этот файл содержит тип перечисления DerivedEnum, который объединяет все поля перечислений BaseEnum и _DerivedEnum. Для начала убедитесь, что они имеют одинаковое имя и полное значение, а также имеют соответствующие поля в исходных перечислениях: public enum DerivedEnum {        A,        B,        C,        D,        E, } Расширение VS также формирует статический класс DerivedEnumExtensions, содержащий методы преобразования между суб и супер перечислениями: static public class DerivedEnumExtensions {        public static BaseEnum ToBaseEnum(this DerivedEnum fromEnum)        {              int val = ((int)(fromEnum));              string exceptionMessage = "Cannot convert DerivedEnum.{0} value to BaseEnum - there is no matching value";              if ((val > 1))              {                     throw new System.Exception(string.Format(exceptionMessage, fromEnum));              }              BaseEnum result = ((BaseEnum)(val));              return result;        }        public static DerivedEnum ToDerivedEnum(this BaseEnum fromEnum)        {              int val = ((int)(fromEnum));              DerivedEnum result = ((DerivedEnum)(val));              return result;        } } Если использовать метод Program.Main (...), как и в предыдущем образце, получим достаточно похожий результат: static void Main(string[] args) {        DerivedEnum derivedEnumConvertedValue = BaseEnum.A.ToDerivedEnum();        Console.WriteLine("Derived converted value is " + derivedEnumConvertedValue);        BaseEnum baseEnumConvertedValue = DerivedEnum.B.ToBaseEnum();        Console.WriteLine("Base converted value is " + baseEnumConvertedValue);        DerivedEnum.C.ToBaseEnum(); } Вы можете указать значение поля как в суб, так и в супер перечислениях. Генератор кода достаточно развит для того, чтобы выдавать правильный код. Например, если мы поставим значение BaseEnum.B 20: public enum BaseEnum {        A,        B = 20 } И _DerivedEnum.C – 22: enum _DerivedEnum {        C = 22,        D,        E } Получим такой генерируемый код: public enum DerivedEnum {        A,        B = 20,        C = 22,        D,        E, } Метод расширения ToBaseEnum(...) также будет обновляться так, чтобы показывать исключение только тогда, когда мы пытаемся увеличить целое значение области DerivedEnum до 20: public static BaseEnum ToBaseEnum(this DerivedEnum fromEnum) {        int val = ((int)(fromEnum));        string exceptionMessage = "Cannot convert DerivedEnum.{0} value to BaseEnum - there is no matching value";        if ((val > 20))        {              throw new System.Exception(string.Format(exceptionMessage, fromEnum));        }        BaseEnum result = ((BaseEnum)(val));        return result; } Обратите внимание, что изменив значение первого поля суб-перечисления на меньшее или равное последнему полю супер-перечисления, генерация кода не осуществится, и это состояние будет отображаться, как ошибка. Например, попробуйте изменить значение _DerivedEnum.C на 20 и сохранить изменения. Файл DerivedEnum.extension.cs  будет отображаться в списке ошибок. Примечания о введении генератора объектного кода. Код ввода кода генерирования содержится в схеме NP.DeriveEnum. Основная схема NP.DeriveEnum была создана с помощью шаблона "Visual Studio Package" (также, как это было сделано при Implementing Adapter Pattern и Imitating Multiple Inheritance в C# с использованием системы Roslyn, основанной на VS Extension Wrapper Generator). Нам пришлось добавить пакеты Roslyn и MEF2, чтобы использовать функции Roslyn при таких командах, как "Nu Get Package Manager Console": Install - Package Microsoft.CodeAnalysis - Pre Install - Package Microsoft.Composition Класс main генератора называется DeriveEnumGenerator. Он вводит интерфейс IVsSingleFileGenerator. У интерфейса есть два метода - DefaultExtension(...) и Generate(...). Метод DefaultExtension(...) позволяет разработчику указать расширение генерируемого файла: public int DefaultExtension(out string pbstrDefaultExtension) {        pbstrDefaultExtension = ".extension.cs";        return VSConstants.S_OK; } Метод Generate(...) позволяет разработчику указать код, который входит в состав созданного файла:  public int Generate ( string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress ) {        byte[] codeBytes = null;        try        {               codeBytes = GenerateCodeBytes(wszInputFilePath, bstrInputFileContents, wszDefaultNamespace);        }        catch (Exception e)        {              pGenerateProgress.GeneratorError(0, 0, e.Message, 0, 0);              pcbOutput = 0;              return VSConstants.E_FAIL;        }        int outputLength = codeBytes.Length;        rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(outputLength);        Marshal.Copy(codeBytes, 0, rgbOutputFileContents[0], outputLength);        pcbOutput = (uint)outputLength;        return VSConstants.S_OK; } В данном случае генерация кода получена за счет метода GenerateCodeBytes (...).  protected byte[] GenerateCodeBytes(string filePath, string inputFileContent, string namespaceName) {        string generatedCode = "";        DocumentId docId =              TheWorkspace              .CurrentSolution              .GetDocumentIdsWithFilePath(filePath).FirstOrDefault();        if (docId == null)              goto returnLabel;        Project project = TheWorkspace.CurrentSolution.GetProject(docId.ProjectId);        if (project == null)              goto returnLabel;        Compilation compilation = project.GetCompilationAsync().Result;        if (compilation == null)              goto returnLabel;        Document doc = project.GetDocument(docId);        if (doc == null)              goto returnLabel;        SyntaxTree docSyntaxTree = doc.GetSyntaxTreeAsync().Result;        if (docSyntaxTree == null)              goto returnLabel;        SemanticModel semanticModel = compilation.GetSemanticModel(docSyntaxTree);        if (semanticModel == null)              goto returnLabel;        EnumDeclarationSyntax enumNode =              docSyntaxTree.GetRoot()              .DescendantNodes()              .Where((node) = > (node.CSharpKind() == SyntaxKind.EnumDeclaration)).FirstOrDefault() as EnumDeclarationSyntax;        if (enumNode == null)              goto returnLabel;        INamedTypeSymbol enumSymbol = semanticModel.GetDeclaredSymbol(enumNode) as INamedTypeSymbol;        if (enumSymbol == null)              goto returnLabel;        generatedCode = enumSymbol.CreateEnumExtensionCode(); returnLabel:        byte[] bytes = Encoding.UTF8.GetBytes(generatedCode);        return bytes; } Метод Generate (...) имеет доступ к C # в качестве одного из параметров. Мы используем такой способ, чтобы получить Id документа в системе Roslyn: DocumentId docId = TheWorkspace .CurrentSolution .GetDocumentIdsWithFilePath(filePath).FirstOrDefault(); Из документа Id можно получить идентификатор схемы, используя dockId. Из схемы Id получаем Roslyn Project от Rosly Workspace: Project project = TheWorkspace.CurrentSolution.GetProject(docId.ProjectId); Из Project получаем следующее: Compilation compilation = project.GetCompilationAsync().Result; Также получаем Roslyn Document: Document doc = project.GetDocument(docId); С данного документа получаем Roslyn SyntaxTree: SyntaxTree docSyntaxTree = doc.GetSyntaxTreeAsync().Result; С компиляции Roslyn и SyntaxTree образовывается семантическая модель: SemanticModel semanticModel = compilation.GetSemanticModel(docSyntaxTree); Вы также получите синтаксис перечисления в файле SyntaxTree: EnumDeclarationSyntax enumNode = docSyntaxTree.GetRoot() .DescendantNodes() .Where((node) = > (node.CSharpKind() == SyntaxKind.EnumDeclaration)).FirstOrDefault() as EnumDeclarationSyntax; Наконец, из SemanticModel и EnumerationDeclarationSyntax Вы можете вытянуть INamedTypeSymbol, соответствующий перечислению: INamedTypeSymbol enumSymbol = semanticModel.GetDeclaredSymbol(enumNode) as INamedTypeSymbol; INamedTypeSymbol очень похож на System.Reflection.Type. Практически всю информацию про тип С# можно получить от объекта INamedTypeSymbol. Метод расширения DOMCodeGenerator. CreateEnumExtensionCode() генерирует и возвращает весь код. generatedCode = enumSymbol.CreateEnumExtensionCode(); Другая часть кода, отвечающая за код генерации, входит в состав NP.DOMGenerator. Система Roslyn используется только для анализа, для генерации кода используется CodeDOM, так как он меньше по объему и удобнее. Есть два основных статических класса в программе NP.DOMGenerator: RoslynExtensions - для анализа Roslyn и DOMCodeGenerator - для генерирования кода, используя функции CodeDOM. Источник: http://www.codeproject.com/Articles/879129/Implementing-Enumeration-Inheritance-using-Roslyn
Что нового в Angular 4?

Автор: Редакция ITVDN

Что нового в Angular 4? Наконец, когда обновленная технология предстала перед нами, мы можем приступить к ее изучению! То, что новый представитель семейства Angular приобрел новый номер, свидетельствует об инновационных изменениях. Но все же встает вопрос: почему Angular 4, а не 3? Все достаточно просто: так как пакет маршрутизатора был уже представлен в версии 3.x, вместо того, чтобы вносить все нововведения в версию 3.0, а маршрутизатор перенести в 4.0, разработчик решил объединить все в версии 4.0. Не стоит волноваться касательно обновления Ваших приложений к новой версии Angular: так как тех самых инновационных изменений в принципе оказалось не слишком много, процесс установки не занял больше нескольких минут. Ничего особо страшного. Среди дополнительных требований стоит упомянуть версию TypeScript 2.1 или выше (раньше требовалась только 1.8+). К тому же некоторые элементы интерфейса были изменены или вовсе упрощены (редко используемые OpaqueTolen или SimpleChange). Плюс, TypeScript 2.1 и 2.2 приобрел целый ряд прекрасных особенностей, которые теперь поддерживаются в Angular 4. К примеру, в скором времени Вы сможете использовать TypeScript-опцию stringNullChecks. Итак, что именно позволяет нам новая версия Angular? Давайте углубимся!   Ahead of Time (AoT) компиляция: обновленный движок представлений Пожалуй, это наиболее значимое изменение, пусть даже Вы, как разработчик, не ощутите разницы. Как Вы, наверно, знаете, в режиме AoT Angular компилирует Ваши шаблоны во время сборки, после чего генерирует JavaScript код (в отличие от режима Just in Time, когда компиляция происходит во время выполнения приложения). Режим AoT обладает целым рядом преимуществ, например, в случае неправильного построения шаблона ошибка возникнет во время сборки, а не во время работы приложения, как раньше. Эта методика позволяет ускорить запуск приложения, так как генерация JS-кода уже произведена. Также Вам не нужно отправлять Angular-компиляторы пользователям, что в теории должно уменьшить размер пакетов. Почему в теории? Потому что, как правило, обратная сторона медали в том, что сгенерированный JavaScript-код обычно больше, чем нескомпилированные HTML-шаблоны. Таким образом, в большинстве приложений с использованием AoT размер пакета де-факто увеличивается. Разработчики Angular хорошо поработали над новым движком представлений, что позволило производить меньше кода при использовании Ahead of Time компиляции. Эффект на больших приложениях не заставил себя ждать. Без падений производительности. Ежели говорить в цифрах, размер пакета стал: С 499 КБ до 187 КБ (или с 68 КБ до 34 КБ после gzip) С 192 КБ до 82 КБ (или с 27 КБ до 16 КБ после gzip) Достаточно большая разница! Интересно отметить, что в своих дизайн-документах команда Angular сравнивает производительность (как в контексте времени выполнения, так и в контексте нагрузки на память) с базовой имплементацией (лучшим «дефолтным» кодом JS, который они только могут написать) Angular 2.x и InfernoJS (быстрая React-подобная имплементация). Универсальность Масса работы была проделана над универсальным проектом, позволяющим производить серверный рендеринг. Когда раньше этот тип проекта поддерживался в основном силами сообщества, теперь, начиная с Angular 4, поддержка приобрела официальный характер. Анимации Анимации теперь обзавелись собственным пакетом @angular/platform-browser/animations (одна из вещей, которая может быть изменена в процессе обновления). Что это значит? Это значит, что Вам больше не нужно нагружать пакеты ненужным кодом, если вы не используете анимации. Шаблоны ng-template вместо template Тэг template устарел. Вместо него используйте ng-template. Хотя и первый вариант все еще работает. Вообще, было немного странно использовать template, так как это реально существующий HTML-тэг. Теперь же Angular обзавелась собственным ng-template. В случае, если вы используете устаревший template, будет выдано соответствующее предупреждение: это в значительной мере упростит обнаружение подобного кода в проектах. Else С новой версией Angular 4 появилась возможность использовать оператор else: <div *ngIf="races.length > 0; else empty"><h2>Races</h2></div> <ng-template #empty><h2>No races.</h2></ng-template> As Еще одно синтаксическое нововведение. Ключевое слово as позволяет упростить синтаксис let. As позволяет хранить результат переменной шаблона для дальнейшего использование в элементе. К примеру, сия особенность может быть достаточно полезной для хранения коллекции: <div *ngFor="let pony of ponies | slice:0:2 as total; index as i">   {{i+1}}/{{total.length}}: {{pony.name}} </div> Или даже более полезной, если один раз использовать pipe с async. Вместо плохого и некрасивого: <div>   <h2>{{ (race | async)?.name }}</h2>   <small>{{ (race | async)?.date }}</small> </div> Вы можете использовать: <div *ngIf="race | async as raceModel">   <h2>{{ raceModel.name }}</h2>   <small>{{ raceModel.date }}</small> </div> Различные виды pipe Titlecase Angular 4 презентует новый pipe: titlecase. Он позволяет переводить первую букву каждого слова в верхний регистр: <p>{{ 'ninja squad' | titlecase }}</p> <!-- will display 'Ninja Squad' --> Http Задание параметров поиска Http-запроса было упрощено: http.get(`${baseUrl}/api/races`, { params: { sort: 'ascending' } }); Раньше вам необходимо было произвести следующее: const params= new URLSearchParams(); params.append('sort', 'ascending'); http.get(`${baseUrl}/api/races`, { search: params }); Test Переопределение шаблона во время теста также было упрощено: TestBed.overrideTemplate(RaceComponent, '<h2>{{race.name}}</h2>'); До этого мы обычно писали так: TestBed.overrideComponent(RaceComponent, {   set: { template: '<h2>{{race.name}}</h2>' } }); Сервисы Meta Для получения содержимого или обновления meta-тэгов был введен новый сервис: @Component({   selector: 'ponyracer-app',   template: `<h1>PonyRacer</h1>` }) export class PonyRacerAppComponent { constructor(meta: Meta) {     meta.addTag({ name: 'author', content: 'Ninja Squad' });   } } Формы Валидаторы Новый валидатор позволит объединить существующие required, minLength, maxLength, и pattern. email позволит провести валидацию e-mail адреса (если Вы планируете просто обойтись подходящими регулярными выражениями – удачи в поисках). Сравнение выбранных опций Для сравнения выбранных опций была добавлена новая директива: compareWith: <select [compareWith]="byId" [(ngModel)]="selectedPony">    <option *ngFor="let pony of race.ponies" [ngValue]="pony">{{pony.name}}</option> </select> byId(p1: PonyModel, p2: PonyModel) {    return p1.id === p2.id; } Маршрутизатор ParamMap Для представления параметров URL был введен новый интерфейс: ParamMap. Вместо использования params или queryParams, отныне Вам стоит использовать paramMap или queryParamMap, так как они позволяют выбрать между get() для получения значения или getAll() для получения всех значений (так как параметры запросов могут иметь несколько значений, к примеру). const id = this.route.snapshot.paramMap.get('ponyId'); this.ponyService.get(id).subscribe(pony => this.pony = pony); Или как здесь:   .map((params: ParamMap) => params.get('ponyId'))   .switchMap(id => this.ponyService.get(id))   .subscribe(pony => this.pony = pony); CanDeactivate Интерфейс CanDeactivate теперь обзавелся дополнительным опциональным параметром, содержащим следующее состояние (то, куда Вы собираетесь перейти). Теперь можно реализовать «умную логику», когда пользователь может покинуть текущий компонент в зависимости от того, куда он или она направляется. I18n Интернационализация также медленно, но верно улучшается. К примеру, ngPlural теперь упрощен: <div [ngPlural]="value">   <ng-template ngPluralCase="0">there is nothing</ng-template>   <ng-template ngPluralCase="1">there is one</ng-template> </div> А теперь давайте сравним с тем, что было раньше: <div [ngPlural]="value">   <ng-template ngPluralCase="=0">there is nothing</ng-template>   <ng-template ngPluralCase="=1">there is one</ng-template> </div> Только что мы добавили целую главу к нашей электронной книге, включая несколько юз-кейсов и прочее! Подведем итоги Релиз Angular 4 привносит множество улучшений и действительно востребованных инноваций в сферы размера генерируемого кода, сохраняя в целом концепцию предыдущей версии Angular. Благодаря этому обновление технологии не должно вызвать затруднений. Автор перевода: Евгений Лукашук Оригинал статьи
C# против Java: какой язык программирования общего назначения выбрать?

Автор: Yoshitaka Shiotsu

Что такое C#? Что такое Java? C# vs. Java: основные сходства. C# vs. Java: основные различия. Когда стоит использовать C# или Java? C# vs Java – какой из общецелевых, объектно-ориентированных языков программирования лучше всего подойдет вам для работы? Они оба имеют обширные библиотеки, которые можно использовать для создания приложений для ПК, веб, мобильных устройств и других платформ. У обоих есть большие сообщества восторженных поклонников и много онлайн-поддержки. Имея так много общего, выбор правильного языка требует более тонкого, тщательного подхода. Давайте подробнее рассмотрим сходства и различия между C# и Java. Что такое C#?   C# – это язык программирования общего назначения, который впервые появился в 2000 году в рамках инициативы Microsoft .NET. Он был разработан для общей языковой инфраструктуры (CLI) – открытой спецификации, разработанной Microsoft и стандартизированной ISO и ECMA. Приложения C# скомпилированы в байт-код, который может запускаться при реализации CLI.   Что такое JAVA?   Java, первоначально выпущенный Sun Microsystems в 1995 году, является языком программирования общего назначения, который был разработан с конкретной целью, позволяющей разработчикам “write once, run anywhere”, то есть написать код единожды и запускать в любом месте. Java-приложения скомпилированы в байт-код, который может запускаться при реализации виртуальной машины Java (JVM). Подобно CLI, JVM помогает преодолеть разрыв между исходным кодом и 1 и 0, которые понимает компьютер. C# VS. JAVA: ОСНОВНЫЕ СХОДСТВА  Появление как Java, так и C#, тесно связано с переходом от низкоуровневых языков программирования, таких как языки программирования C++, к языкам более высокого уровня, которые компилируются в байт-код. Байт-код можно запустить на виртуальной машине. С этим связан ряд преимуществ, в первую очередь, возможность написания кода, который будет понятен человеку и будет работать на любой аппаратной архитектуре, на которой установлена виртуальная машина. Если отбросить синтаксические причуды в сторону, то неудивительно, что эти два подобные между собой языка так популярны для разработчиков приложений. Вот несколько основных сходств между C# и Java: Безопасность типов. Ошибка типа возникает, когда тип данных одного объекта ошибочно назначается другому объекту, создавая непреднамеренные побочные эффекты. И C#, и Java работают на то, чтобы гарантировать выявление таких типов незаконных приведений во время компиляции. Если приведение не может быть применено к новому типу, тогда во время выполнения такие исключения будут удалены. Сборка мусора: На языках более низкого уровня управление памятью может быть утомительным, ведь нужно помнить о том, что необходимо правильно удалить новые объекты, чтобы освободить ресурсы. На С# и Java есть встроенная сборка мусора, которая помогает предотвратить утечку памяти путем удаления объектов, которые больше не используются приложением. Утечки памяти все еще могут возникать, но благодаря основам управления памятью -  это уже не ваша проблема. Одиночное наследование. Оба языка поддерживают одиночное наследование – это означает, что существует только один путь из любого базового класса в любой из его производных классов. Это ограничивает непреднамеренные побочные эффекты, которые могут возникать при наличии нескольких путей между несколькими базовыми классами и производными классами. Diamond pattern – книжный пример этой проблемы. Интерфейсы. Интерфейс представляет собой абстрактный класс, где все методы абстрактны. Абстрактным методом является тот метод, который объявлен, но не содержит подробностей его реализации. Код, определяющий любые методы или свойства, определенные интерфейсом, должен предоставляться классом, который его реализует. Это помогает избежать двусмысленности паттерна diamond, поскольку всегда ясно, какой базовый класс реализует данный производный класс во время выполнения. Результатом является чистая иерархия линейных классов одиночного наследования в сочетании с некоторой универсальностью множественного наследования. Фактически использование абстрактных классов является одним из способов множественного наследования языков, которые могут преодолеть проблему паттерна diamond. C# VS. JAVA: ОСНОВНЫЕ РАЗЛИЧИЯ Важно помнить, что C# берет свое начало в желании Microsoft иметь собственный «Java-подобный» язык для платформы .NET. Поскольку C# не создавался в вакууме, новые функции были добавлены и настроены для решения проблем, с которыми сталкивались разработчики Microsoft, когда они изначально пытались создать свою платформу на Visual J++. В то же время сообщество Java с открытым исходным кодом продолжало расти и между этими двумя языками развивалась гонка технических вооружений. Вот некоторые из основных различий между C# и Java. Windows vs open-source. Хотя существуют реализации с открытым исходным кодом, C# в основном используется в разработке для платформ Microsoft – .NET Framework CLR и является наиболее широко используемой реализацией CLI. На другом конце спектра Java имеет огромную экосистему с открытым исходным кодом и у него открылось второе дыхание отчасти благодаря тому, что Google использует JVM для Android. Поддержка обобщений (Generics): Generics улучшает проверку типов с помощью компилятора, в основном удаляя приведения из исходного кода. В Java средства обобщений реализуются с использованием стираний. Параметры общего типа «стираются», а при компиляции в байт-код добавляются приведения. C# также использует обобщения, интегрируя его в CLI и предоставляя информацию о типе во время выполнения, что дает небольшое увеличение производительности. Поддержка делегатов (указателей): В C# есть делегаты, которые по существу служат в качестве методов, которые могут быть вызваны без знания целевого объекта. Для достижения такой же функциональности в Java вам необходимо использовать интерфейс с одним методом или другим способом обхода, который может потребовать нетривиального количества дополнительного кода, в зависимости от приложения. Проверяемые исключения: Java различает два типа исключений – проверяемые и непроверяемые. C# выбрал более минималистский подход, имея только один тип исключения. Хотя способность ловить исключения может быть полезна, она также может отрицательно влиять на масштабируемость и контроль версий. Полиморфизм: C# и Java используют очень разные подходы к полиморфизму. Java допускает полиморфизм по умолчанию, C# же должен вызывать ключевое слово «virtual» в базовом классе и ключевое слово «override» в производном классе. Перечисления (Enums): в C# перечисления представляют собой простые списки именованных констант, где базовый тип должен быть целым. Java представляет перечисления более глубоко, рассматривая его как именованный экземпляр типа, что упрощает добавление пользовательского поведения к отдельным перечислениям. Когда стоит использовать C# или Java? Язык, который вы в конечном итоге решите использовать, будет во многом зависеть от платформы, которую вы выбрали для своего проекта. Сегодня C# используется в основном для реализации CLI на .NET Framework, Mono и Portable.NET. Если ваше программное обеспечение или веб-приложение создаются для Windows, C# будет работать лучше всего с набором технологий .NET. Тем не менее, если вы хотите разрабатывать для Unix, Linux или других платформ за пределами платформы Microsoft, экосистема с открытым исходным кодом – Java – лучший выбор. Сообщество постоянно создает новые библиотеки и инструменты. Появились новые мощные языки, такие как Scala, Clojure и Groovy, и они все тоже основаны на JVM. К тому же это неплохо, что большинство реализаций JVM являются общедоступными и бесплатными. Java – основной язык разработки, который использует Google для Android – самой большой мобильной операционной системы в мире в настоящее время. Имейте в виду, что перечисленные выше преимущества незначительны, и ни один из языков не исчезнет в ближайшее время. Оба языка существуют достаточно долго и, на самом деле, вы не сможете ничего такого построить на одном языке, чего бы  не смогли построить на другом. Итог: выберите язык, который лучше всего подходит для платформы вашего проекта. Источник: https://www.upwork.com/hiring/development/c-vs-java/
Notification success