Как стать автором
Обновить
114
0
Протько Сергей @Fesor

Full-stack developer

Отправить сообщение
А причем тут agile/scrum? Хотите привлечь отдельного специалиста — привлекайте.

> не должна создаваться так рано

Тут все упирается в то сколько у вас сейчас есть денег, сколько вы можете вложить и как быстро сможете понять стоит ли оно того дополнительных вливаний средств или нет.

Если вам удалось найти специалиста и вы условились скажем в 2 недели на R&D дабы по результатам уже смотреть окупится ли дальнейшая разработка данной фичи — ну сделайте так. Если денег много и потенциальный профит перевешивает плюсы, и вы можете взять специалиста на пол года, почему нет.

Все же R&D с точки зрения планирования проще организовывать за счет фиксированных итераций, ибо оценить такие задачи адекватно невозможно. две недели ресерч, анализ результата, решение копать дальше или забить.
> творческие они, посмотри-ка!

Ну всю эту движуху что мол на конвейере у вас не совсем уж дураки стоят начали еще в 70-х и далеко не в IT. Мол, зачем надсмотрщики, выдайте людям секундамеры и ответственности о они сами будут пытаться оптимизировать свой участок работы.

Ну там всякие книжки на эту тему вроде знаменитого The Goal и всякие там книжки про безотходное производство (toyota way, lean)…
речь идет о линтерах vs нормальные тайп чекеры.

Но как контр приме можно привести скажем python, который позволяет вам определить тайпинги для всего на свете. Или flow, который справляется с этим даже лучше.

Да, в языках типа ruby все будет плохо со статическим анализом, и обычно все ограничивается банальным линтингом.
Вопрос: почему тогда разработчики субд не используют такое?

индексы как-бы примерно таким образом и работают.


Даже для сохранения в памяти они использую таблицы

Что удивительного в том что реляционная база использует реляции а не что-то другое? В целом нет никакой проблемы хранить данные в jsonb с ключем, будет та же хэшмэпа. Но только если вам прям в памяти нужно дешевле будет redis использовать. Он опять же может только ключи в памяти хранить, если вдруг у вас все в память не помещается.

Официальная наука говорит

когда говорите "наука говорит" приводите источники, иначе это вы говорите а не "наука".


модульные и функциональные

то есть модульные тесты не проверяют функциональность? Ну и интеграционные тесты не являются функциональными? Чем тогда приемочные от ваших функциональных отличаются? И можно ли делать приемочные тесты не со стороны UI?


Мне кажется, что наиболее полезный подход — что-то среднее между этими двумя.

Мне нравится что вы начали комментарий с фразы "наука говорит".


Они не проверяют функциональность, они проверяют, что какие-то методы были вызваны с правильными параметрами

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


слишком много знаний о внутреннем устройстве кода утекает.

Это говорит о том что дизайн нашего кода такой, что провацирует подобное. Обычно — из-за большого количества зависимостей (попробуйте перегруппировать код таким образом, что бы уменьшить количество оных).


а тестирую микросервис как black box — снаружи

Немного накину: J B Rainsberger — Integrated Tests Are A Scam

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

Возможно вам будет интересно: Ideology — там как раз рассматриваются эти точки зрения (что статическая типизация и тесты могут заменять друг друга)

Что делать, когда ты не можешь написать ни одного красного теста, так как код сейчас работает верно

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


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


но тестовые сценарии покрыты определённо не все?

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

даёт уверенность в понимании требований?

"уверенность" понятия субъективное. Суть в том что бы разработчик начал формулировать требования ДО написания кода. Если уверенности в понимании требований нет — пишите больше тестов, есть уверенность в понимании — возможно тестов уже достаточно.


У Кента Бэка в его книге про разработку через тестирование было об этом, мол длина итераций красный-зеленый-рефакторинг зависит от вашей уверенности. Ну и в целом он в своей книге пишет что это все способ борьбы со страхом внесения изменений.


