• О декораторах, сквозной функциональности, CQRS и слоеной архитектуре

      Разработчик SimpleInjector очень любит «декораторы», особенно в сочетании с дженериками вида
      QueryHandler<TIn, TOut>, CommandHanler<TIn, TOut>.

      Такой подход позволяет «навешивать» на обработчики то, что принято называть cross-cutting concerns без регистрации и смс interception и особой уличной магии вроде Fody или PostSharp.

      CQRS не top level architecture, поэтому хочется иметь такие-же декораторы и для классических Application Service. Под катом я расскажу как это сделать.
      Читать дальше →
    • Domain Driven Design на практике

      • Tutorial
      Эванс написал хорошую книжку с хорошими идеями. Но этим идеям не хватает методологической основы. Опытным разработчикам и архитекторам на интуитивном уровне понятно, что надо быть как можно ближе к предметной области заказчика, что с заказчиком надо разговаривать. Но не понятно как оценить проект на соответствие Ubiquitous Language и реального языка заказчика? Как понять, что домен разделен на Bounded Context правильно? Как вообще опредилить используется DDD в проекте или нет?

      Последний пункт особенно актуален. На одном из своих выступлений Грег Янг попросил поднять руки тех, кто практиукует DDD. А потом попросил опустить тех, кто создает классы с набором публичных геттеров и сеттеров, располагает логику в «сервисах» и «хелперах» и называет это DDD. По залу прошел смешок:)

      Как же правильно структурировать бизнес-логику в DDD-стиле? Где хранить «поведение»: в сервисах, сущностях, extension-методах или везде по чуть-чуть? В статье я расскажу о том, как проектирую предметную область и какими правилами пользуюсь.
      Читать дальше →
    • CQRS. Факты и заблуждения

      • Tutorial

      CQRS — это стиль архитектуры, в котором операции чтения отделены от операций записи. Подход сформулировал Грег Янг на основе принципа CQS, предложенного Бертраном Мейером. Чаще всего (но не всегда) CQRS реализуется в ограниченных контекстах (bounded context) приложений, проектируемых на основе DDD. Одна из естественных причин развития CQRS — не симметричное распределение нагрузки и сложности бизнес-логики на read и write — подсистемы Большинство бизнес-правил и сложных проверок находится во write — подсистеме. При этом читают данные зачастую в разы чаще, чем изменяют.

      Не смотря на простоту концепции, детали реализации CQRS могут значительно отличаться. И это именно тот случай, когда дьявол кроется в деталях.
      Читать дальше →
    • Про ошибки и исключения



        В прошлый раз я разобрал два примера (раз, два), как можно перейти от императивной валидации входных значений к декларативной. Второй пример действительно «слишком много знает» про аспекты хранения и имеет подводные камни (раз, два). Альтернатива – разбить валидацию на 3 части:

        1. Модел байндинг: ожидали int, пришел string – возвращаем 400
        2. Валидация значений: поле email, должно быть в формате your@mail.com, а пришло 123Petya – возвращаем 422
        3. Валидация бизнес-правил: ожидали что корзина пользователя активна, а она в архиве. Возвращаем 422

        К сожалению стандартный механизм байндинга ASP.NET MVC не различает ошибки несоответствия типа (получили string вместо int) и валидаци, поэтому если вы хотите различать 400 и 422 коды ответа, то придется это сделать самостоятельно. Но речь не об этом.

        Как слой бизнес-логики может вернуть в контроллер сообщение об ошибке?


        Самый распространенный по мнению Хабра способ (раз, два, три) – выбросить исключение. Таким образом между понятием «ошибка» и «исключение» ставится знак равно. Причем «ошибка» трактуется в широком смысле слова: это не только валидация, но и проверка прав доступа и бизнес-правил. Так ли это? Является ли любая ошибка «исключительной ситуацией»? Если вы когда-нибудь сталкивались с бухгалтерским или налоговым учетом, то наверняка знаете, что существует специальный термин «корректировка». Он означает, что в прошлом отчетном периоде были поданы неверные сведения и их необходимо исправить. То есть в сфере учета, без которой бизнес не может существовать в принципе, ошибки – объекты первого класса. Для них введены специальные термины. Можно ли назвать их исключительными ситуациями? Нет. Это нормальное поведение. Люди ошибаются. Программисты — просто чересчур оптимистичный народ. Мы просто никогда не снимаем розовых очков.
        Читать статью полностью желаешь
      • Еще немного о валидации в ASP.NET

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

          public class MoveProductParam
          {
             public ProductId {get; set; }
          
             public CategoryId {get; set; }
          }
          
          //...
          if(!dbContext.Products.Any(x => x.Id == par.ProductId))
              return BadRequest("Product not found");
          
          if(!dbContext.Categories.Any(x => x.Id == par.CategoryId ))
              return BadRequest("Category not found");
          

          Мы достойны лучшего
          public class MoveProductParam
          {
             [EntityId(typeof(Product))]
             public ProductId {get; set; }
          
             [EntityId(typeof(Category))]
             public CategoryId {get; set; }
          }
          
          Читать дальше →
        • Избавляемся от boilerplate для валидации в ASP.NET MVC

            В большинстве примеров проверка входных данных ASP.NET MVC осуществляется следующим образом:

                    [HttpPost]
                    public IActionResult Test(SomeParam param)
                    {
                        if (!ModelState.IsValid)
                        {
                            return View(param);
                            // return Json({success: false, state: ModelState});
                        }
                        
                        dbContext.UpdateData(param);
            
                        return RedirectToAction("index");
                        // return Ok({success: true});
                    }
            

            Этот код можно улучшить:

            1. вынести валидацию из тела метода и избавиться от дублирования if (!ModelState.IsValid)
            2. вернуть код ответа 422
            Читать дальше →
          • Шаблон проектирования «состояние» двадцать лет спустя

              Состояние — поведенческий шаблон проектирования. Используется в тех случаях, когда во время выполнения программы объект должен менять своё поведение в зависимости от своего состояния. Классическая реализация предполагает создание базового абстрактного класса или интерфейса, содержащего все методы и по одному классу на каждое возможно состояние. Шаблон представляет собой частный случай рекомендации «заменяйте условные операторы полиморфизмом».

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

              Нарушение принципа подстановки Лисков на лицо. Yaron Minsky предложил альтернативный подход: сделайте недопустимые состояния непредставимыми (make illegal states unrepresentable). Это дает возможность перенести проверку ошибок со времени исполнения на время компиляции. Однако control flow в этом случае будет организован на основе сопоставления с образцом, а не с помощью полиморфизма. К счастью, частичная поддержка pattern matching появилась в C#7.
              Альтернативная реализация шаблона
            • О пользе лаконичности



                С одной стороны, программисты – мягко говоря не самые общительные люди на свете. Это нормально, ведь если разработчики вдруг станут разговорчивыми кто будет писать код? С другой – время одиночек прошло. Современное ПО разрабатывается командами и даже самые консервативные компании, вроде Сбербанка внедряют Agile. Agile manifest пропагандирует определенные ценности, в том числе: «Люди и взаимодействие важнее процессов и инструментов». Так что общение с коллегами – не прихоть, а потребность. Эта статья ориентирована на гибкие команды разработки: разработчиков, тим-лидов, аналитиков, тестировщиков и т.д.

                Профессиональные PM вряд ли найдут здесь что-то новое. Если вы – «технарь» и хотите, чтобы вас как можно меньше отвлекали от основного вида деятельности и вам интересно при чем здесь Спарта, добро пожаловать под кат.
                Читать дальше →
              • Железнодорожно-ориентированное программирование. Обработка ошибок в функциональном стиле

                • Перевод
                • Tutorial

                Как пользователь я хочу изменить ФИО и email в системе.

                Для реализации этой простой пользовательской истории мы должны получить запрос, провести валидацию, обновить существующую запись в БД, отправить подтверждение на email пользователю и вернуть ответ браузеру. Код будет выглядеть примерно одинаково на C#:

                string ExecuteUseCase() 
                { 
                  var request = receiveRequest();
                  validateRequest(request);
                  canonicalizeEmail(request);
                  db.updateDbFromRequest(request);
                  smtpServer.sendEmail(request.Email);
                  return "Success";
                }
                

                и F#:

                let executeUseCase = 
                  receiveRequest
                  >> validateRequest
                  >> canonicalizeEmail
                  >> updateDbFromRequest
                  >> sendEmail
                  >> returnMessage
                
                Читать дальше →
              • OO VS FP

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

                Эти точки зрения игнорируют саму суть ООП и ФП парадигм. Вставлю свои пять копеек.
                Читать дальше →