O/RM — это все равно что добавить в базу данных повреждение мозга

O/RM — это искусство вставлять квадратный колышек в круглое отверстие. Ваша база данных SQL основана на записях и отношениях, а объекты основаны на ООП. ООП — это не более чем массовый психоз разработчиков программного обеспечения, позвольте мне добавить. Однако, игнорируя тот факт, что ООП по сути уничтожило все хорошее, что было в этом мире, O/RM все еще является мусорной технологией сама по себе, и вся идея «отображения объектов на записи базы данных» должна быть прекращена. Потому что в конце концов O/RM — это все равно что добавить повреждение мозга в вашу базу данных.

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

class Customer
{
   string Name;
   string Address;
   string PhoneNo;
}
Вход в полноэкранный режим Выход из полноэкранного режима

Представьте, что Джон и Джейн одновременно работают над одним и тем же объектом. Джон обновляет Address клиента, а Джейн обновляет PhoneNo клиента. Они оба начали работать над объектом одновременно и поэтому «извлекли» объект из базы данных. Джон обновляет поле Адрес и нажимает кнопку «сохранить». Джейн обновляет поле PhoneNo и нажимает «сохранить». Поскольку Джейн получила объект клиента из «хранилища» до того, как Джон сохранил его, поле Address возвращается к своему старому значению, которое оно имело до того, как Джон обновил его. Это называется «условием гонки». Потому что тот, кто сохранит объект последним, «победит».

Для решения вышеописанной проблемы требуется так называемый механизм блокировки базы данных. SQL Server, например, решает эту проблему, позволяя пользователям создавать столбцы RowVersion в таблицах. Это называется «оптимистической блокировкой» и имеет тенденцию распространяться на графический интерфейс пользователя, приводя к негерметичности абстракций, требуя от разработчика добавлять тонны мусорного кода в свой слой графического интерфейса, чтобы убедиться, что объекты действительно сохраняются, когда пользователь пытается их сохранить.

Существуют различные версии техник блокировки записей в базе данных, но все они, по сути, мусор, и требуют тонны мусорного кода для распространения, вплоть до пользовательского интерфейса и человека, фактически редактирующего записи. Теперь вы остаетесь с программным «решением», в котором что-то столь фундаментальное, как обновление одного поля в одной записи базы данных, может не сработать, заставляя конечного пользователя «вернуть» свои изменения и «перезагрузить» исходный объект. 25% вашего кода теперь является защитным кодом, пытающимся предотвратить применение пользователем условий гонки к вашим данным, и этот мусорный код проникает из вашей базы данных, через промежуточное ПО, в пользовательский слой вашего приложения.

Игнорирование того факта, что 98% разработчиков программного обеспечения даже не знают, как применять блокировку записей базы данных, и просто игнорируют ее, что приводит к появлению мусорных данных в вашей базе данных — Даже если вы примените «идеальный» код, защищающий такие сценарии, вы все равно получите мусорный код, где что-то столь же фундаментальное, как изменение записи в базе данных, может привести к тому, что перед конечным пользователем появится модальная форма.

«Мы не смогли сохранить ваш объект, хотите ли вы сохранить его принудительно, перезагрузить исходный объект или отменить?».

Большинство конечных пользователей даже не поймут, что здесь делать, и, вероятно, просто позвонят по болезни, оставшись дома до конца недели — Или побеспокоят какого-нибудь технического специалиста, которому понадобится час, чтобы просто выяснить, почему объект не может быть сохранен. Следовательно, использование O/RM в слое базы данных приводило к тому, что конечный пользователь терял половину своего дня, не имея возможности выполнять свою работу.

У нас есть слово для этого, и оно называется безумием!

Большая шутка

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

update customers set Address = 'xyz' where ...
Вход в полноэкранный режим Выход из полноэкранного режима

Затем представьте, что изменение Джейн привело к следующему.

update customers set PhoneNo = 'xyz' where ...
Войти в полноэкранный режим Выйти из полноэкранного режима

Все буквально так просто. Теперь вы устранили все источники потенциальных условий гонки. Вам больше не нужна блокировка, и вы можете, по сути, SHIFT+DELETE 25% вашей кодовой базы, в итоге получив на порядки более безопасный код. Больше никакого «кода синхронизации» в слое пользовательского интерфейса, промежуточном ПО или базе данных.

Технически это называется «нарезка записей» и подразумевает частичное обновление записей. Однако это принципиально несовместимо с лучшими практиками паттернов проектирования O/RM, такими как Active Records, Repository Pattern и т.д. и т.п. Я понимаю, что некоторые O/RM библиотеки реализуют эту технику нарезки, но тогда вы больше не используете вашу O/RM библиотеку как O/RM библиотеку, а скорее как плохо реализованную замену SQL, и она становится ужасно реализованным функциональным языком программирования, с неоптимальным слоем сериализации базы данных, нарушая все «лучшие практики», которым вас учили, когда вы начинали использовать O/RM библиотеки. Причины, по которым это невозможно реализовать в O/RM без нарушения лучших практик ООП, можно описать следующим образом…

Можно мне половину вашего объекта, пожалуйста?

Когда это сформулировано так, как описано выше, это легко понять. ООП основано на классах и сильной типизации. Предоставление «половины объекта» в ООП просто не имеет смысла и буквально невозможно. Следовательно, если вы хотите применить нарезку записей в вашем О/РМ, вы больше не используете ваш О/РМ как О/РМ, а скорее что-то другое, и вы больше не используете ваш язык ООП как ООП, а скорее как плохо реализованный функциональный язык программирования.

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

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

  • Зарегистрируйте бесплатный Low-Code генератор CRUD бэкенда здесь

Оцените статью
devanswers.ru
Добавить комментарий