Pull to refresh
5
0
Владислав Килин @Quilin

.net разработчик

Send message

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

if (x is not null but y)


Шутка.
Используется ли у вас в компании DDD подход в разработке, и если используется — насколько он заменяет собой BDD подход, и если не особо — то почему?

Пробовал его и не понравилось, но сейчас в доках вижу что-то новое. Спасибо, попробую.

Сотни строк данных это не самый большой объем, вообще говоря.
Я на своем петпроекте обычно держу в состоянии приложения только срез данных. Например, если у меня есть табличка с юзерами, то подгружается она постранично, и если из вебсокетов приходит сообщение об изменении пользователя (например, он вошел в сеть), то в хранилище вносятся изменения только если пользователь есть на этой условной странице.
Аналогично ведется работа с другими многочисленными сущностями — комментариями, новостями итд. Приложение и его стор не должны превращаться в копию бд на клиенте.
Недавно перевел средних размеров проект (страниц штук 40, своя библиотека базовых компонентов) на тайпскрипт и стайлус. Ничего особенно сложного, а поддержка тайпскрипта вполне бодрая.
Единственное что меня как олда подбешивает — это отсутствие хоть одной удобной тулзы для валидации форм. После, простите, jquery.unobtrusive.validate все выглядит громоздким и при этом черновым.
Я бы еще добавил — сразу используйте тайпскрипт.

Боюсь, помимо отображения вам еще понадобится само множество

О, круто, спасибо! Надеюсь, в новом подходе им нашлось место.
1. Названия полей json — это типа «тайпчеки для самых маленьких». В декларациях типа xml/grpc и даже в swagger.json есть возможность указать явно, что вот эта строка — это uuid, а эта — дата в формате ISO, тут любое число, а здесь — беззнаковое целое. И по-хорошему нужно проверять на стороне «бэка», что вы отдаете в верно проименованных полях верного типа данные. И, конечно, я вообще молчу про глубокие объекты с массивами и прочим.

2. Мы говорили о константах для перечислений состояний. Например, у вас есть поле Status, где хранится число — логично, экономно. Числа никто не помнит, если их больше двух, а хранить строки для такого служебного поля — оверкилл. Держать в конфигурации информацию о том, что 1 — это подписка на поздравление с днем рождения, а 21 — на новости о новых фичах — крайне плохая идея, как минимум потому, что сценарий «вот на этом инстансе пожалуйста пускай будет наоборот» становится возможным, но не перестает быть идиотским.

Или под «конфигом» вы понимаете еще одну таблицу в БД?

Уточню, что в моем примере выше использовалась фича языка C# под названием Enum — там можно создавать компайл-тайм константы с привязками к целочисленным значениям, которые спокойно приводятся туда-обратно, но при этом дают возможность на этапе компиляции требовать не 1 или 21, а Subscription.Birthday или Subscription.NewFeatures. Это к вопросу о выразительности и удобстве скуля.

3. Повторю вопрос — каким конкретно образом вы ограничиваете использование таблиц в хранимках? Вы лично бдите за этим? У каждого разработчика есть чеклист? Используется какой-то глобальный тест? Что, если хранимок с данной таблицей уже 10, а мне ну очень нужно сделать новую фичу с ее использованием? А если хранимок уже 12 при этом?
Изменение структуры хранения данных — это вряд ли вообще рефакторинг, но даже если и относить это туда, это не единственный вариант. Речь идет скорее о том, что вдруг в какой-то udf вы поняли, что ух — контракт неудобный, опечатка в поле возвращаемого параметра или «нам нужны монады!» В строго типизированных языках есть целые чудесные инструменты, вплоть до того, что переименование поля возвращаемого значения делается одной клавишей буквально.

Разве это не локальные константы? Думаю, вопрос скорее про глобальные константы, которые будут едиными для всех хранимок во всей базе.

