All streams
Search
Write a publication
Pull to refresh
99
0

Пользователь

Send message
Очень круто.
Особенно нравится вторая демка, как наиболее реалистичное. Хотя меня больше всего впечатлило https://www.shadertoy.com/view/XdsGDB

Вообще Shadertoy настоящий кладез информации, а на сайте Inigo Quilez (если не ошибаюсь один из создателей Shadertoy) можно найти кучу очень интересных практических алгоритмов

Вы конечно правы, апрохимация в ряд Тейлора вполне может заменить синус. Он в данном случае нужен для получения просто псевдослучайного значения в любом интервале входных данных. Более того можно избавится от динамического бранчинга, если просто синус заменить на более упрощенное frac((x + x*x)/6.28) например. Но тем не менее изначальная проблема остается и увеличение скорости даже с 1 до 3 фпс сильно не поможет
Тут уже больше зависит от вас. Также эта статья может помочь пролить свет на вопрос об использовании диспетчера/шины.
И тогда возникают следующие вопросы:

1. Какую ответственность покажет фабрика? (Да и зачем для достаточно простых DTO фабрика?) То, что в контроллере используются команды/запросы? А из переданного диспетчера это будет не ясно?

2. Чем передача множества обработчиков вместе с возможными другими зависимостями, которые не относятся к CQRS, упростит чтение контроллера. Может, наоборот — усложнит? (Не считая того, что если контроллер содержит слишком много зависимостей, то, возможно, он делает слишком много, и стоит выделить дополнительный контроллер под более конкретные задачи, или же объединить часть зависимостей в одном высокоуровневом компоненте (вроде того же диспетчера)).

3. Из методов и названия контроллера не будет ясно, какие действия он производит?
Во-первых мы прибегаем к антипаттерну диктатор (по Марку Симену), когда зависимости мы создаем напрямую через new. На мой взгляд было бы уместнее использовать что-то вроде абстрактной фабрики запросов

Теперь мы вынуждены зависеть от фабрики, да и как она будет создавать объекты запросов/команд? Неужели new так плох?

Ну и в плане класса диспетчера, который по факту тоже является антипаттерном сервислокатор, он создает кажующуюся простоту контроллера. На самом деле он не уменьшает количество зависимостей ( и как следствие сложность) класса, он просто скрывает их реальное количество

Диспетчер делегирует вызов обработчиков по переданному сообщению, используется ли в нём Service Locator или нет — это не важно, он оперирует только определенным списком обработчиков. По этому поводу есть довольно интересная статья (англ.).

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

Это хоть и допустимо, но не эффективно, т.к. стоит учитывать, что количество обработчиков может быть неопределенным, тем более если речь идет о рефакторинге.
Тогда может использоваться async/await, в этом случае метод интерфейса IQueryHandler должен будет возвращать Task<>. Для браузера же особой разницы не будет, т.к. он всё так же будет ожидать ответа.

public interface IQueryHandler<in TQuery, out TResult> where TQuery : IQuery<TResult>
{
    Task<TResult> Execute(TQuery query);
}

public async Task<TResult> Execute(...)
{
    var result = await GetSomething(...);
    
    return result;
}
Вот абстракции и потекли. Не, я, конечно, за предгенерацию id, но это далеко не всегда возможно.

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

Идентификатор элемента очереди. Или вы исповедуете принцип «с моей стороны вылетело, а дальше судьба команды меня не волнует»?

Зависит от реализации.
В простом случае команда вполне может вернуть статус выполнения успешно/неуспешно.
В другом случае команда может послать событие, что создание пользователя завершилось успешно, или не успешно, если по какой-то причине выполнить команду не удалось, и затем как-либо оповестить пользователя.
Или вообще без оповещения пользователя, вызывающему коду может лишь понадобиться знать, смогла ли команда выполниться или нет, чтобы, например, попытаться её выполнить снова в случае неудачного выполнения (типа недоступности сервера для отправки email).
CQRS в этом плане выступает как основа для подобных действий.

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

