• Чтобы вести разработку быстрее, необходимо замедлиться
    0

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

  • Чтобы вести разработку быстрее, необходимо замедлиться
    0
    Поправил, спасибо за внимательность.
  • Чтобы вести разработку быстрее, необходимо замедлиться
    0
    А какой перевод вам кажется корректным? Искал принятые в сообществе переводы — однозначного мнения так и не обнаружил.
  • Как правильно работать с исключениями в DDD
    0
    Привел пример в комментарии выше.
  • Как правильно работать с исключениями в DDD
    +1
    Спасибо за развернутый ответ.

    Это как раз классический случай, где надо преобразовывать отсутствие объекта (Single/First) в return value и работать дальше уже с ним.

    Полагаю, данный сценарий можно однозначно разделить на два, и ваша статья про response codes помогла мне это понять, за что дополнительное спасибо.

    Предполагая, что мы остаемся в контексте DDD и Web:

    1. Требуется загрузить aggregate root по идентификатору, пришедшему в web-запросе. Если aggregate root не найден, то бизнес-логика вряд ли сможет делать какие-либо предположения кроме того, что пользователь прислал неверный идентификатор, что превращается в код 404. Если мы используем специфичный репозиторий, а не формируем запросы через IQueryable прямо из бизнес-логики, то данный сценарий можно обработать единожды на уровне Data Access вместо повторяющейся обработки во всех местах вызова из бизнес-логики.

    2. После загрузки aggregate root «Заказ» мы обнаруживаем, что он находится в статусе «Оплачен», но данные об оплате при этом отсутствуют. Для работы с такими случаями идеально подходит Maybe и проверки результата уже на уровне бизнес-логики и дальнейшую трансформацию в код 500, если проверка не пройдена.

    Код получается более verbose, да, но он при этом становится наоборот, более читаемым благодаря явной логике ветвений.

    Абсолютно согласен, что логика становится более явной и Result является верным выбором при написании Domain-логики. Но verbosity может перевесить когда мы работаем над «глупыми» слоями, например при построении Anti Corruption Layer.

    Данную ситуацию трудно пояснить на каком-то специфичном сценарии, поэтому приведу пример общеизвестный, но несколько утрированный — Entity Framework.

    В определенных условиях DbContext выбрасывает исключение ObjectDisposedException. И выброс исключения это оптимальный вариант в данном случае.

    Было бы хорошо, если бы методы First и Single возвращали Maybe вместо выброса InvalidOperationException.

    Было бы хорошо, если бы SaveChanges возвращал Result вместо выброса EntityValidationException.

    Но было бы плохо, если бы Result возвращался вместо выброса ObjectDisposedException, поскольку это бы засорило все контракты IQueryable и даже не могу представить, как бы в таком случае выглядел Lazy Loading. Такая загрузка контракта не стоит того, чтобы обрабатывать ошибку, которая при правильном использовании вообще никогда не произойдет.

    Повторюсь, пример утрированный. Но попытки выстроить Anti Corruption Layer вокруг legacy систем могут ставить в ситуации, которые и в кошмарном сне не приснятся.

    Я обычно делегирую все (возможнные) проверки слою домена через паттерн Do/CanDo.

    Так просто и элегантно, но почему-то никогда не приходило в голову. Спасибо за совет :)
  • Как правильно работать с исключениями в DDD
    +5
    Вопрос не в бровь, а в глаз.
    Для F#, скажем так, зреем и для этого есть куда более весомый довод — упомянутый в статье проект это лишь front-часть, высунутая наружу. А дальше куча микросервисов, представляющих из себя машины состояний на Mass Transit.
    И на императивном языке описывать машины состояний то еще удовольствие. Отлично ощущаешь почему в мире C# и Java так прижился XML :)
    В обозримом будущем (2-3 месяца) планируем аккуратно попробовать F# и начать как раз с машин состояний. Если заведется — тоже будет статья на Хабр.
  • Как правильно работать с исключениями в DDD
    0
    В случае бизнес-ошибок web-серверу тоже лучше работать с Result.

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

    Для ошибки «нет средств для списания» больше походит Result, который в Web будет превращен в код 400 или 409, в зависимости от того, какой выглядит осмысленнее для клиента приложения.

    Вообще, если мы принимаем правила статьи и 403, 404, 422 и 500 обрабатываем исключениями, то мы можем быть уверены на стороне Web, что Result это сугубо бизнесовая ошибка (и к этому и стоит стремиться, на мой взгляд) и его можно преобразовывать в 200 на случай Success и в 400 или 409 на случай Failure.
  • Эффективные личные финансы. Простой способ
    +1
    Радости от покупки после того, как на нее накопил, наоборот больше, потому что усилие приложил, постарался.
    И внезапные поездки вовсе не исключается. Я за жизнь дважды срывался в неожиданные поездки и это очень приятные воспоминания и надолго. По возвращению делаешь reset финансов и заново учет стартуешь. То есть не надо доводит до ситуации, когда финансы управляют тобой, а не ты ими.
  • Эффективные личные финансы. Простой способ
    0
    Если вы не про карьеру в уже выбранной профессии, то я бы на эту тему сам послушал, а не рассказывал.
  • Эффективные личные финансы. Простой способ
    +1
    Так со многими товарами.
    Экономия на обуви, особенно зимней, тоже боком выходит. Футболки покупаешь за 500 рублей и через полгода они как половая тряпка выглядят. Покупаешь за 1000-1200 и носишь 2-3 года.
  • Эффективные личные финансы. Простой способ
    0
    Так социальный аспект пропадает. Иногда хочется с друзьями алкоголь принять или вообще в незнакомой шумной толпе потолкаться :)
  • Эффективные личные финансы. Простой способ
    0
    Хороших материалов по средне- и долгосрочным целям сам бы почитал.

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

    Все либо рискованно, либо требует по сути получения второй профессии и полного вовлечения по времени, либо вообще и то и другое.
  • Эффективные личные финансы. Простой способ
    +1
    Думаю, с анализом и оптимизацией все сильно индивидуально, поэтому не стал расписывать в статье.
    Могу поделиться кратко своими «достижениями»:

    1. Кофе, убер и прочие мелочи рассосались сразу с началом планирования. Даже анализ не пришлось проводить.
    2. В первый же месяц обнаружил, что довольно часто с женой вдвоем пьем пиво под сериальчик, берем к нему закуски или заказываем еду. Начали пить пиво только с друзьями в барах. Раньше в бары тоже ходили, но теперь средний чек как-то сам собой уменьшился. Дома употреблять алкоголь вообще перестали.
    3. Существенная часть денег уходила на готовую еду всех разновидностей. От купленного в магазине салатика и до похода вечером в кафе, когда с женой оба устали. Вместе с этим так совпало, что посмотрел курс про еду и здоровье от coursera (бесплатный, с русскими субтитрами). Мотивации сэкономить деньги было недостаточно для серьезных перемен, тут и помог курс. Начал постоянно помогать жене с готовкой, посуду теперь вообще только я мою. Дома всегда держим упомянутые в курсе чеснок, лимон, соевый соус и т.д., с которыми приготовить блюдо можно вообще из чего угодно. Теперь и завтракаем, и ужинаем всегда дома. Уже несколько месяцев не то что еду с доставкой, даже колбасу не покупали. Бюджет на еду стабилизировался и сжался почти в три раза.

    По итогу всех перемен не только траты уменьшил, но еще и сам собой похудел на пару кило.
  • Эффективные личные финансы. Простой способ
    +5
    А каких советов вы ожидаете для тех, кто зарабатывает мало? «Просто зарабатывайте больше»?
    Финансовый учет это не способ взять там, где ничего не лежит. Это способ грамотно распорядиться, тем что есть в вашем распоряжении.
  • Эффективные личные финансы. Простой способ
    0
    Пока не вел бюджет и не был семейным, было наоборот, поскольку стихийно покупал готовую еду, заказывал с доставкой, ел в кафе.
    Когда взял привычку питаться нормально дома то цифра тоже стала плюс-минус стабильной. Но ее в любом случае сначала надо посчитать, когда начинаешь планирование финансов.
  • Эффективные личные финансы. Простой способ
    0
    Полагаю, коммуналка зависит от множества факторов, начиная от площади квартиры и заканчивая регионом проживания.

    2500 приходит в счете от ЖКУ в Новосибирске за однокомнатную квартиру.
    Интернет и мобсвязь в статье считал отдельно. Покупку и замену счетчиков не включал, поскольку это не относится к фиксированным тратам.
  • Эффективные личные финансы. Простой способ
    +1
    Описал более внятно в статье. Спасибо, что поделились :)
  • Эффективные личные финансы. Простой способ
    +5
    Если попытка посчитать финансы заставляет задуматься о смысле жизни, то, финансы надо увеличивать, а не считать :)
  • Эффективные личные финансы. Простой способ
    0
    А, да все нормально :) Я действительно не понял.
    Возможно, эти траты стоило назвать не постоянными, а фиксированными.
    Еда к ним не относится, поскольку заранее не известно, сколько на нее уйдет в месяц. Сильно зависит от того, что покупать, в какой магазин ходить и вообще в магазине покупать или в кафе/ресторанах кушать.
  • Эффективные личные финансы. Простой способ
    +1
    Если заниматься финансовым планированием, а не финансовым безумием, то нормально.
    От того, что начинаешь считать деньги, их ведь меньше не становится.
    Хочется кушать — кушай. Не хватает на покушать и минимальные сбережения — зарабатывай больше.
  • Учись учиться: непрерывное образование – ключ к конкурентоспособности в эпоху цифровой экономики
    +3
    Не могу не поделиться ссылкой на бесплатный и даже с русскими субтитрами курс Learning How To Learn
  • Хватит подозревать разрабов в самозванстве. Научитесь лучше собеседовать
    +9
    Я закрываю скайп и, конечно, тут же вспоминаю, что за virtual.

    Наверняка у многих такое бывало на собеседовании. Но, когда беседа закончена, то уже «нещитово».
    Маленький лайфхак: можно записать суть вопроса одним словом на бумажке и предложить продолжить разговор.
    Неизбежно возникнет пауза (например, когда собеседующий будет мысль формулировать) и ваш на секунду освободившийся мозг вытолкнет найденную в архивах информацию.
    Так уж наш мозг работает.
  • Angular vs React: битва за фронтенд
    +17
    Чак Норрис, это вы?
  • Почему программистам нужны ограничения
    0
    Судя по всему, мне стоило не лениться и описать сценарии более детально.
    Пример 1.
    Используем какой-либо внешний сервис, и он бросается исключениями, например, если ему были переданы некорректные параметры. А мы, в итоге, вынуждены заниматься разбором текстов и/или типов исключений, чтобы направить логику работы по тому или иному пути. Например, банально определить, прокинуть ли текст исключения в исходном виде до UI пользователя, потому что это исключение с сообщением о бизнесовой ошибке. Или же это техническое исключение (связь отвалилась, сервис лежит) и надо замаскировать сообщение.

    Пример 2.
    Код бизнес логики для большого и толстого кейса. Реализовано это все в виде кучи классов/методов — как кому угодно, не суть. Главное это большой уровень вложенности. Метод вызывает метод, который вызвал метод, который вызвал метод.
    И где-то в глубине нужно по определенному условию прервать вообще всю операцию. Как такой обычно пишется? У всех методов в цепочке сделать возвращаемое значение и ставить if-ы для проверки по всей цепочке вызовов? А если методы должны по бизнесу какие-то значения возвращать? Решение, которое я видел много-много раз — выбрасывать exception аля BusinessLogicException. А на верхнем уровне стоит catch на этот тип исключения, который не делает ничего, просто глушит операцию.

    Возможно, у нас с вами совсем разные условия обитания, но я с такими примерами сталкиваюсь постоянно.
    В приложенном видео как раз приводится резонный и простой способ избегать подобных ситуаций.
  • Почему программистам нужны ограничения
    –1
    Со временем, новые языки программирования полностью отказались от поддержки GOTO.

    И добавили поддержку throw/catch. Структурно то же самое, но только без усов.
    Не раз и даже не два видел бизнес-логику, основанную на типах исключений. Да и сам пару раз такое писал, чего уж греха таить.
    Задумавшимся об альтернативах — ссылка на полезное видео
  • Представляем библиотеку right-angled, конструктор гридов для angular2
    0
    В итоге сделали feature request о котором вы говорили. Детали, как всегда, в демо-приложении.

    А еще мы сегодня вышли в релиз :)
  • Невидимые друзья вашего github-репозитория
    +1
    Разумно. Поднял заметку о том, что речь в основном про npm, чтобы она была до хабраката.
  • Представляем библиотеку right-angled, конструктор гридов для angular2
    0
    Добрый день. За рекламу большое спасибо )

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

    Суть сэмпла в том, что управление массивом элементов можно взять на себя. В сэмпле записи копируются в поле «myOwnItemsCollection» и в шаблоне теперь используется это поле, вместо обычного «list.items».
    Теперь имеющиеся записи не уничтожаются, а перетираются новыми. Плюс на время запроса за данными добавлена маска, как вы и написали.

    Вообще RTList никакой магии с коллекцией записей не делает. Он лишь опционально вызывает метод destroy элементов при уничтожении (про него мы вот тут написали). И еще он определяет, почистить или нет уже загруженные записи для случая когда список буферный. Эту логику очень легко воспроизвести в своем коде и реализовать нужное поведение по остальным вопросам. Мы решили выбрать такой подход, вместо добавления сомнительных настроек типа «уничтожать записи до/после загрузки»,

    А текущее поведение сделали основным поскольку уничтожение имеющихся записей, пока идет загрузка новых, позволяет уменьшить «лаг» при отрисовке большого количества данных (особенно если логика уничтожения записей в методе destroy «тяжелая»), что тоже важно.
  • Представляем библиотеку right-angled, конструктор гридов для angular2
    0
    Виртуальный скролл пока не можем, но в планах по развитию стоит.
  • Почему я больше не использую MVC-фреймворки
    +2
    Уважаемые хабравчане.

    Поскольку дискуссия вокруг статьи идет весьма активно, Жан-Жак Дюбре (он читает комментарии) решил организовать чаты в gitter.

    Вы можете пообщаться с ним лично в следующих чатах:
    https://gitter.im/jdubray/sam
    https://gitter.im/jdubray/sam-examples
    https://gitter.im/jdubray/sam-architecture

    Также автор статьи разместил примеры кода здесь: https://bitbucket.org/snippets/jdubray/

    По поводу кода он оставил следующий комментарий:
    I don't code for a living, so I am not the best developer, but people can get a sense of how the pattern works and that you can do the exact same thing as React + Redux + Relay with plain JavaScript functions, no need for all these bloated library (and of course you don't need GraphQL).
  • Почему я больше не использую MVC-фреймворки
    +2
    Сoncern при переводе на русский язык плохо отделяется от responsibility. Мне неизвестны устоявшиеся русские переводы этих слов в среде разработчиков, которые бы четко отделяли одно от другого. То же самое касается, к примеру, cohesion и coupling.

    По поводу side effect — никогда не слышал чтобы разработчики употребляли термин «побочный эффект» или «сторонний эффект».

    Ну и оба термина часто используются разработчиками в речи без перевода.
  • Почему я больше не использую MVC-фреймворки
    +1
    Автор ответил на вопрос по поводу масштабируемости:
    Оригинал
    There are a couple of reasons why Redux «does not scale to real-world applications» (which is an expression that Dan Abramov is using all the time to explain that Redux is so much better).

    First, Redux cannot implement the simple rocket example because it does not have a «next-action-predicate», so when the counter is decremented and something has to decide what to do next, Redux, is powerless, some ugly code will show up in the reducer.

    Second, Redux is coupling action/model inside the reducer. Let's say you trigger an action that increments a counter, all I suggest in SAM is that you factor the code in two steps:
    a) an action (a pure function) hat given a dataset computes the proposed changes to the model
    b) a method that mutates the model

    The Redux reducer looks like this:

    case INCREMENT:
                return state + 1;
    

    All I am saying, you need to write an action increment:

    function increment(data) {
         data.counter = data.counter || 0 ;
         data.counter += 1 ;
         return data ;
    }
    

    and then present the new value to the model which will choose to accept the proposed values:

    model.present = function(data) {
           if (data.counter !== undefined) {
               // can have some validation rules that decides whether
               // that value is acceptable or not
               model.counter = data.counter ;
           }
    }
    


    In SAM the actions and the model updates are strictly decoupled, unlike Redux which encourages people to create a big ball of mud, for no particular reason, other than Dan using a naive interpretation of state machine semantics.

    With SAM, actions are external to the model and as such can be reused across models and even implemented by third parties. In Redux, actions are merely intents. The implementation of the action is in the model (reducer). That is wrong.

    Перевод
    Есть несколько причин почему Redux “не масштабируется под реальные приложения” (это выражение, которое Дэн Абрамов постоянно использует чтобы объяснить, что Redux гораздо лучше)

    Во-первых, Redux не в состоянии реализовать простой пример с ракетой, потому что он не имеет “next action predicate”. То есть когда счетчик уменьшается и нужно принять решение, что делать дальше, то Redux бессилен и в reducer появится какой-либо уродливый код.

    Во-вторых, Redux связывает действия и модели внутри reducer. Предположим, вы вызываете действие которое увеличивает счетчик, все, что я предложил в SAM это что разделить код на два шага:
    а) действие (чистая функция)
    b) метод, который изменяет модель

    Reducer в Redux выглядит следующим образом:
    case INCREMENT:
                return state + 1;
    

    Все, что я утверждаю, это что вам необходимо написать действие инкрементации:
    function increment(data) {
         data.counter = data.counter || 0 ;
         data.counter += 1 ;
         return data ;
    }
    


    И после этого предоставить новой значение в Model, который решит, принять ли предлагаемое значение:
    model.present = function(data) {
           if (data.counter !== undefined) {
               // can have some validation rules that decides whether
               // that value is acceptable or not
               model.counter = data.counter ;
           }
    }
    

    В SAM действия и обновления модели строго разделены, в отличие от Redux, который поощряет людей в создании big ball of mud (полагаю, автор про антипаттерн) без особых на то оснований, помимо этого Дэн использует наивную интерпретацию семантики машин состояний.

    В SAM, действия являются внешними по отношению к Model и, как таковые, могут быть переиспользованы с другими Model-ами и даже быть реализованными третьей стороной. В Redux, действия это всего лишь намерения. Реализация действий находится в модели (reducer). Это неправильно.
  • Почему я больше не использую MVC-фреймворки
    +1
    Да, речь именно про finite state machine.
    Комбинация с MVC и предлагается автором, то есть он предлагает оценить нашу систему с точки зрения состояний (выделить их в отдельный конструктив) и на их основе вычислять next-action predicate.

    По поводу дерева каталогов и бесконечного количества состояний не совсем понял. Можете более развернуто описать? Я могу представить состояния к примеру, «редактируемый-нередактируемый», или «актуальный каталог-каталог в архиве», но бесконечного количества состояний я не могу представить.
  • Почему я больше не использую MVC-фреймворки
    +1
    Читая статью я сделал вывод что главное отличие в этом:
    Другими словами, машины состояния не должны быть кортежами, соединяющими два состояния (S1, A, S2) каковыми они обычно являются. Они являются, скорее, кортежами форм (Sk, Ak1, Ak2,...) которые определяют все разрешенные Actions для состояния Sk с результирующим состоянием вычисляемым после того, как Action был применен к системе и Model обработал изменения.

    И выведенном далее отдельном state representation.

    На всякий случай написал еще автору оригинальной статьи и попросил его сформулировать, в чем проблема масштабируемости. Как только он ответит — репостну сюда.
  • Почему я больше не использую MVC-фреймворки
    +1
    что вы ответите на такое: FLUX это ничто иное как православный MVC

    Плюсану вам карму и потопаю перечитывать про FLUX и историю развития MVC.
  • Почему я больше не использую MVC-фреймворки
    +4
    По поводу мотивации Facebook в создании React/Flux/GraphQL согласен — мотивация о немасштабируемости MVC мне кажется слабоватой, чтобы переходить на GraphQL, с которым вопросов куда больше чем ответов.

    По поводу данной конкретной статьи — в том и прелесть идеи автора, что без существенного слома можно получить плюшки.

    Возможно тут дело просто в личной боли каждого. У меня за душой есть здоровенный пожилой проект, который еще не смертельно, но уже страдает от сложности. Изучая, к примеру, грядущие Angular 2 и Aurelia, я не смог увидеть, в чем они мороку с этим приложением помогут уменьшить. А пока читал оригинал этой статьи — несколько решений в голову сами собой пришли. И это без всяких переходов на новые фреймворки.
  • Почему я больше не использую MVC-фреймворки
    –1
    Как уже писал выше, если бы не было проблем с MVC, то Facebook не изобретал бы Flux и GraphQL.
    Речь же не о том, что MVC безоговорочно фигня и все — не используем. До какого-то предела сложности он отлично работает. Начиная с какого-то предела уже приходится искать альтернативы. Каждому гвоздю свой молоток.
  • Почему я больше не использую MVC-фреймворки
    +3
    Если раскидать данные по 4-м отдельным REST-эндпойнтам, то это не сильно помогает, если на front-end нужен целый граф объектов. Да, будет меньше эндпоинтов, но будет больше запросов за данными, чтобы собрать нужный граф объектов на клиенте.
    Дополнительные проблемы возникают от того, что на front end зависимости объектов друг от друга со временем рискуют стать неуправляемыми.
    Вообще про это гораздо лучше меня рассказывал Samer Buna в своем выступлении.
    Ну и как раз из-за этих проблем Facebook изначально и разработал React, Flux и GraphQL, поскольку MVC не масштабируется под их потребности
    Автору же решение Facebook в виде React и GraphQL кажется недоработанным, о чем он и говорит в статье.
  • Почему я больше не использую MVC-фреймворки
    +4
    Да. Согласен, что далеко не идеал )
    Изначально пытался писать как можно больше на русском, но мешанина из «действий», «представлений» и «представлений состояний» получалась такой, что я сам с трудом читал написанное.
    Если писать «экшен», «вью» и т.д., то те, кто не знает английский вряд ли будут сильно счастливее.
    Поэтому решил все-таки устоявшиеся термины писать на английском.
  • Почему я больше не использую MVC-фреймворки
    +7
    По поводу
    чувак звучал очень умно

    Он ученый и ему свойственна академичность. Возможно и несколько избыточная.

    По поводу
    пытается сделать очередный основанный на FRP подход/фреймворк

    Лично мне статья показалась скорее попыткой под другим углом взглянуть на MVC.
    Да, приведенный код весьма далек от идеала. Но те проблемы, которые он обозначил в начале статьи, от этого ведь никуда не пропадают. Как направление для развития своих мыслей при проектировании, имхо, статья стоит внимания. Как конечное непререкаемое решение — тут соглашусь с вами, не стоит.