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

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

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

Підписка
Підписка

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

Результати пошуку за запитом: mvc 5
Читабельність програмного коду

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

Введение Вам приходилось возвращаться к фрагменту кода, написанному год или месяц назад? Каково это было?  Это было просто, или приходилось вникать в код исходя из заметок? Если у Вас не получается быстро разобраться в коде и Вы задаете себе вопрос: «Что же я тогда имел ввиду?» – Вы определенно делаете что-то не так. Скорее всего, Ваш код работает правильно. И Вы знали его вдоль и поперек, когда над ним работали. Почему же Вы не можете его вспомнить сейчас? Быть может, он не был написан достаточно доступно и не соответствовал стандартам машинного кода? В этой статье Вы найдете полезную информацию о том, как научиться писать доступный не только для себя, но и для остальных разработчиков код. Пример использования стандарта оформления кода Рассмотрим это на следующем примере метода в C#: public string Transform(List<DateTime> s)         {             string d = null;             foreach (DateTime kc in s)             {                 if (kc > DateTime.Now)                 {                     d = d + kc + "\n";                 }                 else                 {                     d = d + "Delayed\n";                 }             }             return d;         } Скорее всего, Вы не можете понять, какую функцию он выполняет и как его можно использовать. Но после короткой реконструкции кода мы получим:  public string GetText(List<DateTime> arrivalTimes)         {             var stringBuilder = new StringBuilder();             foreach (DateTime arrivalTime in arrivalTimes)             {                 if (arrivalTime > DateTime.Now)                 {                     stringBuilder.AppendLine(arrivalTime.ToString());                 }                 else                 {                     stringBuilder.AppendLine("Delayed");                 }             }             return stringBuilder.ToString();         } Или если мы обратимся к оператору “?:”, мы получим:  public string GetText(List<DateTime> arrivalTimes)         {             var stringBuilder = new StringBuilder();             foreach (DateTime arrivalTime in arrivalTimes)             {                 string message = arrivalTime > DateTime.Now ? arrivalTime.ToString() : "Delayed";                 stringBuilder.AppendLine(message);             }             return stringBuilder.ToString();         } Что произошло с кодом? Некоторые изменения сделали наш код более читабельным: 1. Имя метода получило более понятное название. 2. Мы изменили названия переменных: 1. “kc” изменена на arrivalTime, 2. “s” изменена на arrivalTimes, 3. “d” изменена на stringBuilder, Это облегчит понимание того, за что отвечает каждая переменная и как она используется. 3. Скобки были стандартизированы. 4. Добавлены вкладки для читаемости, размещения и разметки в скобках. 5. Оператор “?:” был введен для того, чтобы сократить наш код до четырех строчек. 6. Добавлен класс StringBuilder, чтобы избежать конкатенации (“string” + “string”). Кто-то может возразить, что создание экземпляра StringBuilder будет замедлять метод из-за его распределения памяти. Но стоит помнить, что конкатенация струн создает много мусора в памяти, который вынужден чистить Garbage Collector. Считается, что ~ 5 непрерывных строк равны созданию реализации StringBuilder, так что если список состоит из пяти или более элементов, то производительность этого метода будет увеличена. А для больших коллекций этот метод будет работать в несколько раз быстрее. Правильный способ составления кода Давайте перейдем к другому примеру. Рассмотрим класс пользователя: public class User         {             public bool HasConfirmedEmail { get; set; }             public bool HasActiveAccount { get; set; }             public bool IsLoggedIn { get; set; }             public bool HasPremiumAccount { get; set; }             public bool StatusAutoGenerated { get; set; }             public DateTime LastStatusChange { get; set; }             public bool SetStatus(string status)             {                 // write to Data Base                 return true;             }         }  Метод, отвечающий за обновление статуса пользователя, который должен проверить, все ли свойства в правильном состоянии: public string UpdateStatus(string status, User user)         {             if (user.HasActiveAccount)             {                 if (user.HasConfirmedEmail)                 {                     if (user.IsLoggedIn)                     {                         if (user.HasPremiumAccount)                         {                             if (!user.StatusAutoGenerated)                             {                                 if (user.LastStatusChange < DateTime.Now.AddDays(-1))                                 {                                     if (user.SetStatus(status))                                     {                                         return "Updated";                                     }                                 }                             }                         }                     }                 }             }             return "Fail";         } Хотя этот код более понятный, чем первый, представленный в этой статье, он все еще не соответствует стандартам программного кода. Вот пример того, как этот код можно сделать немного лучше: const string OK = "Updated";         const string FAIL = "Fail";         public string UpdateStatus(string status, User user)         {             if (!CanUpdateStatus(user)) return FAIL;             if (!user.SetStatus(status)) return FAIL;             return OK;         }         public static bool CanUpdateStatus(User user)         {             if (!user.IsLoggedIn) return false;             if (!user.HasActiveAccount) return false;             if (!user.HasConfirmedEmail) return false;             if (!user.HasPremiumAccount) return false;             if (user.StatusAutoGenerated) return false;             if (!(user.LastStatusChange < DateTime.Now.AddDays(-1))) return false;             return true;         } Основные изменения, внесенные в этот код, чтобы улучшить его читабельность: Static method был создан, чтобы проверить возможность обновления статуса пользователя. Это делает метод UpdateStatus более понятным с первого взгляда. Кроме того, логика метода CanUpdateStatus может быть повторно использована в других частях системы, если они являются public и static. Все " if " были заменены, чтобы уменьшить вложения. Количество скобок значительно уменьшилось, и код гораздо легче читать и компилировать. Еще одним преимуществом данного условия является его масштабируемость. Представьте себе, что класс User имеет теперь еще три свойства, которые должны быть проверены перед обновлением статуса – будут необходимы еще три "if" выписки. Теперь Вы можете добавить только три (не более) линии в методе CanUpdatedStatus. Строки, которые представляют сообщения, были удалены из тела методов и были введены в постоянные переменные. Это помогает поддерживать код, потому что независимо от числа использований кода есть только одно место, где Вы должны изменить содержание сообщения, если это необходимо. Но, на самом деле, все тексты должны быть помещены в проект внешних ресурсов. Источник: http://blog.goyello.com/2014/12/11/clean-code/ 
Навички, які визначили кар’єру у 2025 і задають напрям на 2026

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