Опять же, способ этот не универсален и он хорошо работает на ком-то вроде Кента Бэка, но может плохо работать для кого-нибудь другого. Ну и не для всех задач такой способ подойдет. Универсальных вещей в этом плане как бы нету.


решает проблему низкого покрытия?

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


О которых вы нам не расскажете?

Не могу говорить за VolCh но… для меня тесты в TDD это та самая "бесплатная" вещь. А главная цель для меня все же в формализации требований и проектировании интерфейсов (ибо тесты это тот же клиентский код). Тесты такие на ранних этапах будут намекать нам о связанности лишней, о том что с декомпозицией что-то не так пошло и т.д.


p.s. я не очень понимаю вашу позицию. Вы хотите затеять очередной холивар нужен ли TDD? А зачем? подход не претендует на универсальность а его плюсы, минусы и прочее разжеваны в 5-ти часовом холиваре DDH, Кента Бэка и Фаулера (Is TDD Dead). Есть еще TDD vs DbC с дядей Бобом и Джимом Копленом.


Ну либо накиньте что-то конкретное.

> по свойствам вложенных объектов.

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

> ну ORM — это все же не RDBMS

прикол то в том что если у вас есть RDBMS то ограничения этой модели будут просачиваться сквозь вашу ORM (если она общего назначения, типа гибернейта). Те же one-to-many там кастылем разруливаются, что бы эмулировать однонаправленность связи.
> Глупо с моей стороны было упускать из виду существование ORM as is

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

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

Ну и еще раз — вы сами предлагали посмотреть на вещи «по другому». Например — event sourcing вполне себе компромисный вараинт, который позволяет вам крутить вертеть вашей моделью данных как угодно.
> У меня информация от контрагентов…

Сейчас бы по одному кейсу статистику по индустрии проэцировать. Импорт данных может быть, но чаще всего это импорт части данных а не всех. Да, есть исключения, как и проекты где вообще нет bulk import.
которые отрабатываются по уже загруженным данным

и джойны там есть? Или чисто проверка условий? Ну мол реляционная алгебра это все ж чуть интереснее чем фильтрация коллекции.


Опять же — главное пожалуй отличие — отсутствие ссылок и возможности однонаправленные one-to-many связи делать (у вас на стороне many fk что делает его зависимым от one)


Ну и за счет всех этих нюансов и появляются кучи плюшек по оптимизации. А так можно просто key-value хранилище сделать и индексы строить, никто не мешает. Объектно-ориентированные базы были, сейчас вот есть документно ориентированные (или мой любимый объектно/реляционный постгресс)

На всякий случай повторю, а то может быть вы не заметили — я НЕ использую тригеры и процедуры для бизнес логики и категорически против этого на своих проектах. Опять же я категорически против так же называть ORM "решением всех проблем", есть и другие способы дела делать.


Чем меньше зафиксированных зависимостей пришлось затащить в проект — тем лучше.

Меня не покидает ощущение что мы говорим о разных вещах. Что бы небыло недопонимания, давайте так.


Вы согласны что зависимость все равно есть? А это значит что мы не можем просто поставить "другую субд" и все будет гарантировано работать, то есть может потребоваться дополнительная работа.


Ну или расскажите про свои проекты. Ибо я не могу вспомнить ни одного проекта где мы гарантировали бы стабильность работы софта при смене скажем postgres на mysql.


У вас вообще нет контроля за окружением? Коробочные решения? Десктоп? Просто это довольно важно понимать, ибо задачи могут быть чуть другие.


Я просто не очень верю в волшебное "зависимости есть но я могу махнуть палочкой и вжух уже имплементация другая". То есть да, изолировать зависимость — понимаю и согласен. Но ORM — это не про "устранение зависимости от конкретной базы", это не ее первоочередная задача. Абстракцию вы уже сами делаете (шаблон Repository например).


Что мешает работать и тем и другим параллельно?

