Мы в Хекслете учим людей программировать, но стараемся хитрить: например, под видом простого, на первый взгляд, курса по PHP, рассказываем людям про абстракции, рекурсии, функции первого класса, замыкании, свертку и вообще начинаем «Основы программирования» с МИТ'шного СИКПа, а не с классов и формочек. В этом и других курсах, а также в наших регулярных вебинарах рассказываем о функциональном программировании, о проблемах современных подходов и о главном зле: состоянии. В нашем чате постоянно поднимаются крупные дискуссии, в которых выясняется, что изменяемое состояние в разы повышает сложность в системе.
Сегодня мы публикуем перевод статьи, в которой Пиотр Солница, один из создателей популярного DataMapper для Ruby, рассуждает в подобном ключе о взаимодействии с базой данных.
* * *
Я продвигаю функциональный подход в Ruby уже давно, и, хотя он включает в себя много различных методов и моделей, есть одна идея, одна фундаментальная идея, которая меняет всё: неизменяемость (иммутабельность).
Но что это вообще означает в Ruby? Запретить изменять любые объекты? Будет слишком медленно, так что — нет. Иммутабельно-ориентированный дизайн означает, что вы избегаете те интерфейсы, которые могут изменять объекты. Да, много методов в Руби изменяют состояние, но когда вы разрабатываете интерфейсы объектов, вы можете создавать их таким способом, что объекты не будут изменяться.
Использование неизменяемых объектов стало для меня шокирующим открытием. Одна из вещей, которую я понял после того открытия, это почему object-relational mapping (ORM) — плохая идея, и из-за нее у нас так много ненужной сложности.
Я был пользователем различных ORM около 10 лет, что включает в себя ~2 года в рабочей группе проекта Data Mapper и ещё ~2 года в попытках построить новую версию, которая должна была преодолеть все препятствия модели Active Record. Я увидел их снаружи, я увидел их изнутри, и больше не хочу иметь дело с ORM. С меня хватит.
Я забил на ORM.
Сложность
При создании программного обеспечения нам нужно фокусироваться на минимизации сложности, насколько это возможно.
Object-relational mapping — не что иное, как слой дополнительной сложности, которая существует только потому что мы хотим, изменять объекты и хранить их персистентно в БД.
Одна из основных идей ООП это использование абстракций, которые представляют концепции из реального мира и дают возможность легче объяснять свой код, легче понимать его. Мы надолго застряли с этой концепцией, так что многие люди уже почти не способны увидеть что-то за её пределами.
Но можно создавать свои объекты так, что будет легко разбираться что происходит, и не иметь дело с «пользователем, который меняет свой адрес» или «списком, в который добавляется товар». Вместо того, чтобы создавать объекты, которые представляют сущности вроде пользователя или порядкового номера, старайтесь подумать о том, как моделировать бизнес-транзакции, предметно-ориентированные процессы.
Подсказка: осознайте, что все можно смоделировать в виде функции, которая просто преобразует данные.
Потеря соответствия
Сложность, которая стоит за ORM, вызвана тем, что мы называем несоответствием объектной и реляционной модели. Это задача безумно сложная, потому что существует множество различных моделей баз данных и много различных способов представления объектов.
У вас есть два варианта:
- Согласиться на маппинг один-к-одному между моделью базы данных и вашими объектами.
- Использовать какую-нибудь сложную систему, которая будет соединять представление объектов в базе данных с представлением объектов в памяти.
И оба варианта ужасны.
Первый особенно страшный, и многие люди в сообществе Ruby знают почему. Потому что маппинг 1:1 плотно связывает уровень приложений с базой данных. Мы используем Active Record ORM'ы достаточно долго, чтобы понимать, насколько это усложняет наши приложения.
Что насчёт второго варианта, известного как шаблон Data Mapper? В Ruby такого нет, но еще есть люди, которые пытаются построить его. Плюс уже существуют несколько проектов, которые пытаются реализовать этот шаблон.
Реальность такова, что мы даже не приблизились к решению проблемы несоответствия объектной и реляционной модели.
Хуже всего то, что мы так и не сможем решить её. Можно лишь улучшать все по возможности, учитывая ограничения конкретного языка программирования. И в конце концов люди точно перейдут на написание SQL-запросов руками.
Базы данных не существует?
На самом деле, она существует. И это одна из самых мощных частей вашего стека. Теперь задумайтесь на секунду вот о чём:
Мы притворимся, что базы данных нет, чтобы можно было изменять объекты и хранить их персистентно.
Понимаю, всё не так, как вы привыкли. Обычно мы говорим о замечательных штуках вроде «грамотной абстракции, где наша база данных становится деталью реализации» или «будет проще менять базы данных» или «объекты отделены от базы данных, так систему построить проще» и так далее.
Но к чему на самом деле всё сводится? «Я хочу изменять объекты и хранить их персистентно».
Что если я скажу вам, что вы можете отделить логику предметной области от деталей персистентности, и в то же время, избежать всей сложности, которая сопутствует ORM и изменяемым объектам?
Два волшебных слова: функции и типы данных.
Пользователя не существует
User'а не существует, Order'а не существует
Не существует ActiveProductShippingContainerHolyMolyManager'а.
Есть только клиент, отправляющий запрос на сервер. Запрос содержит данные, которые сервер использует, чтобы превращать их в ответ.
Самое близкое, чем мы можем смоделировать это взаимодействие — функция, которая принимает ввод и возвращает вывод. На самом деле, это всегда группы функций, которые в итоге возвращают ответ.
Как только вы увидите это, не будет никакой необходимости придумывать неудобные абстракции, которые мы городим для иллюзии комфорта.
А что с данными? Данные означают сложность, поэтому мы скрываем это за объектами, верно? Вот только это никогда не работает так, как в
Винегрет из данных с беспорядочным и непредсказуемым поведением — вот что такое ORM.
Но как так? Почему?
Беспорядок возникает потому, что мы не можем точно определить, с какими типами данных наше приложение имеет дело. Мы с удовольствием передаем сырые входные данные прямо в слой ORM и надеемся на лучшее. Непредсказуемость появляется потому, что объекты мутабельны, а с мутабельностью приходят трудно предсказуемые побочные эффекты. Побочные эффекты приводят к багам.
Представьте, что вы можете определить тип данных для пользователя, и этот тип гарантирует невозможность невалидного состояния. Представьте, что вы можете передать этот тип данных из одного места в другое, получить ответ и не беспокоиться о побочных эффектах. Вы видите куда я веду, да?
Использование функций и типов данных — более простой и более гибкий подход к моделировании взаимодействия клиент-сервер, чем любая типичная объектно-ориентированность с изменяемыми объектами.
Не существует User'а, но, скорее всего, есть SignupUser. Нет Order, но вы определённо столкнётесь с PlaceOrder. А когда увидите классы, заканчивающиеся на Manager — просто убегайте.
Какой у нас есть выбор?
Я считаю, что одно из самых глубоких заблуждений современного ОО-мира это:
«Мне нужен ORM, потому что я использую объектно-ориентированный язык»
Неужели? На самом деле — нет! Что вам нужно, так это способ получать данные из базы данных и уровня преобразования данных, чтобы легко преобразовывать типы данных предметной области в типы, совместимые с персистентностью.
Это избавит от кучи ненужных абстракций, которые появляются в типичных ORM.
Вы по-прежнему можете использовать объекты при моделировании взаимодействия между клиентом и сервером, но нет необходимости иметь дело с изменяемыми объектами.
Объектно-ориентированные языки, которые поддерживают такое, проживут дольше.
Мой стиль программирования на Руби резко изменился за последние несколько лет. Избавление от ORM было одним из лучших решений, которые я когда-либо принял. Поэтому я работаю над Ruby Object Mapper и рассказываю об этом на конференциях. Возможно это против общепринятого мнения, но когда что-то общепринятное и привычное постоянно подводит тебя, то нет никаких причин продолжать углубляться в проблемы. Не хочется знать насколько глубоко можно залезть.
В реальности сообщества функциональщиков уже впереди своих ОО-коллег. Лучшее, что мы можем сделать, это понять, какие крупные парадигмы из мира функционального программирования мы можем взять и применить к нашему объектно-ориентированному коду, чтобы получить выгоду. Для меня это — отказаться от ORM и изменяемых объектов.
Откажитесь от ORM. Примите неизменяемо-ориентированный дизайн. Он работает лучше.
Перевод: Наталия Басс
Комментарии (57)
saggid
18.11.2015 12:30+13То чувство, когда ты уже лет пять используешь в своей работе ORM, и за всё это время только больше полюбил его, и вдруг видишь какую-то статью, в которой говорится, что всё это неправильно и не работает. Серьёзно чтоли?) Как я жил-то все эти годы?)
В итоге, автор этого ROM'а всё равно приходит к созданию всяких TasksRelation-классов в своём туториале для получения нужных данных из определённой таблицы в БД. Разница-то совсем небольшая…asm0dey
20.11.2015 10:37Особенно весело такие статьи должно быть читать создателям суперуспешных ORM'ов типа hibernate и SQLAlchemy.
LighteR
18.11.2015 13:20+12Я совершенно не понял что хотел сказать автор в этой статье. Посмотрел его код. Автор написал еще одну orm, назвал это не-orm, и объявил все остальные orm неправильными.
torrie
18.11.2015 13:46+5Не согласен с автором. Использую Django ORM(py) на всех проектах и ужасно доволен. Проектирование бд — несколько минут, все запросы через ООП — не задумываюсь вообще.
first_oleg = Users.objects.filter(name__contains='Олег').sort_by('-date')
ООП — не панацея. Это упрощение/улучшение читабельности/ускорение разработки. По факту в ORM те же Select'ы просто оборачиваются оболочкой и мы передаем в функцию переменные и что с ними делать.
Am i wrong?jrip
18.11.2015 14:04+4>Am i wrong?
Ну чутка да, это далеко не всегда именно ускорение разработки, временами нужно писать всякого сильно больше.
Однако если хотябы частично делать всякое правильно, то это упрощает поддержку кода, уменьшает количество багов и позволяет новым или сторонним разработчикам быстрее включиться в разработку. Ну типа когда дофига разных таблиц и хитрых связей между ними можно это все дело не держать особо в голове. А еще есть хайлоад, а там вообще все не так однозначно.
norguhtar
19.11.2015 08:34+3Только не говорите мне что вы базу генерите из объектов :)
LighteR
19.11.2015 12:47-2А что в этом такого?
jrip
19.11.2015 12:54+1Как вариант в том, что в таком случае классическая реляционная бд как бы не нужна.
VolCh
19.11.2015 13:07Всё хранить в памяти? Или, прости господи, в Монге? )
jrip
19.11.2015 13:34Я написал «как вариант», суть в том что странно использовать навороченную бд и использовать 1% ее функционала, как обычно бывает в довольно большой части случаев, при этом писать прокладку, которая абстракции разворачивает в классические таблицы.
А что вам так Монга не нравится?)VolCh
19.11.2015 19:59Использовать навороченные СУБД приходится потому, что по какому-то странному сочетанию обстоятельств, навороченные ещё и примитивные задачи решают лучше, чем ненавороченные.
Неприятный личный опыт.
maxru
19.11.2015 13:21-1Выбор СУБД к генерации схемы из объектов никаким образом вообще не относится.
jrip
19.11.2015 13:37Что вы имеете ввиду? Что пофиг для чего схему генерить для pg или mysql?
Или про то что у вас есть волшебная генерилка схем для любых объектов и для любых хранилищ?maxru
19.11.2015 15:39Что пофиг для чего схему генерить для pg или mysql?
Да
есть волшебная генерилка схем для любых объектов и для любых хранилищ
Не для любых хранилищ.
Doctrine умеет в монго и достаточно большой список реляционок.
jrip
19.11.2015 19:32>>Что пофиг для чего схему генерить для pg или mysql?
>Да
Тут надо было написать «спасибо кэп», но самое смешное, что если писать свою генерилку, то уже не так все однозначно.
>Doctrine умеет в монго и достаточно большой список реляционок.
Есть опыт на доктрине поднимать успешный проект где 500+ различных типов сущностей, между ними пара тысяч связей, при этом чтение/запись 50/50 и запросов к сущностям по десятку тысяч в секунду и более? Поделитесь, думаю будет многим интересно.
maxru
20.11.2015 14:24что если писать свою генерилку
Что есть «своя генерилка»?
Есть опыт на доктрине поднимать успешный проект где 500+ различных типов сущностей, между ними пара тысяч связей, при этом чтение/запись 50/50 и запросов к сущностям по десятку тысяч в секунду и более?
Что есть «успешный проект»?
Нет, такого опыта нет, но не думаю, что это будет большой проблемой при грамотном архитектурном решении (опять же, использовать doctrine orm или нет — это чистая архитектурка, для сферического «успешного проекта» в вакууме я ничего сказать не могу)
LighteR
23.11.2015 11:27Это как вы такой вывод сделали?
В чем, по-вашему, принципиальное различие между хранением схемы в виде sql ddl кода и orm нотации?jrip
23.11.2015 11:33>Это как вы такой вывод сделали?
Из сугубо практического опыта.
>В чем, по-вашему, принципиальное различие
Странный вопрос, ну банально же, sql это sql а orm нотация такая как захотите :DLighteR
23.11.2015 11:53И как же использование orm нотации автоматически делает ненужными возможносности классических РСУБД? Какая, по-вашему, связь между способом описания схемы данных и, например, необходимостью иметь транзакции?
jrip
23.11.2015 13:22Во-первых я написал «как вариант», это сильно отличается от какого либо категоричного заявления.
И как я писал выше, в большинстве случаев там где есть генерация и тд — используется минимум всех возможностей субд, и использование субд выглядит странным и неоправданым, т.к. на данный момент существует огромное множество различных хранилищ на любую вкус цвет и запах.
> Какая, по-вашему, связь между способом описания схемы данных и, например, необходимостью иметь транзакции?
У вас очень странные вопросы, из серии «какая по вашему связь между теплым и зеленым», я не знаю какой вы ответ хотите увидеть.LighteR
23.11.2015 13:54в большинстве случаев там где есть генерация и тд — используется минимум всех возможностей субд
Это смотря что вкладывать в понятие «минимум всех возможностей субд». С таким же успехом можно заявить, что большинство проектов использующих только raw sql используют минимум возможностей субд. Непонятно как это относится к обсуждаемой теме.
У вас очень странные вопросы, из серии «какая по вашему связь между теплым и зеленым»
Ну собственно изначальный посыл, что если используется генерация ddl, то вам не нужна РСУБД как раз и есть про «теплое и зеленое».
norguhtar
19.11.2015 13:53Напоминаю ORM является текущей абстракцией и стоит идти от меньшего к большему, а не наоборот. Да и по хорошему сначала проектируем БД, а уже потом делаем объекты. Иначе можно больно наступить на грабли :)
jrip
19.11.2015 14:19>Напоминаю ORM является текущей абстракцией и стоит идти от меньшего к большему, а не наоборот.
>Да и по хорошему сначала проектируем БД, а уже потом делаем объекты.
Ну как бы что получается, у нас есть бизнес процессы, мы знаем какие для него нужны абстракции. Но. у нас есть база и у нее есть ограничение, поэтому мы пытаемся создать базу, ориентированную на бизнес, в результате получаем странные абстракции в коде.
С другой стороны можно создать годные абстракции в коде и подумать о их хранении позже, тогда получается некая монструозная прокладка, т.к. в классическую бд их просто так положить не получается.
Вот автор статьи и пишет в целом про то что ОРМ это какая-то хренотень в результате и что не надо парить мозг, все равно идеально не получится.norguhtar
19.11.2015 14:34Ну как бы что получается, у нас есть бизнес процессы, мы знаем какие для него нужны абстракции. Но. у нас есть база и у нее есть ограничение, поэтому мы пытаемся создать базу, ориентированную на бизнес, в результате получаем странные абстракции в коде.
Если у вас получаются странные абстракции в коде, то вы явно как-то не так спроектировали БД.
С другой стороны можно создать годные абстракции в коде и подумать о их хранении позже, тогда получается некая монструозная прокладка, т.к. в классическую бд их просто так положить не получается.
Обычно получается не монструозная прокладка, а весьма тормозная схема, которую СУБД прожевывает с трудом. В итоге приложение жрет больше ресурсов чем надо и работает медленно. Так-как не были учтены особенности СУБД. Из-за этого кстати был рост популярности NoSQL решений. Там типа такой проблемы нетjrip
19.11.2015 14:59>Если у вас получаются странные абстракции в коде, то вы явно как-то не так спроектировали БД.
Не всегда получается бизнес-процессы ужать в рамки БД, мир он как бы не идеальный. А проекты бывают еще и очень большими с точки зрения типов сущностей данных.
>Обычно получается не монструозная прокладка, а весьма тормозная схема, которую СУБД прожевывает с трудом.
Тормозная схема получается если тупить. Если же все делать учитывая возможности (особенности в целом уже мелочь) СУБД, ну хотя бы банально знать о том что такое индексы и знать что не все запросы одинаковы быстрые, то как раз, через учет этого прокладка в большом проекте может стать монструозной.
>Из-за этого кстати был рост популярности NoSQL решений. Там типа такой проблемы нет.
NoSQL они как бы разные бывают, я бы не стал так категорично решать что рост их популярности связан с этим.
Вот можно взять абстрактную задачу с системой, в которой есть множество документов, с различными наборами полей. Ее реально намного проще и дешевле реализовать, на Монго, чем например на MySql
norguhtar
19.11.2015 15:30Не всегда получается бизнес-процессы ужать в рамки БД, мир он как бы не идеальный. А проекты бывают еще и очень большими с точки зрения типов сущностей данных
Честно скажу, если не ужимается, то у вас что-то не так с формализацией.
Тормозная схема получается если тупить. Если же все делать учитывая возможности (особенности в целом уже мелочь) СУБД, ну хотя бы банально знать о том что такое индексы и знать что не все запросы одинаковы быстрые, то как раз, через учет этого прокладка в большом проекте может стать монструозной.
В том то и фишка, что как только все это вы начинаете учитывать, становится проще начать проектирование решения с базы данных :)
NoSQL они как бы разные бывают, я бы не стал так категорично решать что рост их популярности связан с этим.
Это один из факторов. Типа зачем учить эту скучную теорию работы с РСУБД если можно взять и просто положить объект как он есть?
Вот можно взять абстрактную задачу с системой, в которой есть множество документов, с различными наборами полей. Ее реально намного проще и дешевле реализовать, на Монго, чем например на MySql
Ровно до того момента, как вам потребуется построить аналитику или сделать отчеты. Плюс очень часто встречаются ошибки при проектировании, а ошибиться там весьма просто и внезапно выбор NoSQL перестает вывозить.jrip
19.11.2015 19:24>Честно скажу, если не ужимается, то у вас что-то не так с формализацией.
С формализацией чего? бизнес процессов? В том то и дело, что в сложных случаях либо база красивая, но абстракции в коде не очень, либо абстракции годные, но в базе их сложно хранить и если в таких случаях использовать какой-то полу-универсальный ОРМ может начаться треш и угар.
>В том то и фишка, что как только все это вы начинаете учитывать,
>становится проще начать проектирование решения с базы данных :)
И у вас особенности базы данных начинают влиять на архитектуру проекта, далее на его бизнес процессы, а далее как часто бывает манагер слышит «ой блин, это нереально переделать»
>Типа зачем учить эту скучную теорию работы с РСУБД если можно взять и просто положить объект как он есть?
Чего там учить? Основ в виде тонкой книжки, которая читается за вечер хватает на 95%+ задач, давай те уж друг перед другом не будем выпендриваться тем как сложно жить программистам :)
>Это один из факторов.
ну так да, однако сначала вы сказали что «Из-за этого кстати был рост», слишком категорично вообщем
>Ровно до того момента, как вам потребуется построить аналитику или сделать отчеты.
Аналитика отчеты это статистика? Ну ее как бы и хранить нужно в каких-нить колоночных субд.
>Плюс очень часто встречаются ошибки при проектировании,
>а ошибиться там весьма просто и внезапно выбор NoSQL перестает вывозить.
Пример хоть приведите, а то както получается по вашим словам что в noSQL все так круто и нет ошибок которые потом оборачиваются принудительной эпиляцией разных частей тела. А вообще я не за noSQL, не надо меня убеждать что оно не очень, мне пофигу, юзаю когда считаю что подходит больше чем всякое другое.norguhtar
20.11.2015 07:23В том то и дело, что в сложных случаях либо база красивая, но абстракции в коде не очень, либо абстракции годные, но в базе их сложно хранить и если в таких случаях использовать какой-то полу-универсальный ОРМ может начаться треш и угар.
А тут уже выбираем что нам шашечки или ехать.
И у вас особенности базы данных начинают влиять на архитектуру проекта, далее на его бизнес процессы, а далее как часто бывает манагер слышит «ой блин, это нереально переделать»
Вот ни разу не было. И обычно если хотят что-то такое что вот в базу ложится только со скрипом, то что-то в запросе не так и часто можно предложить как сделать лучше.
Чего там учить? Основ в виде тонкой книжки, которая читается за вечер хватает на 95%+ задач, давай те уж друг перед другом не будем выпендриваться тем как сложно жить программистам :)
Окей что такое третья нормальная форма Бойса-Кодда? :)
Аналитика отчеты это статистика? Ну ее как бы и хранить нужно в каких-нить колоночных субд.
Это все прекрасно. Но данные то вы откуда выгружать будете?
Пример хоть приведите, а то както получается по вашим словам что в noSQL все так круто и нет ошибок которые потом оборачиваются принудительной эпиляцией разных частей тела.
Да легко habrahabr.ru/post/231213
velvetcat
18.11.2015 14:52+4Не хватает примеров. А то, что я представил сам, на революцию не тянет и вообще выглядит как костыль.
AlexLeonov
18.11.2015 15:46+4>>Откажитесь от ORM.
Откажитесь от тех, кто призывает вас отказываться от чего-либо, потому что не смог понять это.VolCh
18.11.2015 19:39+2Если что, автор разработчик одной из популярных ОРМ — он не смог понять, что разработал?
jrip
19.11.2015 12:35+3Если некто, возможно умный и популярный в некоторых кругах, написал хрень она от его умности и популярности менее хренью не станет.
Впрочем хрень тут вообщем-то в деталях и если некоторые термины заменить несколько другими, то смысл и эмоциональная составляющая поменяются.
Возможно не правильное понимание автора из-за перевода, похорошему надо бы почитать оригинал, ну тем кому еще не надоело решать надуманные проблемы.
maxru
19.11.2015 13:33-1А можно узнать, какой именно?
Для ruby, насколько я помню, ORM уровня Doctrine ещё не запилили (хотя прогресс с DataMapper'ом есть, не спорю).jrip
19.11.2015 13:40Статью еще не прочитали сразу в комментарии?)
>Сегодня мы публикуем перевод статьи, в которой Пиотр Солница, один из создателей популярного DataMapper для Ruby
Ну там и ссылка естьmaxru
19.11.2015 15:15Как уже писали, если ActiveRecord назвать DataMapper, он не станет от этого DataMapper'ом.
AlexLeonov
19.11.2015 13:44Doctrine — это как бы не совсем ORM. А точнее — далеко не только ORM. Это полноценный EntityManager.
maxru
19.11.2015 15:34Не скажу, что полноценный, ManagerRegistry там существует только в виде интерфейса :)
youlose
19.11.2015 16:08А давайте хотя бы приблизительно сравним. Что есть(или удобнее) в Doctrine, чем в activerecord?
VolCh
22.11.2015 13:22Объекты модели — обычные объекты языка, которые ничего не знают о каких-то там базах данных и даже о своей персистентности в принципе. Объектный граф формируется из БД и(или) сохраняется в БД абсолютно прозрачно для модели (или вообще вне потока её управления, или прозрачно проксируя обращения объектов модели к другим объектам). Это позволяет:
1) легко добиться от объектов модели единственной ответственности — бизнес-логики (с активрекорд их всегда минимум две — бизнес-логика и логика хранения), что улучшает архитектуру, упрощает тестирование и рефакторинг, и т. д., и т. п.
2) максимально изолировать бизнес-логику от прикладной логики (логики хранения), от ограничений РСУБД, фреймворка, ОС и т. п. (в идеале, на практике абсолютной изоляции не получается хотя бы из-за ограничений самой Доктрины, например одна сущность не может мапиться на несколько таблиц, если не использовать наследование на уровне модели и объединения на уровне РСУБД), что делает их максимально портабельными между приложениями и(или) средами (скажем, при разделении приложения на сервисную и клиентскую часть модель можно просто выделить в общую библиотеку, которой будет оперировать и сервис, и клиент, причём клиент вообще ничего о базе данных знать не будет — она будет спрятана за интерфейсами сервиса, для activerecord надо будет создавать две версии модели и поддерживать их в синхронизированном состоянии).
Это только навскидку.
VolCh
18.11.2015 20:54+1Есть только клиент, отправляющий запрос на сервер. Запрос содержит данные, которые сервер использует, чтобы превращать их в ответ.
Но у сервера есть состояние, и есть запросы запрашивающее его, а есть запросы изменяющие его состояние. Функция же по определению ничего не меняет.jrip
19.11.2015 12:39> Функция же по определению ничего не меняет.
Как-то не сильно понятно, что вы этим сказать хотели. Функциональщики пишут проги которые могут только читать?VolCh
22.11.2015 13:57Функциональщики пишут проги, где максимально используют функции, но, как правило, совсем без команд на изменение (процедур) обходиться у них не получается, и тогда они плачут горькими слезами. Но самое большое зло — процедура, выглядящая как функция, то есть вроде бы возвращающая разумный результат каких-то вычислений, но под капотом что-то изменяющая так, что дальнейшее поведение системы будет от этого изменения зависеть.
jrip
23.11.2015 11:39Возможно я вас не до конца понял, но мне кажется вы не правы.
Функция вполне себе может получать нечто, изменять это и возвращать наружу, собственно оно так обычно и происходит. Скатываться при этом до процедур обычно необходимости нет. Если же применительно к хранилищам, то там может быть что-то вроде такого: collection->get()->map()->save(); Собственно вроде как мы что-то поменяли, однако в целом все понятно.
ShadowsMind
19.11.2015 00:57+1Из того что приходилось использовать для работы с БД само понравился подход Slick(http://slick.typesafe.com/)
jrip
19.11.2015 14:27Работал с ним немного, могу ошибаться, но временами оно неконтроллируемо порождает кучу неоправданных запросов. Также трудно прозрачно контролировать сами запросы на тему производительности.
norguhtar
19.11.2015 08:35+2Открыл ссылку типа вот смотрите мой НЕ-ORM. Посмотрел увидел ORM не понял про что он. Ну да ORM текущая абстракция, про это просто надо знать и все.
symbix
19.11.2015 10:08+11. Пишем реализацию паттерна ActiveRecord, о проблемах которого исписаны сотни листов еще в девяностых
2. Называем это DataMapper, чтобы никто не догадался
3. Заявляем, что реализаций паттерна Data Mapper на Ruby нет, и Ruby Object Mapper не существует
4. Объявляем известные проблемы AR фундаментальными проблемами ORM
5. ???
6. Не знаю, в чем профит.jrip
19.11.2015 12:45Есть мнение, что если читать перевод чьей-то блогозаписи в переводе на другом ресурсе, не зная толком кто есть автор, то можно не понять над чем этот автор стебается.
symbix
20.11.2015 00:09Я читал в оригинале. :)
Удивительно, как автор при своем опыте не понимает, что такое ORM, или зачем-то делает вид что не понимает.
ORM — это все, что угодно, делающее двусторонний маппинг данных из РСУБД на объекты.
Хоть бы даже вручную написанный.
jrip
Дежавю. Лет семь назад такое про PHP писали, ну прям один в один.
p.s. Откажитесь от советчиков отказываться. Пишите код.