Кінець 2025 року — вдалий момент, щоб не будувати припущення, а спиратися на факти та дані. Які навички справді мали найбільший вплив на кар’єрний розвиток протягом року? У що фахівці вкладали час і гроші, навчаючись? І головне — які висновки з цього варто зробити для планування кар’єри у 2026 році? У статті використано два незалежні міжнародні дослідження: World Economic Forum — Future of Jobs Report 2025 Coursera — Global Skills Report 2025 Обидва звіти дають цілісне розуміння того, які навички були найбільш значущими у 2025 році та які з них зберігають стратегічну цінність на 2026 рік. 1. Які навички були ключовими у 2025 році: погляд роботодавців Дані World Economic Forum (WEF) У звіті Future of Jobs Report 2025 Всесвітній економічний форум проаналізував відповіді понад 1 000 роботодавців у всьому світі, які представляють компанії з мільйонами працівників. 🔝 Топ-10 навичок, що найбільше впливали на кар’єру у 2025 році: Аналітичне мислення Стійкість, гнучкість та адаптивність Лідерство та соціальний вплив Креативне мислення Самомотивація та усвідомленість Технологічна грамотність Емпатія та активне слухання Допитливість і безперервне навчання Управління талантами Клієнтоорієнтованість і сервісне мислення 📌 Ключовий висновок WEF: У 2025 році кар’єрне зростання визначалося не окремими технічними знаннями, а поєднанням мислення, soft skills і здатності ефективно працювати з технологіями. 2. Які технічні навички реально опановували фахівці у 2025 році Дані Coursera Global Skills Report 2025 Звіт Coursera базується не на прогнозах, а на реальній поведінці користувачів платформи: понад 170 млн людей у всьому світі тисячі курсів і професійних програм аналітика попиту з боку бізнесу Це дозволяє побачити, які технічні навички мали практичну цінність у 2025 році і логічно стають орієнтиром для навчальних планів у 2026-му. 3. Найбільш затребувані технічні навички за підсумками 2025 року (Coursera) 1. Навички у сфері штучного інтелекту (AI) Штучний інтелект став беззаперечним лідером за інтересом і попитом протягом 2025 року. Найпопулярніші напрями: Generative AI Machine Learning Prompt Engineering Використання AI в бізнесі, аналітиці, маркетингу, управлінні Важливий зсув 2025 року: Цінується не лише розробка AI-рішень, а й уміння інтегрувати AI у щоденні робочі процеси. 2. Data & Analytics Аналітика даних зберегла позиції однієї з найстабільніших кар’єрних зон. Ключові навички: Data Analysis SQL Python для аналізу даних Візуалізація даних (Tableau, Power BI) Ролі, що активно розвивалися у 2025 році: Data Analyst Business Analyst Product Analyst 3. Хмарні технології (Cloud) Хмарна інфраструктура остаточно стала стандартом для бізнесу. Найбільш затребувані платформи: AWS Microsoft Azure Google Cloud Platform (GCP) 4. Кібербезпека Зростання цифрових сервісів у 2025 році посилило попит на фахівців із захисту даних. Ключові напрями: Основи кібербезпеки Cloud Security Risk & Compliance Network Security 5. Розробка програмного забезпечення (прикладні навички) Ринок дедалі більше цінував інженерне мислення, а не знання окремого інструменту. Актуальні технології 2025 року: Python JavaScript Backend-розробка API та інтеграції Базові DevOps-практики 4. Професійні сертифікації, що показали найбільшу цінність Окремий важливий висновок Coursera — зростання довіри роботодавців до професійних сертифікацій. Сертифікації, які були найбільш затребуваними у 2025 році: Google Professional Certificates (Data Analytics, Project Management, Cybersecurity, UX) IBM Professional Certificates (AI, Data Science, Backend Development) Microsoft Certifications (Azure, Data, AI Fundamentals) AWS Certifications (Cloud Practitioner, Solutions Architect — Associate) Meta Certificates (Frontend, Backend, Marketing Analytics) Тренд 2025 року: Для junior- і middle-фахівців сертифікації дедалі частіше сприймаються як альтернатива класичній освіті. 5. Що означають підсумки 2025 року для планування 2026 🔹 Фокус кар’єрного розвитку у 2026 році логічно будувати на трьох групах навичок: Мислення, адаптивність і стійкість Комунікація, емпатія та лідерство Практичні технічні навички + підтверджені сертифікації 🔹 AI та робота з даними перестали бути нішевими компетенціями й стають базовими для широкого кола професій, зокрема й non-tech ролей. 🔹 Безперервне навчання закріпилося як норма ринку, а не тимчасовий тренд. Джерела World Economic Forum — Future of Jobs Report 2025 https://www.weforum.org/publications/the-future-of-jobs-report-2025/ Coursera — Global Skills Report 2025 https://www.coursera.org/skills-reports/global
Як вибрати свою першу мову програмування: інструкція від HR

Автор: Вікторія Чабан

Якщо ти плануєш увійти в ІТ і не знаєш, з чого почати — ця стаття для тебе. Вибір першої мови програмування схожий на вибір першого велосипеда: важливо, щоб підходив саме тобі, а не був «наймоднішим». У ролі кар'єрного консультанта та HR я спираюсь на реальні кейси студентів і запити компаній. Ось чіткий та короткий план, який допоможе обрати першу мову грамотно. 🎯 Крок 1. Визнач свою цільову сферу Запитай себе: що саме я хочу створювати? Це головний орієнтир. 🧑‍💻 FrontEnd (веб-сайти, інтерфейси) → JavaScript, далі можна додати TypeScript, React 📱 Мобільні додатки → Kotlin (Android), Swift (iOS), або React Native 📊 Аналітика, машинне навчання, ШІ → Python 🏦 Корпоративні рішення, банківські системи → C# / .NET або Java 🧪 QA Automation (автотести) → Python, Java, JavaScript 💡 Порада: якщо не визначився — обирай універсальну мову для старту, наприклад, Python або JavaScript. 📊 Крок 2. Перевір актуальність на ринку За даними DOU та Djinni (станом на 2025 рік), топ-5 мов за кількістю вакансій: JavaScript / TypeScript Python C# Java PHP JavaScript домінує завдяки своїй універсальності (веб, мобайл, backend).  Python — лідер у сфері ШІ, автоматизації та наукових обчислень.  C# / .NET — улюблене рішення для бізнесу в Україні та Східній Європі.  Java — база для багатьох міжнародних проєктів, особливо у банках та ентерпрайз-продуктах. 🔍 Працювати з мовою, яка має стабільний попит — логічний крок для першої роботи. 👶 Крок 3. Почни з доступної до навчання Навіть найкрутіша мова нічого не дасть, якщо ти не зможеш її зрозуміти. Ось три мови, які найкраще підходять для старту: Python — простий синтаксис, читається як англійська, популярний у всіх сферах. JavaScript — швидкий результат (можна написати код і одразу побачити на екрані). C# — добре структурований, допомагає швидко зрозуміти основи ООП. 🧠 Якщо тебе лякає синтаксис або ти сумніваєшся — подивись безкоштовний вступний курс. На ITVDN є 3 безкоштовних уроки, які допомагають обрати напрям без ризику. 🔮 Крок 4. Дивись на перспективу Програміст не вчить лише одну мову на все життя. Але перша створює базу. Після неї буде легше вивчити інші. Якщо мрієш стати FullStack-розробником — комбінуй JavaScript (FrontEnd) + Node.js або C# (BackEnd). Хочеш піти в Data Science — починай з Python, а далі додай бібліотеки як Pandas, NumPy, TensorFlow. 💡 Висновок Не існує «ідеальної» мови для всіх. Вибір має бути практичним:  ✅ під твої задачі  ✅ з урахуванням попиту  ✅ з урахуванням складності на старті 🎓 Обирай шлях, який не лише приведе до першої роботи, а й зробить навчання цікавим. І пам’ятай: важлива не мова, а твоє бажання вчитися!
CSS vs JavaScript: руйнуємо міфи

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