ничего, просто два процесса. И да — формирование email-а это представление. Независимый процесс. Запускайте сколько хотите. А вот если ваш "коркер" бизнес процессы будет разруливать, то вам уже важно что бы бизнес процессы реализованные в версии 1 и версии 2 были совместимы.


Что мне мешает запустить комплект новых воркеров

А что мешает добавить код в имеющийся воркер что бы тот сам стал считать в нужный момент по другому? У вас же по любому будет какой-то код который будет принимать решение какому из воркеров трудиться когда. Или вы руками планируете переключать?


Ради суперзадачи "использовать триггеры во что бы то ни стало?"

Нет, просто я не очень понимаю зачем может понадобиться две версии одного тригера одновременно выкатывать. Два тригера. Или две процедуры. Если очень хочется.


Пример со схемами — просто говорю что есть механизмы. Если говорить не про тригеры и процедуры, а просто про схему базы, то оно вам и с ORM поможет (удобно при zero downtime. Как пример можете глянуть как вот тут делают).


Вот как раз тут через ORM все чудесно решается.

речь идет не о тех изменениях. Это про изменения логики/кода.


Через Entity lifecycle events.

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


т.к. отслеживание изменений в ORM обычно из коробки

Только если ваша ORM имеет внутри unit of work. Это маленький процент ORM и в целом они обычно очень сложные. Не ну как, если понимать что магии там нету и разбираться как оно работает)


Я в последнем проекте просто кидал сообщение в менеджер очередей

А у меня вообще event sourcing


в PostgreSQL в триггкре доступна информация о пользователе, выполнившем транзакцию

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


Скажем у меня на проекте HIPAA и мне нужно не только трекать кто чего подправил, но и кто чего посмотрел. Настолько что мол мне надо трекать кто в какое время в результате поиска каких пользователей увидел.


Подобное я ни в коем случае не буду делать ни на тригерах ни на ORM. У меня сверху подсистема которая коллектит ивентики эти и потом балк инсертом записывает.


и можно ли к каким-то внешним службам обратиться, типа RabbitMQ или Redis?

Там есть notify через который можно замутить pub/sub. Например — штуки типа postgraphile используют для того что бы апдейты на клиент в сокеты пихать.


Но они что, правда не работают в кластерах и при шардинге?

Тут больше вопрос в бизнес логики и можно ли эту логику на шарды разбить.


Опять же, у меня опыта такого тоже нет, просто из всех проектов которые приходилось видеть основной юзкейс был именно в том что бы жестко ограничивать доступ к данным (когда самое критически важное лежит процедурами, все данные жестко разбиты какими-нибудь row based security и т.д.). Ну и те же микросервисы, где можно ввести те же ограничения, уже могут выйти дороже. Но опять же всякое бывает. Иногда критически важную подсистему можно выделить отдельно и будет как бы монолит + внешняя система которая не меняется без согласования с контролирующими органами (какие-нибудь PCI DSS)

> ORM здорово тормозит на операциях bulk import

bulk import благо не самая распространенная задача. Да и для конкретного кейса можно придумать что-то поинтереснее.

В целом ORM нужны там где у вас OLTP (OnLine Transaction Processing). То есть берем чуть-чуть данных (агрегат, границы бизнес транзакции, DDD), делаем с ними что-то и записываем.

Чтение и т.д. — для этого проще делать отдельно выборки через SQL. Тут не только с точки зрения производительности сколько с той точки зрения, что модели данных для чтения и записи нужны обычно разные.

Собственно вы сами в конце про разделение представлений говорите.
ORM — она (он?) такая же реляционная как СУБД под ней.

реляционная в смысле орудует реляционной алгеброй (ну там картежи данных, предикаты) или в каком смысле вы употребляете это слово?


Должен ли это понимать джун? Я думаю да.

Понимают ли? думаю нет. Для подавляющего большинства джунов ORM это волшебная коробка которая просто работает. Более того — это довольно распространенное мнение. Вот выше тоже вещают про то что ORM это абстракция от базы. А если оно абстракция — значит про базу знать не обязательно.

но это внешний компонент