Потому что БД для чтения используется для повышения производительность запросов на чтение, а не записи, в первой ссылке в источниках об этом рассказывается подробнее.
UX меняется в случае использования CQRS с разными БД или Event Sourcing.
И как потом найти свежесозданного пользователя, если команда не будет возвращать нам его id?

Генерировать Id перед созданием пользователя, если только это не автоинкремент в БД (возможные проблемы с которым уже не относятся к CQRS).

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

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

Можем. Создаём 2 соединения: из одного читаем, в другое пишем. Оба соединения могут быть легко инкапсулированы в одном субд адаптере, позволяя программисту вообще не думать о том, что у него есть 2 базы.

Если только эти БД обновляются одновременно, но обычно БД для чтения обновляется позже, через какое-то время после изменений в БД для записи, иначе в ней пропадет смысл при её частом обновлении. То есть не получится сразу после создания пользователя получить по нему данные, его просто еще не будет существовать.
То есть достаточно назвать метод «TryChangeEmail», который пытается изменить email и возвращает статус изменения, и вашей проблемы с недопониманием что делает метод не будет. Разделение на 2 метода тут не требуется.

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

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

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

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

В CQRS предлагается стремиться к тому, чтобы команда (или запрос) выполняла только строго определенную задачу, а вот сама команда уже может являться частью какой-либо бо́льшей задачи.
То есть все необходимые запросы и валидация должны быть сделаны до того, как команда начнет выполняться, и ей должны быть переданы необходимые данные. Тем самым будут иметься отдельные Query, вместо того, чтобы выполнять их в команде.
Из сравнений наиболее актуальных версий (PostgreSQL 9.5b1 и MongoDB 3.2.0) можно упомянуть доклад на PgConf.Russia 2016 где рассматриваются результаты выполнения основных операций и рассказывается, почему и при каких условиях так получилось.:)
С нетерпением ждём сравнение производительности MongoDB 3.4 и PosgreSQL 9.6!
Спасибо за комментарий, обязательно учтём в следующих публикациях!
P.S. информацию по этой теме также можно почитать на хабре.
А Вы не пробовали знаки препинания расставлять когда задание пишете? «Но для кратных трём значений «Fizz» вместо номера...» пять минут потратил чтобы понять, что же здесь хотят)
Архитектуру взаимодействия проектировали не мы. К моменту старта разработки Android-клиента уже был реализован web-клиент. Поэтому пришлось реализовывать такое решение.
Полностью согласен с одним из комментаторов. Вы удивитесь, но многие даже не слышали о том, что есть такая методология. Полноценно набирать популярность в бизнесе они начинают сейчас.
Вы пишете правильные вещи, я согласен. Но конкретно в нашем случае мы решаем эти проблемы следующим образом:
1) начало спринта. задач в тестировании нет, автотестер занимается тем, что вкручивает дополнительные фичи в проект (как пример, Allure отчеты, реализация паралелизации тестов в GRID и так далее). Либо же оптимизация кода, рефакторинг. В общем есть чем заняться.
2) конец спринта. задачи все в тестировании, либо закрыты, на разработке задач не осталось. Разработчики занимаются тем же самым. Оптимизация кода, рефакторинг, внедрение дополнительно функционала, не так ценного для бизнеса, но очень ценного технически.
3) На мой взгляд все подобные проблемы решаются грамотным планированием, пониманием, что такое Agile и правильно построенными коммуникациями.
Все зависит от целей и задач тестирования. Если под целевую аудиторию попадают сотрудники нашей компании, то мы тоже приглашаем их на тестирование.
Ещё генератор сигнала позже усилили, он стал давать более мощный сигнал, излишки забирали стабилитронами и заряжали ими ионистор. Это был дополнительный источник питания, который неплохо так прокачал автономность расходомера
Скорее всего на финальной версии схемы так все и сделано. Проекту 3 года, я точно не помню. Схемы, приведенные в иллюстрациях, рисовались в Proteus ради симуляции, они специально упрощались, чтобы не нагружать процессор
Да, все верно, если подать мощный импульсный сигнал, компаратор погибнет вместе с микроконтроллером. Мы вполне понимали это, когда ваяли схему.

Information

Rating
Does not participate
Location
Россия
Works in
Registered
Activity