Введение Многие разработчики заблуждаются, считая, что CSS – единственный способ работы с анимацией в WEB. CSS становится все более и более популярным, он считается самым надежным и удобным инструментом создания анимаций. Но это не означает, что он лучше, чем JavaScript. В этой статье мы расскажем, почему лучше использовать JavaScript, а не CSS, а также разоблачим мифы, связанные с CSS. 1. JQuery JavaScript и JQuery ошибочно объединяют. Анимации, разработанные с JavaScript – быстрые и динамичные, тогда как анимации JQuery – медленные. Причина в том, что несмотря на его мощные инструменты, JQuery  не был создан для анимации. 2. Отсутствие управления вращением и позиционированием Для выполнения анимации необходимо использовать элементы управления вращением и определением позиции. В CSS все эти функции содержатся в свойстве «transform». Это создает проблемы для уникальной анимации чего-либо через один общий элемент. Например, анимирование «rotation» и «scale» отдельно, с разными таймингами, возможно только с JavaScript, потому что он позволяет использовать различные функции, не поддерживаемые CSS. CSS удобно использовать только для простой анимации. 3. Производительность с Velocity и GSAP Velocity и GSAP – наиболее популярные библиотеки JavaScript. Они работают без JQuery. Нет уменьшения производительности, так как эти библиотеки работают за пределами основных анимаций JQuery. Velocity и GSAP можно применять даже, когда jQuery не используется на странице.  * Работа без JQuery * / Velocity(element, { opacity: 0.4 }, 900); // Velocity TweenMax.to(element, 1, { opacity: 0.4 }); // GSAP В приведенном выше примере Вы видете, что velocity использует тот же синтаксис, даже когда JQuery не применяется. Он просто смещает все элементы в правильном направлении, чтобы создать пространство для целевых элементов. 4. GPU-фактор Полностью оптимизированный код с GPU отлично подходит для выполнения различных задач, включая преобразование матриц и изменение прозрачности, поэтому все ведущие браузеры сначала перенаправляют такие задачи от CPU к GPU. Нужно разделять все анимационные элементы на разные слои GPU. Таким образом мы избавимся от необходимости вычислять каждый пиксель в каждой минуте. Можно сэкономить много времени, просто перемещая один пиксель за другой. Обратите внимание: нет необходимости делать собственный слой для каждого элемента из-за ограничения видеопамяти GPU. 5. Быстрые анимации JavaScript JavaScript обходит CSS в производительности и скорости. JavaScript достаточно универсальный, чтобы создать впечатляющую 3D демо-анимацию, которую Вы можете увидеть через WebGL. Он достаточно быстрый, чтобы построить мультимедийный тизер, разработанный с использованием Flash, или After Effects. С JavaScript это легко сделать с помощью canvas. Вывод Данная статья доказывает, что анимация JavaScript более быстрая, по сравнению с анимацией CSS. Но это не означает, что CSS не стоит использовать. Он хорошо подходит для простой анимации, но если Вы хотите сделать анимацию более гибкой, Вам лучше использовать JavaScript. Источник: http://www.script-tutorials.com/css-vs-javascript-myths-fall-to-pieces/
Угода при розробці AngularJS програми

Автор: Антон Гончаров

Введение Давайте рассмотрим практику написания AngularJS приложения. Приведенные ниже примеры помогут вам писать приложение правильно, чисто и более обдуманно. С помощью применения данной практики вы разработаете приложение, которое будет разделено на блоки, что в конечном итоге поможет строить правильную архитектуру приложения. Итак, начнем. 1) Создавая новое приложение, старайтесь разделять модуль, контроллер, фабрику, вынося их в отдельные файлы. Этот прием имеет ряд приимуществ: улучшается читаемость приложения улучшается рефакторинг приложения легче производить дебаггинг приложения //плохая практика angular        .module('app', ['ngRoute'])        .controller('myController', myController)        .factory('myFactory', myFactory); function myController() { }; function myFactory() { }; //рекомендуется //myapp.module.js – файл модуля angular        .module('app', ['ngRoute']); //mycontroller.js – файл контроллера angular .module('app') .controller('myController', myController); function myController() { }; //myfactory.js – файл фабрики angular        .module('app')        .factory('myFactory', myFactory); function myFactory() { }; 2) Старайтесь оборачивать код в самовызывающиеся функции. Это позволяет : сохранить переменные от глобального объекта scope предотвратить перетирание глобальных переменных (т.к. они локальны) при минификации кода помогает избежать путаницы переменных //плохая практика angular        .module('app')        .factory('myfactory', myfactory); function myfactory() { }; //рекомендуется (function () {     'use strict';     angular         .module('app')         .factory('myfactory', myfactory);     function myfactory() { }; })(); 3) Старайтесь придерживаться иерархии именования. Это поможет правильно структурировать приложение, что в итоге приведет к правильной архитектуре программы. Избегайте создания модуля через переменную и используйте цепочный синтаксис (в виде цепочки) //плохая практика var app = angular.module('app', [        'ngAnimate',        'ngCookies',        'firebase' ]); //рекомендуется angular        .module('app', [        'ngAnimate',        'ngCookies',        'firebase' ]); 4) Используйте именованные функции. Код становится более читабельным и куда лучше тестируется.  //плохая практика angular        .module('app')        .controller('mycontroller', function () { }); //рекомендуется (обратите внимание на контроллер он вынесен в отдельный файл //от модуля) //myapp.module.js – файл модуля angular        .module('app', ['ngRoute']); //mycontroller.js – файл контроллера angular .module('app') .controller('myController', myController); function myController() { }; 5) Используйте controller as нотацию вместо просто controller. Она более читабельна, помогает не запутаться в коде      //плохая практика     <div ng-controller=”myController”>{{title}}div>     //используем     <div ng-controller=”myController as mycontroller”>{{mycontroller.name}}div> 6) Используйте слово vm(ViewModel) внутри контроллера вместо ключевого слова this. Это поможет избежать подмены контекста внутри функции.  //антипаттерн function mycontroller () {        this.name = {};        this.deleteSome = function () {}; }; //паттерн function mycontroller () {        var vm =  this;        vm.name = {};        vm.deleteSome = function () {}; }; Это лишь базовые приемы, которые вы можете использовать в своей практике. Они помогут вам избежать некоторых проблем в вашей роботе и сделать код вашего приложения чище и понятнее. Желаю вам хорошего кода и светлых идей.
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/
Найвищі зарплати в ІТ. Які спеціальності, країни та міста в лідерах?

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