Почему? Можно ли воспринимать скажем версию JVM как "внешний компонент"?


У меня вещи типа база данных это внутренний компонент. Я поставляю код как готовую инфраструктуру (предположим через докер). И я регламентирую что нужно для того что бы код работал.


У меня был один кейс когда мне была выгодна смена субд прозрачная — у заказчика был тот самый вендор лок на оракл, и ничего другого они юзать не могли. И выяснилось это через 3 недели посте старта проекта. Но там и проект примитивный.


Так что нет, сегодня завязка на конкретную СУБД это данность на хоть сколько нибудь серьезном проекте.


Вы же не переживаете что выбрав определенный язык программирования вы как бы тоже создали себе вендор лок?


Задача ORM — реализовать слой абстракции в виде хранилища объектов с реляционными отношениями между ними.

Тогда было бы не O/RM (Object-relational mapping) а Object-Relation Abstraction какой. Задача ORM — исключительно мэппинг одного в другое. И при том что две эти модели данных (основанная на реляциях и ваши in memory структуры) сильно различаются, то и мэппинг мы можем сделать в ограниченном наборе сценариев (всему виной такая вещи как референсы, которые выражены сильно по разному)


Хм… я могу одновременно задеплоить разные версии воркеров, которые будут реализовывать разние версии API

это как UI, попробуйте такое с бизнес логикой провернуть. И не важно будет в тригерах она или в коде. Ну либо ваши две версии воркеров должны реализовывать совместимость на уровне бизнес процессов. Что как бы… можно провернуть и с тригерами.


но я не вижу способа задеплоить одновременно несколько разных версий SQL-триггрер.

Я не вижу необходимости в этом. Но вообще зависит от вашей СУБД. В PostgreSQL подобное можно хитро замутить со схемами.


А в чем тут проблемы с ORM? Вовсе не обязательно, чтобы все пользователи ходили к СУБД под одним пользователем.

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


Такое можно и с кодом провернуть (здрасте микросервисы).


Тот же Highload

Я уже упоминал тут что в хайлоад врядли тригеры и процедуры хорошо ложатся ибо вы ограничиваете себя скейлингом по вертикали. Горизонтальный уже сложнее.

сложно представить разработчика который с node работает (а на нем можно и бэк писать, и просто юзать тулы написанные и дистрибьютящиеся через npm) не знать что такое node_modules.

Ну а на тему изменения серд парти — это может намекать только на то что ваши разработчики никогда не работали с менеджерами пакетов. Что странно в наши дни.

Так что нет, это вопрос не в фулстэк/не фулстэк. Знания необходимые что бы не творить такой черни на 90% проэцируются из любых других языков.
но не данных

поясните что вы имеете ввиду. Мне кажется что для вас "расширение данных" это просто расширение структуры. Что-то типа сишного варианта:


typedef struct foo {
  int a;
} foo;

typedef struct bar {
  struct foo;
  int b;
} bar;

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


А как же неуправляемая память?

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


Ну и да — деструкторы в rust все же есть

Наследование данных

composition over inheritance и все в таком духе.


Интересный момент — даже Страуступ признает что добавление protected в плюсы было ошибкой (очень легко неявное поведение организовать, всякие LSP нарушить, контракты сломать)


А без protected стэйта мы можем ограничиться наследованием об абстрактных классов без состояния (ибо если там приватный стэйт — скорее всего лучше вообще вынести это дело как зависимость, опять же композицией/агрегацией).


Опять же, идеям "ооп" в плюсах лет больше чем это самое ООП существует (Хоар классы описывал задолго до того как Алан Кей сказал кому то что он "ООП делает")


Lisp более ОО чем C++.


виртуальные деструкторы

Именно деструкторы? И именно виртуальные?


Зачем вам деструкторы, если за вас компилятор расставит где почистить ресурсы, высвободить память и т.д.

Информация

В рейтинге
Не участвует
Откуда
Минск, Минская обл., Беларусь
Дата рождения
Зарегистрирован
Активность