Каким образом вы ограничиваете количество хранимок, где используется таблица? Скажем, таблица юзеров у вас правда только в 10 хранимках встречается?
В приведенном примере еще проблемы нешутошные с типизацией возвращаемого json, не наблюдается возможности компайл-тайм проверки того, что все везде правильно отдается. Про автоматическую генерацию swagger.json или чего-то подобного речи тоже не идет.
Вот шарпы с использованием EntityFramework. Тут, кстати, настоящая защита от инъекций, можно даже анализатор написать для экранирования любых строковых констант содержащих SQL определенного диалекта. Конечно, его тоже можно обойти, но ревью это вряд ли пройдет.

return db.Subscriptions
  .Where(s => s.Status == SubscriptionStatus.Active)
  .Where(s => s.SubscriptionDate <= currentMoment)
  .Select(s => new ActiveSubscription
  {
    UserId = s.UserId,
    UserName = s.User.Name,
    Date = s.SubscriptionDate,
  })
  .ToArrayAsync();
Учитывая, что у них все-таки используется mq — технически это не одна транзакция, в зависимости от того, дергается ли хранимка на стороне консюмера.

Ну и опять же — хорошо, когда вы владеете всеми данными. А тут поскольку есть все-таки какие-то сервисы, то сценарий
1. Обновить сущность А
2. Сходить на внешний сервис за данными
3. Обновить на их основании сущность Б
либо лишится транзакционной целостности, либо поменяет местами шаги 1 и 2 и тем самым превратится в другой сценарий, где обновление сущности А условное.
В каждой хранимке оказывается логика по формированию ответа на ошибку и отправки ее в лог? Вообще вы с дублированием кода и подобными бойлерплейтами как разбираетесь? Через udf?
То есть, захотел поменять текст ошибки на фронте — запустил запрос. Примерно как я и предположил.

А эти запросы лежат в какой-то системе контроля версий? Как гарантируется консистентность нескольких баз? Грубо говоря, есть ли у меня возможность узнать, что моя бд такая же как у Пети, а у Васи — такая же как на проде?
Обычно, в компаниях, где царит плюрализм, изменения в бд делаются итерационно и хранятся в какой-то системе контроля версий. Как правило, удобно держать изменения в отдельных файлах, например, с номером версии. Поменял хранимку? Залил дельту в виде отдельной миграции, и теперь любой коллега может запросто накатить твою версию на свою среду либо вручную (не айс), либо воспользовавшись готовой тулзой. Всё-таки тянуть целый снепшот всей бд в краткосрочной перспективе не очень удобно, а вот держать для историчности хотя бы минорные и патчевые изменения в схеме базы и ее окоужении — полезная штука.

Допустим, у вас не используется этот подход. Ваше дело, хотя и странное. Получается, для изменения текста ошибки на фронте мне придется на прод выкатывать… что? В случае с миграциями, релиз будет состоять в запуске одного скрипта, который выполнит alter stored procedure, а в вашем случае релиз в чем состоит?
Да нет, вас понять очень легко как раз-таки. Статьи по хранимкам входят в топ 3 сущностей, где на хранимки можно смотреть без слез.
То есть, вы вместо монолита сделали якобы не-монолит, где для изменения текста ошибки фронта нужно выполнять миграцию бд? Это, конечно, новый уровень…
Ну например в гайдлайнах некоторых советуют использовать паттерн Deadline для распределенных таймаутов: www.datawire.io/guide/traffic/deadlines-distributed-timeouts-microservices

Но вообще несмотря на то, что Polly — это прекрасная библиотека, вам наверное стоит пересмотреть идею использовать ее для CircuitBreaker'а. Раз у вас SOA, то вы наверное используете горизонтальное масштабирование, и вряд ли вы сможете шарить состояние CB между двумя инстансами одного сервиса. Возможно, целый ряд ваших проблем с распространением ошибки решат Hystrix или Istio, но CB-то уж точно стоит туда отправить.

Information

Rating
Does not participate
Location
Санкт-Петербург, Санкт-Петербург и область, Россия
Registered
Activity