Тренди. Найвищі зарплати Junior, Middle, Senior інженерів. Найвищі зарплати керівної інженерної ланки. Зарплати інших ІТ-фахівців. Найвищі зарплати в США, Європі та решті світу. Дані для рейтингу. Levels.fyi – компанія, що базується в США – нещодавно опублікувала річний звіт за 2023 рік з переліком компаній, міст, тайтлів та різних трендів, які мають найбільші грошові винагороди. Відповідно до інформації на сайті компанії, аналітичні матеріали Levels.fyi дозволяють людям будувати кращі кар’єри в ІТ, відштовхуючись від чесних та прозорих зарплат. Давайте разом подивимось, які ІТ-спеціалісти в яких куточках світу отримують найбільше?   Тренди Спочатку дізнаємось, як змінилися зарплати ІТ-спеціалістів порівняно з 2022 роком. На картинці нижче – медіанні ЗП в доларах США (сумарно за рік) для кожного сімейства спеціальностей. Найвідчутніший приріст мають технічні менеджерські напрямки, повний штиль у Data Scientists, а невеликий від’ємний приріст – у розробників програмного забезпечення та дизайнерів продукту.   Найвищі зарплати Junior, Middle, Senior інженерів Розглянемо річні компенсаційні медіани інженерів, які мають досвід від 0 до 15+ років в розробці. В кожному розділі буде ТОП-7 компаній, які найбільш щедро винагороджують своїх працівників в залежності від їхнього досвіду. Укладачі рейтингу зазначають, що в поняття компенсації входять зарплата, акції та бонуси, отримані за минулий рік, але для простоти ми ототожнюємо “компенсацію” та “зарплату” в даній статті. Інженер початкового рівня (від 0 до 2 років досвіду) Рейтинг включає інженерів рівня Intern/Trainee/Junior. Зазвичай це випускники з невеликим або взагалі нульовим досвідом в галузі. Вони розвивають та підтримують компоненти низької та помірної складності, використовуючи настанови та підтримку членів команди з більшим досвідом. Тут вам можуть бути знайомі Figma та LinkedIn. Перша компанія – всесвітньо відомий розробник онлайн-інструменту для дизайнерів, а друга – соціальна мережа для встановлення ділових зв’язків.  Engineer (від 2 до 5+ років досвіду) Даний тайтл можна прирівняти до Middle. Сюди відносяться спеціалісти, які працюють над компонентами середньої та високої складності, і навіть здатні керувати невеликою командою або проєктом. Можуть менторити та консультувати менш досвідчених інженерів, проводити код-рев’ю, працювати над невеликими проєктами від початку до кінця. Межі відповідальності такого фахівця різняться від команди до команди. В багатьох компаніях спеціалісти можуть працювати постійно на цьому рівні, не боячись, що їх звільнять за те, що вони не просуваються кар’єрною драбиною далі. Senior Engineer (понад 5 років досвіду) Сеньйори – від них очікується керування іншими та просування власних комплексних технічних ініціатив. Можуть виконувати візіонерські функції, визначаючи подальший вектор руху команди. Також здатні впливати на інші команди в межах компанії. Їхня роль більше охоплює дизайнерські задачі, ніж реалізацію – залежно від розміру та очікувань компанії. Зазвичай таких спеціалістів в компанії не більше 30%.   У кого в ІТ найбільші ЗП? Рейтинг світу. Найвищі зарплати керівної інженерної ланки Staff Engineer – інженер управлінського апарату Ця посада передбачає 10+ років досвіду, і є досить бажаною порівняно з Junior, Middle та Senior. Менше 10% персоналу займають цю позицію, при цьому їхній вплив досить масштабний і простягається на різні організації. Інженерам даної ланки довіряють важливі бізнес-проєкти та встановлення технічного бачення для однієї або декількох організацій. Найбільшу винагороду отримують саме staff-інженери з OpenAI – компанії, що наприкінці 2021 року випустила в світ славнозвісний ChatGPT і нещодавно мала бурхливий скандал навколо звільнення гендиректора OpenAI Сема Альтмана. Principal Engineer – головний інженер Посада передбачає 15+ років досвіду, причому менше 3% персоналу сягають цього рівня. Головний інженер характерний для компаній середнього та великого розміру, а в маленьких зазвичай відсутній. Вплив Principal Engineer може поширюватися як на всю компанію, так і на індустрію. Від цих спеціалістів очікують повну автономію в роботі. Аналітики рейтингу зазначають: даний тайтл властивий малому відсотку людей в компанії, а тому деякі компанії не мають інформації в достатній кількості, аби бути включеними в цей список.   Зарплати інших ІТ-фахівців. ІТ-компанії з найбільшими ЗП Аналітики даного звіту розробили стандарт рівнів для менеджерських ролей та ролей індивідуального спеціаліста (individual contributor) в цьому році. Оскільки на початку 2023 у них не була встановлена система рівнів, вони вказують ТОП-5 компаній з найвищим рівнем компенсації, використовуючи медіанне значення в межах компанії для наведених нижче професійних категорій незалежно від рівня. Варто враховувати, що це найвищі медіани, і вони можуть не відображати весь ринок. Software Engineering Manager SE Manager може керувати однією або кількома командами інженерів, які створюють програмне забезпечення (ПЗ). Він комбінує технічні обов’язки з управлінськими і відповідає за: створення сприятливого середовища для ефективної роботи Engineering-команди; визначення структури та навантаження, яке покладається на кожного в команді; трансляцію команді загального руху та цілей компанії; контроль та підготовку технічного роадмапу разом з Tech Lead та інженерами для визначення інструментів, ресурсів та пріоритетів у роботі; надання технічної експертизи; вимірювання показників якості та ефективності команди; тощо. Product Manager Product Manager орієнтований на стратегічне управління продуктом в цілому, включаючи стратегію продажів, ринковий аналіз і взаємодію з клієнтами. На відміну від SE Manager, даний фахівець досить далекий від технічної складової і натомість сконцентрований на досягненні бізнес-цілей. Він фокусується на визначенні функціональності та властивостей продукту, які задовольняють потреби клієнтів, взаємодіє з усіма рівнями команди, включаючи розробників, маркетологів, дизайнерів і т. д. Product Designer Це НЕ UX/UI дизайнер. У Product Designer`а зміщено фокус з UX/UI на досягнення цілей бізнесу, продукту. Якщо “юікс-юай” займається безпосередньо створенням інтерфейсу (роль виконавця), то PD аналізує ринок користувачів, досліджує та визначає їхні потреби, на основі чого можна спроєктувати якісний інтерфейс, який приноситиме користувачеві максимально комфортний досвід, а власнику – аудиторію і прибутки (роль мудрого архітектора, дослідника). Hardware Engineer Важка артилерія від світу розробки. Ці спеціалісти займаються не програмним, а апаратним забезпеченням – “залізом”. Серед їхніх обов’язків: дизайн, розробка, тестування комп’ютерних систем та пристроїв, розробка схемотехнічних рішень та друкованих плат, покращення існуючих пристроїв (заміна компонентів, тестування тощо). Data Scientist Data Scientists працюють з великими обсягами даних і виконують збір, аналіз, структурування і подальшу візуалізацію інформації. Спочатку йде збір великої кількості невпорядкованих даних, а потім – їхнє перетворення у зручний формат, з яким далі працюють аналітики.   Найвищі зарплати в США, Європі та решті світу В яких містах світу топові ЗП у галузі Software Engineering? Американські аналітики дають відповідь і на це питання. Ситуація в США, Європі та світі загалом, відповідно: До останньої картинки автори додають примітку: цей список включає лише одне місто з найвищою оплатою праці в кожній країні. Інші міста в межах країни також можуть мати високу зарплату, яка не відображена в цьому списку.   Дані для рейтингу Головне джерело даних для аналітики – анонімні відгуки, які можна залишити у відповідній формі на сайті. Для цього треба надати наступну інформацію: Розмір компенсації. Інформація про рівні у компанії. Бонуси від компанії. У 2023 році компанія Levels.fyi отримала понад 200 000 заявок від тисяч компаній з усього світу. Нещодавно ми досліджували рівень ЗП та кар’єрний шлях українських DevOps-спеціалістів та Embedded-розробників – переходьте за посиланнями, щоб дізнатись, наскільки цінується їхня праця.
Процедури та таймінг у відділі SEO

Автор: Андрій Афанасьєв

Введение Всем привет! У меня давно созрела навязчивая мысль написать о том, какой является структура работы в техническом отделе SEO. “Почему именно такая тематика?” - спросите Вы. Это наболевшее. Иногда клиенты, да и просто люди, которые не занимаются всерьез данным продуктом, смотрят на весь процесс со стороны и  думают: “Да это же просто дело. Взял проектик, денек-два оптимизировал сайт, ссылочек подкупил, всего делов. Может мне и самому SEO заняться?” Забавляет и интернет-пространство, например, рекламой с лозунгами наподобие: “Хватит платить сеошникам. Продвинь свой сайт самостоятельно!”. Это не может не веселить, если, конечно, не учитывать, что часть пользователей все-таки ведутся на подобные вещи. Ну а если всерьез, то я скажу банальную вещь, что любая стоящая работа требует не менее качественного подхода. Любое интернет-агентство маленького, среднего или большого размаха разрабатывает и выстраивает свой процесс отработки клиентских проектов. В данной статье мы рассмотрим только работу технического отдела, потому что существует еще и аккаунтинг, и топ-менеджмент, которые тоже  важны во взаимодействии компании и клиента. Но там “своя кухня” и она несколько отличается от технической. Идем дальше… Как известно, для того, чтобы построить качественный и надежный дом, нужно начать с фундамента. Так вот, в отделе SEO таковым является регламент процедур и тайминга. Это путеводитель как для руководителя отдела, так и для остальных членов команды. Зачем он нужен? Отвечаю. У каждой компании в отработке находится много текущих + еженедельный поток новых клиентов, которые требуют в разы больше внимания, чем текущие. Когда я приведу пример технологии Abweb, Вы поймете критическую важность этого регламента. Если одновременно ведется работа по десяткам проектов, просто физически невозможно держать все в голове. Необходимо иметь универсальный план действий, который разбит на множество подзадач и переносить его в проекцию каждого проекта. Ну, теперь конкретно о процессах Для того, чтобы всю информацию было проще воспринять, я четко структурирую все процессы в виде двух таблиц. Как правило, процесс продвижения можно условно поделить на 2 глобальных этапа: внутренняя и внешняя оптимизация. Поэтому и процедуры для них разные. Внутренняя оптимизация (1-й месяц) Процедура Старт выполнения Тайминг Проверка доступов от клиента (админка, FTP, хостинг) 1-й день работ 5 рабочих дней Создание папки проекта и файла проекта в CRM с семантикой и основными доступами 1-й день работ Анализ проекта, составление технического задания по внутренней оптимизации для программиста и техническое задание для копирайтера 2-й день работ Отправка сформированных технических заданий аккаунт-менеджеру, который ведет проект. В тот же день, когда составлено ТЗ, но не позднее 5-ого рабочего дня со старта проекта Внедрение правок на тестовом домене. В день, когда аккаунт-менеджер дал сигнал, что ТЗ на оптимизацию утверждено клиентом. 5 рабочих дней (4 дня реализация + 1 день на исправление багов по программной части) Написание текстов для целевых страниц. В день, когда аккаунт-менеджер дал сигнал, что ТЗ на тексты утверждено клиентом. Отправка выполненного ТЗ по оптимизации на тестовом домене аккаунт-менеджеру. В день, когда ТЗ было полностью внедрено и проверено. 1 рабочий день Отправка написанных текстов аккаунт-менеджеру. В день, когда тексты были полностью написаны и проверены. Перенос выполненных правок на основной домен. В день, когда аккаунт-менеджер дал сигнал, что ТЗ на тестовом утверждено клиентом. 2 рабочих дня Размещение текстов. В день, когда аккаунт-менеджер дал сигнал, что клиент утвердил тексты. 3 рабочих дня Тестирование основной функциональности сайта после внесенных правок (форм заказа, авторизация, регистрация, добавление контента и его сохранение и т.д.) + исправление багов, если они есть В день, когда все правки по внутренней оптимизации были перенесены на основной домен. 2 рабочих дня Отправка сайта и целевых страниц на принудительную переиндексацию поисковыми системами для скорейшего индексирования ПС В день, когда все правки по внутренней оптимизации были перенесены на основной домен + протестирован основной функционал 1 рабочий день Добавление сайта в систему мониторинга для отслеживания позиций. Когда все внедрено, отправлено на переиндексацию. Итого примерно 19 рабочих дней Ситуация выглядит таким образом, что за 16 рабочих дней (условно 3 рабочих недели) вся оптимизация должна быть внесена на основной версии сайта. 1 рабочая неделя отводится на тестирование выполненных правок, переиндексацию сайта, мониторинг динамики по позициям и составления отчета по всей проделанной работе. Обращаю внимание, что тут предлагается такой подход, в котором сначала все внедряется на тестовой копии (которую обязательно нужно закрыть от индексации), демонстрируется и согласовывается с клиентом и, если все OK, переносится на основной домен.  Я склонен считать, что это процесс затратный по времени, но зато безопасный! Переходим ко второму и последующим месяцам. Второй и дальнейшие месяцы плюс-минус похожи в плане выполняемых процессов. Внешняя оптимизация (2-й и последующие месяцы) Процедура Старт выполнения Тайминг Планирование и составление ссылочной стратегии в виде ТЗ со списком закупаемых анкоров. После получения оплаты 3 рабочих дня Регистрация аккаунтов для закупки ссылок по проекту 1 этап закупки ссылок На 4-й рабочий день 2 рабочих дня Пополнение ссылочного аккаунта для 1 этапа Плановая проверка сайта на предмет внутренней оптимизации/составление ТЗ по дооптимизации/отправка аккаунт-менеджеру на утверждение 12-й рабочий день 2 рабочих дня Внедрение правок по дооптимизации на основании предыдущего пункта В день, когда аккаунт-менеджер дал сигнал, что ТЗ на дооптимизацию утверждено клиентом. 4 рабочих дня Пополнение ссылочного аккаунта для 2 этапа 14-й рабочий день 2 рабочих дня 2 этап закупки ссылок Модерация ссылочных бирж 1 раз в 2 рабочих дня 11 рабочих дней Наполнение ТЗ на ссылки списком доноров, откуда куплены ссылки За день до составления и отправления отчета аккаунт-менеджером. 1 рабочий день Итого примерно 22 рабочих дня Выше приведена таблица со всеми процедурами и ориентировочными дедлайнами по каждому из них. Хочу сделать акцент на том, что весь этот грандиозный план действий должен быть ориентиром, но всегда бывают исключения. Сроки реализации задач часто зависят от сложности и объема работ по проекту, оперативности клиента по согласованиям технических заданий, текстов и внесенных правок. Могут также вклиниваться и форс-мажорные задачи, которых мы, как правило, не ожидаем. К таким нюансам нужно быть морально готовым и все равно максимально выстроить процессы под нужные дедлайны. Достаточно ли этого? Буду честен. Конечно, нет. Недостаточно лишь прописать процедуры. Чтобы все было “в ажуре”, Вам и нам нужны: Квалифицированные и перспективные ребята, которые будут закрывать все вопросы и задачи, которые расписаны выше (SEO-специалисты, копирайтеры, программисты и т.д.); Календарные планы по процессам. Например, календарный план по закупке ссылочной массы на каждый месяц, который позволит не запутаться в большом потоке, когда что закупать; Правильная постановка задач друг другу в худшем случае с помощью блокнота, а в лучшем - CRM-систем или других программ для фиксирования задач и планирования; Высокая степень самоорганизованности и четко выстроенный тайм-менеджмент у каждого сотрудника; Регулярное проведение планерок. Я с удовольствием поделился с Вами прототипом своего видения по выстраиванию процессов в отделе производства SEO. Буду рад услышать замечания и положительные отзывы. На сегодня пока все;)
Пріоритет операторів у JavaScript (частина 1)

Автор: Олександр Марченко

Введение В данной статье мы познакомимся со стандартными операторами и их применением в языке программирования JavaScript для работы с переменными и со значениями. Сперва познакомимся со специфической терминологией, которая используется при работе с операторами.Большинство операторов обозначаются символами пунктуации, такими как =, +, - и другими. Некоторые – специальными ключевыми словами, к примеру, delete и new. Но, как знаки пунктуации, так и ключевые слова обозначают обычные операторы, просто используют для этого разный синтаксис. Оператор присвоения Операнд – то, к чему будет применен оператор, или порой можно встретить название: «аргумент оператора». Оператор присваивания выглядит как знак равенства = :    var a = 1, b = 2; В данной строке переменной "a" было присвоено значение 1, а переменной b – значение 2.      var a = a + 2; В этой строке переменной "a" было присвоено ее значение, увеличенной на 2. Иначе говоря, сперва выполнится операция сложения текущего значения переменной a, результат которого будет пере-присвоен переменной a. Полезной особенностью данного оператора является использование его по цепочке:      var a, b, c;       a = b = c = 2 + 3; В результате работы последней строки всем трем переменным будет присвоено значение 5. Арифметические операторы Арифметические операторы используются для определения простейших математических операций над операндами, в качестве которых могут выступать как значения, так и переменные: плюс + , минус - , умножить * , поделить / , деление по модулю (определение остатка от деления) %. Большинство JavaScript-операторов работают с двумя операндами, следовательно, способны два простых выражения объединить в одно более сложное. Но JavaScript поддерживает несколько унарных операторов, которые преобразуют только одно выражение в другое, более сложное. Таким оператором является унарный минус, который изменяет знак числа на противоположный. В таком случае оператор «минус» в выражении -1 представляет собой унарный оператор и выполняет смену знака у своего единственного операнда 1. <script type="text/javascript">         var x = 1;         document.write(-x + " ");         document.write(-(-x) + " ");         document.write(-(x + 4) + " "); script> Унарный плюс, используемый в качестве арифметического оператора, не выполняет каких-либо действий: <script type="text/javascript">         document.write(+1);         document.write(" ");         document.write(+(1 - 2)); script> Более распространенным применением унарного плюса является преобразование значения в число. В случае объединения двух выражений в одно более сложное используются бинарные операторы, иначе говоря, бинарным называют оператор, который применяется к двум операндам, к примеру, если оператор плюс будет стоять между двумя числами, он будет представлен в своей бинарной форме: <script type="text/javascript">         var a = 1, b = 2;      document.write(a + b + " ");      document.write(b + a + " "); script> Кроме того, если у нас есть две переменные со строковыми значениями, бинарный плюс сложит эти строки. произведя конкатенацию, а применение унарного плюса к каждой из переменных произведет преобразование их значений к числу. var a = "2"; var b = "3"; alert(a + b); // "23", произошла конкатенация строк alert(+a + b); // "23", второй операнд - всё ещё стоковая переменная alert(+a + +b); // 5, число, поскольку оба операнда предварительно преобразованы в числа ((+a) + (+a)) В то же время, если использовать оператор «минус», мы получим другие результаты: var a = "2"; var b = "3"; alert(a - b); // -1, произошло неявное преобразование типов Таким образом, мы подошли к тому, что создавая JavaScript-выражения, важно обращать внимание на типы данных, передаваемых операторам, и, как следствие, на типы данных, которые они возвращают. Стоит отметить, что различные операторы требуют, чтобы операнды, с которыми они работают, возвращали значения только определенного типа. Так, нельзя выполнить умножение строк, поэтому выражение var a = "text1" * "text2"; не является допустимым и приведет к ошибке. В то же время, выражение var a = "2" * "3"; вполне допустимо, потому что интерпретатор JavaScript будет пытаться по мере возможностей преобразовать выражение в требуемый тип данных, в нашем случае из строкового типа в числовой. Познакомимся с работой операторов умножения и деления на простом примере. В данном случае мы используем бинарные формы операторов, поскольку они взаимодействуют с двумя операндами: <script type="text/javascript">      document.write("2" / 2 + " "); // 1, произойдет неявное преобразование строки в число      document.write(((2 + 2) * 6) / "12" + " "); // 2, произойдет неявное преобразование строки в число      document.write(12 * 7 / 2 + " "); // 42      document.write(17 % 7 + " "); // 3, возвращаем остаток от целочисленного деления      document.write(21 / 3 - 1 + " "); // 6, наблюдаем правильный порядок выполнения операций: сперва деление, затем нахождение разницы script> Если с работой операторов +, -, *, / в самом простом их применении мы были знакомы еще из младшей школы, то с оператором % стоит познакомиться детальней. Оператор деления по модулю % вычисляет остаток, получаемый при целочисленном делении первого операнда на второй, которые в курсе школьной математики именовались как делимое и делитель соответственно, а в результате самого деления мы получали частное и остаток от деления. Деление по модулю подразумевает возвращение остатка от деления. Например, выражение var a = 190 % 27; будет выполнено следующим образом: Оператор деления по модулю зачастую применяют к целочисленным операндам, но он корректно работает и с вещественными значениями. Так, в итоге выполнения выражения var a = -6.3 % 3; переменной a будет присвоено значение -0.3. Кроме этого, стоит отметить следующие особенности вычислений в JavaScript:  <script type="text/javascript">        var a = 4,        b = true;        c = undefined,        d = Infinity,        e = 0,        res = undefined;         res = a * d;         document.write(res + " "); // Infinity, умножение числа на бесконечность возвращает бесконечность         res = a + b;         document.write(res + " "); // 5, true преобразовывается в 1 и производится операция сложения         res = a / e;         document.write(res + " "); // Infinity, деление числа на ноль возвращает бесконечность         res = a * c;         document.write(res + " "); // NaN, умножение числа на неопределенный тип данных, вернет сигнализацию об ошибке в виде NaN - Not a Number script> В дальнейшем мы познакомимся с такими операторами как инкремент/декремент, операторами сравнения, равенства и идентичности, которые будут часто использоваться в написании клиентских сценариев c использованием языка JavaScript.
Як не треба використовувати патерн "Repository"

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

Обобщенный паттерн Репозиторий Чтобы избежать недоразумений, давайте для начала проясним, что здесь имеется ввиду под понятием обобщенного репозитория. Видели ли вы когда-нибудь интерфейс вроде этого: Или может вы видели его брата-близнеца, который имеет иной вариант метода Get: Вдохновение для написания первого примера пришло из официальной документации Microsoft для ASP.NET MVC 4. Что же касательно второго примера, в Интернете вы можете найти бесконечное число блогов, описывающих именно этот вариант написания репозитория — иногда лишь с небольшими отличиями в виде возвращения IEnumerable<TEntity> вместо IQueryable<TEntity>. И в последнем случае часто еще и с дополнительным методом для генерации запросов. Что-то вроде этого: Так что плохого в них, вы можете спросить? Почти ничего, если не считать плохое именование методов из примера Microsoft (здесь лучше было бы использовать Find и FindAll вместо Get и GetAll). Но «почти ничего» - это далеко не то же самое, что «ничего». Первую проблему, которую я здесь вижу, так это нарушение Принципа Сегрегации Интерфейсов (Interface Segregation Principle). Они выражают полный набор CRUD-операций даже для тех сущностей, для которых операции удаления не имеют никакого смысла (к примеру, когда вы деактивируете пользователей вместо удаления их записей из базы данных). Но эта проблема может быть решена при помощи просто разбиения на три интерфейса — для чтения, обновления и удаления записей. Реальная проблема, которую мы здесь имеем, заключается в некорректном использовании. Оригинальная идея заключается в том, что интерфейсы должны быть использованы в качестве базовых для ваших пользовательских интерфейсов. Что-то вроде этого: Ваши обработчики событий и сервисы (клиенты пользовательских репозиториев) должны сами определять нужные методы и помещать их в пользовательские интерфейсы. Это в теории. К сожалению, за свою карьеру мне довольно часто приходилось видеть несколько иную картину: Кто-то создал рабочую реализацию IGenericRepository. Что хуже в этой реализации, так это то, что эта имплементация почти всегда регистрируется в IoC-контейнере и может быть внедрена в ваши обработчики команд и сервисы точно так же, как и любая другая зависимость. Код выглядит достаточно красиво и чисто. На самом деле — нет. Почему именно так — скажу немного позже. Теперь же я бы хотел поговорить об одном из решений неправильной интерпретации GenericRepository<T> многих разработчиков. Само решение выглядит примерно так (диалог на code-review): Джим Сеньор: вы когда-либо слышали, что NHibernate ISession или DbSet из Entity Framework на самом деле репозитории? А то, что вы только что создали — всего лишь небольшая обертка над ISession или DbSet? Де-факто, мы можем отказаться от этого обобщенного репозитория и просто использовать DbSet — результат будет аналогичным. Единственное, в чем IGenericRepository<T> действительно полезен — так это в том, что он скрывает большую часть ненужных для нас методов, которыми обладает DbSet. Джонни Джуниор: да, в этом действительно есть смысл. Я полагаю, использование обобщенного репозитория в нашем случае было лишним (счастливо возвращаемся к написанию программы…) Как по мне, что GenericRepository<T>, что DbSet – в большинстве ситуаций их использование лишнее (ну разве что вы пишите наиболее заCRUDженное приложение в своей жизни). Почему? Вот почему: Единственный способ убедиться, что все LINQ-запросы будут верно преобразованы в SQL — это протестировать их на том же типе базы данных, что находятся в продакшине. Кроме того, в таком случае задача написания интеграционных тестов становится достаточно затруднительной. К примеру, взглянем на код: Чтобы выполнить эти запросы, должны быть соблюдены два условия. За счет этого интеграционный тест становится менее читабельным. Теперь же давайте представим, что этот метод помещен в метод репозитория. Теперь в тесте нам нужно просто вызвать метод репозитория и проверить результат — просто, не так ли? Я уверен, вы согласитесь, что LINQ-предикаты внутри сервисов нельзя использовать повторно и они имеют плохую тенденцию повторяться на протяжении всего кода. Даже если программист желает извлечь запрос в свой собственный метод, обычно это будет приватный метод конкретного сервиса. Инкапсуляция запросов внутри методов репозитория приведет к большей читабельности кода и в значительной мере упростить его использование. LINQ-предикаты не именуются. Как правило, единственный способ узнать, что же, собственно говоря, делает наш запрос (без углубления в его логику), так это имя переменной-результата. К сожалению, искусство информативного именования переменных постигается с опытом, а поскольку в нашей индустрии полно начинающих программистов, мы имеем дело с переменными вроде result, ordersToProcess или просто — orders. Создавая обертку над запросами в виде метода репозитория, это автоматически обязывает разработчика дать этому самому методу конкретное имя. Даже если это имя не из лучших, в последствии провести небольшой рефакторинг не составит труда! Порой, по причине скорости, мы вынуждены доставать данные из базы посредством чистого SQL. Подумайте, вы действительно хотите в своей бизнес-логике работать с такими низкоуровневыми сущностями, как DbConnection или SqlException? Подобный код лучше прятать за методами репозиториями.   Никаких обобщений — только конкретные репозитории   Перед тем как начать разработку репозитория, необходимо определить его интерфейс. Интерфейс должен содержать только те методы, которые нужны конечным клиентам. Другими словами, если никому не нужно удалять сущности данного типа, нет никакого смысла в написании функционала для их удаления. Если вы боитесь закончить среди разных имен для базовых CRUD-операций — таких как Delete в одном репозитории и Remove в другом — вы можете создать полезные интерфейсы типа ICanDeleteEntity<TEntity>, ICanUpdateEntity<TEntity> и так далее. В таком случае конкретный репозиторий будет реализовывать только действительно нужные из них. Ни один из методов репозитория не должен возвращать IQueryable<T>. Также убедитесь, что репозиторий не возвращает IQueryable<T>, скрытые за IEnumerable<T>. Всегда вызывайте ToList() или ToArray() дабы «материализовать» значения, придав им более конкретный тип данных. Как только заходит речь о реализации репозитория, вы можете наследовать абстрактный класс GenericRepository<TEntity>. Если угодно — можно также использовать напрямую ISession и DbSet. Не важно, какой подход вы выбираете. Помните: любые «лишние» в данном контексте методы — по типу Delete из базового класса — будут скрыты за интерфейсом репозитория. Также не забывайте, что ваш репозиторий не несет ответственности за транзакции базы данных. Лучше всего эта концепция реализуется при помощи паттерна Unit Of Work. Этот паттерн уже реализован в рамках ISession и DatabaseContext. Все, что нам нужно — это хороший интерфейс над ними: Для большинства веб-приложений чтобы начать транзакцию через IUnitOfWork в виде начала запроса и Commit / Rollback в конце запроса — этого функционала вполне достаточно. Так же подобное может быть достигнуто при помощи фильтров действий или декораторов обработчиков / сервисов. Пример репозитория, созданного при соблюдении всех приведенных рекомендаций:   Сейчас все стало ясно, но давайте еще раз проясним. Каждый метод наших репозиториев должен быть учтен по крайней мере одним интеграционным тестом, который должен использовать тот же тип базы данных, что и продакшн. Всегда используйте интеграционные тесты для проверки своих репозиториев. Немного о недостатках Не существует роз без шипов, и представленный выше подход — не исключение. Некоторые из них можно решить, используя отличимую от трехуровневой архитектуру. Наиболее часто с конкретными репозиториями возникали следующие проблемы: За длительное время репозитории могут набрать большое количество Find-методов. Достаточно часто эти методы похожи друг на друга. Есть два способа это предотвратить. Один из них — это группировка нескольких Find-методов в один общий. Этот метод должен принимать object, что представляет собой критерий запроса. Пример: Чтобы создать запрос с критерием запроса, мы строим набор критериев шаг за шагом:   Зачастую слишком большие репозитории обрастают целой плеядой различных сервисов. Вы можете избежать этого при помощи чего-то, что я называю CQRS-light. Отличием от полной версии является использование тех же таблиц как для чтения, так и для записи. Используя эту технологию, мы можем использовать ту же самую ORM как для чтения, так и для записи. Обращаться же к CQRS только в тех случаях, когда приложение в этом действительно нуждается (например, при обработке 80+ колонок, с использованием 20+ join). Диаграмма ниже представляет типичную архитектуру CQRS-приложения: Ключевые принципы CQRS-light следующие: Деление всех действий пользователя на две категории. Первая категория — действия, изменяющие систему. К примеру, оформление заказа в интернет-магазине. Вторая категория — действия, систему не трогающие. К примеру, просмотр списка товаров. Первая категория пишет — это команды, другая — читает, это запросы. Обработчики запросов для доступа к данным могут использовать только репозитории. Доступ к данным может осуществяться посредством любой технологии. Обычная конфигурация включает в себя ORM для чтения-записи, ORM для записи и микро-ORM для чтения (вроде Dapper) или же ORM для записи и чистый SQL для чтения. Обработчики команд для доступа и изменения данных могут использовать только репозитории. Для получения данных из базы обработчики команд не должны использовать обработчики запросов. Если обработчик команд должен выполнить комплексный запрос и этот запрос должен получить ответ от обработчика запроса, вы должны продублировать логику этого обработчика запроса и поместить его как в обработчик запроса, так и в метод репозитория (операции чтения и записи должны быть разделены). Обработчики запросов тестируются только в интеграционных тестах. Для обработчиков команд существуют юнит и — опционально — также интеграционные тесты. CQRS даже в своей легкой форме — сама по себе объемная тема и заслуживает отдельного блога. Теперь же давайте вернемся к теме недостатков паттерна конкретного репозитория. Другой недостаток, о котором я бы хотел упомянуть, заключается в нежелательной миграции бизнес-логики в определение запросов. К примеру, даже такой простой запрос:   содержит часть бизнес-логики, описывающей необходимые параметры, дабы заказ стал активным. Как правило, ORM не позволяет нам инкапсулировать такие части логики в отдельные свойства, как IsActive. Что нам здесь нужно, так это паттерн спецификации. Теперь наш запрос в форме паттерна спецификации будет выглядеть так: Автор перевода: Евгений Лукашук Источник
Notification success