Здравствуйте, Cyberax, Вы писали:
C>Которые есть часть поведения, и которые ломаются от изменения структуры данных.
Эта часть поведения очень хорошо отделяется от собственно поведения и структуры хранения, а не является неотъемлемой частью объекта, как в OODB и классических ORM.
C>Нет, просто у RDB получилась фора примерно в 10 лет, которой они воспользовались.
После этой форы прошло уже лет 20, пора бы фору и наверстать уже. К тому же, иерархические БД и тем более сетевые, в этом разрезе, мало чем отличаются от OODB, так что на самом деле и форы никакой не было, наоборот, у такого подхода было преимущество, так как появился он раньше.
C> Cache' вон вполне себе нормально живёт, и рвёт RDB на многих задачах.
Не на многих, а на очень конкретных и весьма консервативных — во-первых, эти задачи весьма специфичны, а во-вторых, в силу консервативности, там просто нет смысла переходить на RDB, раз и так работает. Собственно, Cache сейчас выступает ровно там, где всегда были сетевые БД и на реляционные так и не перешли.
C>А без ORM оно не нужно?
Нет конечно. LL и DTO — не нужны, кеш нужен совсем в другом виде.
C>А зачем "совсем другие"?
Затем, что прикладная логика существенно многообразнее того, что нужно хранить, и меняется эта логика гораздо чаще сохраненных данных. Собственно с чего и начали — это фундаментальная разница, между собственно данными и их интерпретацией в конкретном юзкейсе конкретного приложения. "Data != Object" (c)
Мы уже победили, просто это еще не так заметно...
Re[16]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, IB, Вы писали:
C>>Которые есть часть поведения, и которые ломаются от изменения структуры данных. IB>Эта часть поведения очень хорошо отделяется от собственно поведения и структуры хранения, а не является неотъемлемой частью объекта, как в OODB и классических ORM.
Она отделяется ровно в той мере, в которой объекты отделены от схемы БД в ORM.
IB>После этой форы прошло уже лет 20, пора бы фору и наверстать уже. К тому же, иерархические БД и тем более сетевые, в этом разрезе, мало чем отличаются от OODB, так что на самом деле и форы никакой не было, наоборот, у такого подхода было преимущество, так как появился он раньше.
Иерархические БД — отличаются, слишком они примитивные. Сетевые БД — уже ближе, да.
C>> Cache' вон вполне себе нормально живёт, и рвёт RDB на многих задачах. IB>Не на многих, а на очень конкретных и весьма консервативных — во-первых, эти задачи весьма специфичны, а во-вторых, в силу консервативности, там просто нет смысла переходить на RDB, раз и так работает. Собственно, Cache сейчас выступает ровно там, где всегда были сетевые БД и на реляционные так и не перешли.
Cache' сейчас собираются внедрять там, где живёт map-reduce, так что очень интересно может получится.
C>>А без ORM оно не нужно? IB>Нет конечно. LL и DTO — не нужны, кеш нужен совсем в другом виде.
DTO прямо совсем не нужны? Так и собираешься dataset'ы гонять между слоями?
C>>А зачем "совсем другие"? IB>Затем, что прикладная логика существенно многообразнее того, что нужно хранить, и меняется эта логика гораздо чаще сохраненных данных. Собственно с чего и начали — это фундаментальная разница, между собственно данными и их интерпретацией в конкретном юзкейсе конкретного приложения. "Data != Object" (c)
Ну и причём тут ORM? В объектах, с которыми работает ORM логики быть не должно. Так что пусть себе меняется.
Sapienti sat!
Re[11]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Gaperton, Вы писали:
G> Я говорю конкретно об их BigTable, который не слишком сильно привязан к специфике их софта.
Насколько я понимаю, таки привязано...
G>Во-первых, не только для отчетов.
Тем более...
G> На практике — они гораздо более быстрые за счет существенно лучшей масштабируемости.
К сожалению, это далеко не всегда эквивалентная замена.
G>1) Апгрейд схемы БД при изменении версии. G>2) Репликация изменений схемы БД.
Вот это круто, если оно это умеет при относительно небольшой плате за производительность, то весьма интересно.
G>3) "Нормализация" и понижение производительности из-за обилия операций join. В CouchDB как ключ, так и значения могут быть составным типом произвольной сложности (это произвольные JSON-объекты). Это касается и "table-oreinted view" в том числе.
Ну, так и в RBD можно BLOB записать, а как только нам от BLOB-а нужны подробности — здравствуй join.
G>4) Реляционная модель — это не та модель, в которой удобно работать в твоей проге.
Собственно, мой поинт в этой дискуссии ровно в том, что на данный момент, для работы с данными, реляционная модель, таки удобнее любой другой. И лучше работать в ОО с реляционной моделью, чем пытаться из данных строить графы объектов. Другое дело, что идеальным решением может быть что-то еще, но это "что-то еще", определенно сильно смахивает на ту же реляционку.
Мы уже победили, просто это еще не так заметно...
Re[17]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Cyberax, Вы писали:
C>Она отделяется ровно в той мере, в которой объекты отделены от схемы БД в ORM.
Как-то ты быстно с OODB съехал.. =)
Как я уже писал, именно по этому ORM встречаются гораздо чаще, чем OODB, но тем не менее, ORM у тебя строит вполне конкретный граф объектов, который для другого юзкейса уже не катит.
C>Иерархические БД — отличаются, слишком они примитивные. Сетевые БД — уже ближе, да.
Иными словами — никакой форы не было.
C>Cache' сейчас собираются внедрять там, где живёт map-reduce, так что очень интересно может получится.
Это последние судороги? =)
C>DTO прямо совсем не нужны? Так и собираешься dataset'ы гонять между слоями?
Причем тут датасеты?
C>Ну и причём тут ORM? В объектах, с которыми работает ORM логики быть не должно.
При том, что ORM-ом, равно как и OODB, ты пытаешься построить совершенно конкретный граф объектов, вместо того, чтобы просто использовать данные.
Мы уже победили, просто это еще не так заметно...
Re[28]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Cyberax, Вы писали:
C>То что ты рассказывал как у вас там всё работает — это чистый антипаттерн использования Hibernate. У каждого потока должна быть своя сессия со своим графом объектов, иначе будем натыкаться на сплошные проблемы.
Ты думаешь это от хорошей жизни так сделали? У каждого потока есть своя сессия, как полагается. Только скорость обработки запроса была упала в 6 раз по сравнению с без гибернейта в лучшем случае, до совершенно несуразных цифр там, где доля работы с БД была побольше. И потребление памяти на некоторых задачах подскочило с 2-х гиг до 16 (большой привет каждому треду со своим графом объектов).
Естественно, это проблема не ORM вообще, а проблема неоптимальности конкретного Hibernate. Проблема ORM в невозможности без проблем работу распаралелить или закешировать. Попытки что-то закешировать приводили поначалу к слабоуловимым ошибкамт(совершенно разным и феерическим), а теперь привела к необходимости превентивно резолвить все LL ссылки. Т.е. на всякий случай приходится грузить дерево объектов, потому что не ясно какой кусок, когда и кому понадобится.
Здравствуйте, IB, Вы писали:
C>>У Андрея проблема в том, что с одним соединением идёт работа из нескольких потоков. Все известные БД на таком use-case'е глючат. IB>Так с соединением или с гибернейтовской сессией?
Попрошу без инсинуаций Это не шатная ситуация! И с соединением и с сессией работает только один поток. Но если один объект вычитать из БД и передать на обработку в другие потоки (т.е. читаем в db-thread обрабатываем на пуле worker-ов), то поведение получалось непредсказуемым. В лучшем случае, если в db-thread работа с БД закончилась, то получается LazyLoadException. Тогда всё ясно. В более сложном случае, при доступе к нересолвеной LL ссылке из разных потоков происходила конкурентная работа с хиб.сессий и БД. Тут всё сложно. Может даже не быть исключений. Просто течёт память и конекшены к БД Какого-то corruption данных вроде не случалось — и на том спасибо.
Здравствуйте, Cyberax, Вы писали:
C>Не, это RDB являются тупиковой ветвью, пережитком старого COBOLьного прошлого.
Я бы сказал по другому. Там где можно применить ORM скорее всего нафиг не нужны RDB. Там где нужны преимущества предоставляемые моделью RBD вреден ORM.
Здравствуйте, Cyberax, Вы писали:
A>>Cyberax, я его превел не в контексте спора, а сам по себе. Очень правильный закон ограничивающий связность системы. Не стоит о нем забывать. C>Чем правильный?
Самое главное что уменьшается связность системы (а особенно неочеведная связность).
Метод SomeMethod(SomeObject object): зависит только от класса SomeObject, а не от всех классов с которыми он связан. Если метод требует SomeObject то он его и использует, а не его потроха.
C>Да ещё и хватило наглости назвать это "законом".
Без комментариев.
A>>В частности закон деметры запрещает проектировать классы с вложенными коллекциями в виде: order.Items.Add(newItem) предлагая в замен order.AddItem(newItem). C>Вот это и есть неправильно.
Почему неправильно? Тем, что класс не позволяет напрямую изменять сущности от которых зависит?
Может доведем ситуацию до абсурдной: "student.Group = newGroup"? Надеюсь с этим вопросов не возникает.
Чем же тогда принципиально отличается order.Items.Add(newItem)?
И еще:
Чаще всего для LL характерен такой код "someStudent.getParentGroup().getGroupPrefect().addToAssignments(...)".
Я так понимаю ты описался, правильно? Ну зачем старосте группы метод addToAssignments? Лучше же prefect.Assignments.Add(...)
A>>P.S. Тем более никаким образом он не ограничивает запросы из двух таблиц C>Ограничивает. Так как join двух таблиц — тоже нарушение принципа Деметры.
Каким образом? Ты уверен, что правильно его понял?
C>И вообще, можешь показать мне как будет выглядеть "деметрированый" метод, который будет переводить студента в группу к другому студенту?
Такого метода не будет! Во всяком случае этот метод будет делегировать работу более общему методу который переводит студента в другую группу:
Здравствуйте, Cyberax, Вы писали:
C>>>Кстати, он ещё и противоречит принципу, что методы класс должны заниматься только тем, что требует доступа к его приватным данным. A>>1) Каким это образом? Тем, что он не запрещает? C>Таким. Метод Object.AddItem — избыточен, если есть публичная коллекция Object.Items.
1) Вы не ответили на вопрос. Как избыточность/неизбыточность соотносится с "методы класс должны заниматься только тем, что требует доступа к его приватным данным"?
2) Ага, и методы get/set_something тоже избыточны, раз есть публичное поле? Ню-ню.
A>>2) Что это за принцип-то такой? Не мог бы ты полнее его озвучить? C>Да очень простой принцип, неоднократно обсуждали в форуме по архитектуре. См.: http://www.martinfowler.com/bliki/AnemicDomainModel.html (правда, Фаулер считает это антипаттерном).
А, ну если так. То почему это плохо? Интересно.
RichDomainModel противоречит AnemicDomainModel. И что? Это два разных подхода. Они диаметрально противоположны. Что, блин, в этом плохого?
Кроме того Закон Деметры НЕ противоречит тому, что
методы класс должны заниматься только тем, что требует доступа к его приватным данным
.
Опровергните меня, если уж я не понимаю.
СУВ, Aikin
Re[21]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Aikin, Вы писали:
C>>Чем правильный? A>Самое главное что уменьшается связность системы (а особенно неочеведная связность).
Зато увеличивает количество мусора, затрудняющего понимание этой системы.
A>Метод SomeMethod(SomeObject object): зависит только от класса SomeObject, а не от всех классов с которыми он связан. Если метод требует SomeObject то он его и использует, а не его потроха.
Дойдём до максимума — нафиг нам тогда все ассоциации между объектами, если все методы каждого объекта зависят только от своих данных?
C>>Вот это и есть неправильно. A>Почему неправильно? Тем, что класс не позволяет напрямую изменять сущности от которых зависит?
Да.
A>Может доведем ситуацию до абсурдной: "student.Group = newGroup"? Надеюсь с этим вопросов не возникает.
Почему "до абсурдной"? Оно даже вполне нормально будет работать.
A>Чем же тогда принципиально отличается order.Items.Add(newItem)?
Ничем особым.
A>И еще: A>
Чаще всего для LL характерен такой код "someStudent.getParentGroup().getGroupPrefect().addToAssignments(...)".
A>Я так понимаю ты описался, правильно? Ну зачем старосте группы метод addToAssignments? Лучше же prefect.Assignments.Add(...)
Да, так лучше. Но это мелочи.
C>>Ограничивает. Так как join двух таблиц — тоже нарушение принципа Деметры. A>Каким образом? Ты уверен, что правильно его понял?
Да. Каждый класс должен работать только со своими данными. А если мы делаем join по цепочке на несколько таблиц — уже интересно получается.
C>>И вообще, можешь показать мне как будет выглядеть "деметрированый" метод, который будет переводить студента в группу к другому студенту? A>Такого метода не будет! Во всяком случае этот метод будет делегировать работу более общему методу который переводит студента в другую группу:
Вот в этом и проблема.
A>
void TranferStudentToOtherStudentGroup(Student transferingStudent, Student studentToWhoseGroupTransfering)
A>{
A> _groupHelper.ChangeStudentGroup(transferingStudent, student.Group);
A>}
Вот таких методов из одной строки будет очень много, а их выразительность будет весьма низкой. Вывод: и нафиг оно нужно?
Тут я согласен — если действие требует нескольких скоординированых операций, то его стоит выносить в хэлперы. А вот однострочные методы — ну их нафиг.
Sapienti sat!
Re[22]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Cyberax, Вы писали:
C>Зато увеличивает количество мусора, затрудняющего понимание этой системы.
Дело не в количестве мусора. Всё как раз наоборот — если у тебя есть некий граф объектов, то в нем некоторые связи являются избыточными с точки зрения транзитивного замыкания. Принцип Деметеры рекомендует свести граф зависимостей к остовному дереву. Очевидным образом, мы уменьшаем количество мусора (коим являются с точки зрения этого принципа "лишние" связи).
C>Дойдём до максимума — нафиг нам тогда все ассоциации между объектами, если все методы каждого объекта зависят только от своих данных?
Максимум, до которого можно дойти без потери транзитивного замыкания — это остовное дерево.
Его преимущество — это максимальная инкапсуляция, облегчающая рефакторинг и локализующая изменения. При изменении интерфейса одного из классов пострадает только абсолютный минимум классов — те, кто зависит от него напрямую. Классы, расположенные дальше по графу, изолированы от него принципом Деметеры.
A>>Чем же тогда принципиально отличается order.Items.Add(newItem)? C>Ничем особым.
C>Да. Каждый класс должен работать только со своими данными. А если мы делаем join по цепочке на несколько таблиц — уже интересно получается.
Всегда смешно, когда правила из одной культуры переносят на другую. В join не участвуют никакие классы. Границы декомпозиции проходят совсем в других местах.
C>Тут я согласен — если действие требует нескольких скоординированых операций, то его стоит выносить в хэлперы. А вот однострочные методы — ну их нафиг.
Дело в том, что однострочность — понятие относительное. А вот остовность дерева — абсолютное.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[22]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Cyberax, Вы писали:
A>>Самое главное что уменьшается связность системы (а особенно неочеведная связность). C>Зато увеличивает количество мусора, затрудняющего понимание этой системы.
Голословно.
A>>Метод SomeMethod(SomeObject object): зависит только от класса SomeObject, а не от всех классов с которыми он связан. Если метод требует SomeObject то он его и использует, а не его потроха. C>Дойдём до максимума — нафиг нам тогда все ассоциации между объектами, если все методы каждого объекта зависят только от своих данных?
Каким образом у тебя это получилось? Не могу проследить логики.
Закон Деметры не запрещает вызывать методы переданного объекта результатом которых является связанный объект, он всего лишь запрещает вызывать методы этого объекта.
C>>>Вот это и есть неправильно. A>>Почему неправильно? Тем, что класс не позволяет напрямую изменять сущности от которых зависит? C>Да.
Почему? (неужели сложно сразу ответить на ворос? Ты ведь знаешь, что я его задам.)
A>>Может доведем ситуацию до абсурдной: "student.Group = newGroup"? Надеюсь с этим вопросов не возникает. C>Почему "до абсурдной"? Оно даже вполне нормально будет работать.
Да, до тех пор, пока модуль подсчета стипендии не поменяет группу студента, а ты без детального анализа даже не сможешь найти место где это произошло.
A>>И еще: A>>
Чаще всего для LL характерен такой код "someStudent.getParentGroup().getGroupPrefect().addToAssignments(...)".
A>>Я так понимаю ты описался, правильно? Ну зачем старосте группы метод addToAssignments? Лучше же prefect.Assignments.Add(...) C>Да, так лучше. Но это мелочи.
Почему же ты предлагаешь заведомо худший вариант?
C>>>Ограничивает. Так как join двух таблиц — тоже нарушение принципа Деметры. A>>Каким образом? Ты уверен, что правильно его понял? C>Да. Каждый класс должен работать только со своими данными. А если мы делаем join по цепочке на несколько таблиц — уже интересно получается.
Ну где там цепочка? Две джоинимые таблицы абсолютно равнозначны с точки зрения входных данных.
Хотя я не уверен, что Закон Деметры приминим к SQL. Я, если честно, не могу понять что же в SQL входные параметры, а что тело "метода", ...
C>>>И вообще, можешь показать мне как будет выглядеть "деметрированый" метод, который будет переводить студента в группу к другому студенту? A>>Такого метода не будет! Во всяком случае этот метод будет делегировать работу более общему методу который переводит студента в другую группу: C>Вот в этом и проблема.
В чем проблема?
В том, что за изменение группы студентам будет отвечать ОДИН метод вместо десятка мелкоспециализированных ("переводить студента в группу к другому студенту")?
A>>
C>Вот таких методов из одной строки будет очень много, а их выразительность будет весьма низкой. Вывод: и нафиг оно нужно?
Заметь, это ты попросил метод "который будет переводить студента в группу к другому студенту". То что метод получился однострочным лишь следствие твоей задачи, а не чего-то еще.
СУВ, Aikin
Re[23]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Sinclair, Вы писали:
C>>Зато увеличивает количество мусора, затрудняющего понимание этой системы. S>Дело не в количестве мусора. Всё как раз наоборот — если у тебя есть некий граф объектов, то в нем некоторые связи являются избыточными с точки зрения транзитивного замыкания. Принцип Деметеры рекомендует свести граф зависимостей к остовному дереву. Очевидным образом, мы уменьшаем количество мусора (коим являются с точки зрения этого принципа "лишние" связи).
Да нифига не рекомендует. Мне точно так же может потребоваться работа с объектами, скажем , двумя уровнями ниже текущего. И то что они все образуют дерево — тут ничего не решает.
C>>Дойдём до максимума — нафиг нам тогда все ассоциации между объектами, если все методы каждого объекта зависят только от своих данных? S>Максимум, до которого можно дойти без потери транзитивного замыкания — это остовное дерево.
Остовное дерево — оно в реальной жизни не живёт. Циклы встречаются слишком часто.
Да и причём оно здесь вообще?
S> Всегда смешно, когда правила из одной культуры переносят на другую. В join не участвуют никакие классы. Границы декомпозиции проходят совсем в других местах.
Ну вот чем отличается вот это:
select pr.id from prefect pr
inner join group grp on pr.parent_group=grp.id
inner join student st on st.parent_group=grp.id
where st.id=?
Здравствуйте, Aikin, Вы писали:
A>>>Самое главное что уменьшается связность системы (а особенно неочеведная связность).C>>Зато увеличивает количество мусора, затрудняющего понимание этой системы. A>Голословно.
Как и весь "закон" Деметры.
C>>Почему "до абсурдной"? Оно даже вполне нормально будет работать. A>Да, до тех пор, пока модуль подсчета стипендии не поменяет группу студента, а ты без детального анализа даже не сможешь найти место где это произошло.
Точно так же модуль подсчёта стипендии может выполнить "delete from student" и забыть добавить "where". Причём случай с модулем подсчёта стипендий в моём примере отлаживается элементарно — просто смотрим все точки использования метода setParentGroup() (ну или все точки записи свойства, если это C#).
A>>>Я так понимаю ты описался, правильно? Ну зачем старосте группы метод addToAssignments? Лучше же prefect.Assignments.Add(...) C>>Да, так лучше. Но это мелочи. A>Почему же ты предлагаешь заведомо худший вариант?
Простая ошибка. Что ты ожидаешь от примера, написанного в браузере?
A>Ну где там цепочка? Две джоинимые таблицы абсолютно равнозначны с точки зрения входных данных. A>Хотя я не уверен, что Закон Деметры приминим к SQL. Я, если честно, не могу понять что же в SQL входные параметры, а что тело "метода", ...
Задам тот же вопрос, что и Синклеру.
В чём отличие вот этого кода:
select pr.id from prefect pr
inner join group grp on pr.parent_group=grp.id
inner join student st on st.parent_group=grp.id
where st.id=?
?
A>В том, что за изменение группы студентам будет отвечать ОДИН метод вместо десятка мелкоспециализированных ("переводить студента в группу к другому студенту")?
Этих "одних методов" в итоге набираются огромные толпы. Я это ВИДЕЛ своими глазами на системе, где так приходилось делать из-за технических ограничений.
Потом появляются методы TransferIfStudentIsLocal, TransferWithoutReissuingZachetka.
Sapienti sat!
Re[21]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Aikin, Вы писали:
C>>Таким. Метод Object.AddItem — избыточен, если есть публичная коллекция Object.Items. A>1) Вы не ответили на вопрос. Как избыточность/неизбыточность соотносится с "методы класс должны заниматься только тем, что требует доступа к его приватным данным"?
Тем и относится. Добавление в коллекцию не требует доступа к приватным данным, следовательно этих методов быть не должно.
A>2) Ага, и методы get/set_something тоже избыточны, раз есть публичное поле? Ню-ню.
Тут другая ситуация, get/set методы — это способ организации свойств. Которые ведут себя, как ни странно, почти как простое поле класса.
Свойства, в свою очередь, — это простой способ организовать специальную обработку установления полей.
В языках, где можно перехватывать доступ к "полю" (Scala, скажем), get/set методы становятся избыточными.
C>>Да очень простой принцип, неоднократно обсуждали в форуме по архитектуре. См.: http://www.martinfowler.com/bliki/AnemicDomainModel.html (правда, Фаулер считает это антипаттерном). A>А, ну если так. То почему это плохо? Интересно.
Это не анти-паттерн, но Фаулер его таковым считает.
A>RichDomainModel противоречит AnemicDomainModel. И что? Это два разных подхода. Они диаметрально противоположны. Что, блин, в этом плохого?
Обсуждалось в форуме по Архитектуре, поищи там.
A>Кроме того Закон Деметры НЕ противоречит тому, что
методы класс должны заниматься только тем, что требует доступа к его приватным данным
. A>Опровергните меня, если уж я не понимаю.
Кстати! Кто тебе сказал, что строка "student.getParentGroup().getPrefect()" находится в классе Student?
Sapienti sat!
Re[36]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Andrei N.Sobchuck, Вы писали:
IB>>Так с соединением или с гибернейтовской сессией? ANS>Попрошу без инсинуаций Это не шатная ситуация! И с соединением и с сессией работает только один поток. Но если один объект вычитать из БД и передать на обработку в другие потоки (т.е. читаем в db-thread обрабатываем на пуле worker-ов), то поведение получалось непредсказуемым. В лучшем случае, если в db-thread работа с БД закончилась, то получается LazyLoadException. Тогда всё ясно.
Ну вот эффективно и получается, что у тебя идёт параллельная работа над графом объектов из многих сессий.
ANS>В более сложном случае, при доступе к нересолвеной LL ссылке из разных потоков происходила конкурентная работа с хиб.сессий и БД. Тут всё сложно. Может даже не быть исключений. Просто течёт память и конекшены к БД Какого-то corruption данных вроде не случалось — и на том спасибо.
Я же тебе говорил вроде как это пофиксить Делаем свой LazyLoadingHandler и в нём делегируем вызовы в db-поток (или хотя ставим синхронизацию на обращение к сессии).
Как вариант — отключить LL и смотреть где выпадет.
Sapienti sat!
Re[8]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Andrei N.Sobchuck, Вы писали:
C>>Не, это RDB являются тупиковой ветвью, пережитком старого COBOLьного прошлого. ANS>Я бы сказал по другому. Там где можно применить ORM скорее всего нафиг не нужны RDB. Там где нужны преимущества предоставляемые моделью RBD вреден ORM.
Так на практике бывает нужно и то, и другое. Возможности RDB нужны для построения отчётов и сложных запросов, а ORM — для построения логики.
Sapienti sat!
Re[29]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Ты думаешь это от хорошей жизни так сделали? У каждого потока есть своя сессия, как полагается. Только скорость обработки запроса была упала в 6 раз по сравнению с без гибернейта в лучшем случае, до совершенно несуразных цифр там, где доля работы с БД была побольше. И потребление памяти на некоторых задачах подскочило с 2-х гиг до 16 (большой привет каждому треду со своим графом объектов).
Значит надо разбивать задачу на куски и выполнять куски по-отдельности.
ANS>Естественно, это проблема не ORM вообще, а проблема неоптимальности конкретного Hibernate. Проблема ORM в невозможности без проблем работу распаралелить или закешировать.
"Проблема ORM" или "Проблема Hibernate"?
ANS>Попытки что-то закешировать приводили поначалу к слабоуловимым ошибкамт(совершенно разным и феерическим), а теперь привела к необходимости превентивно резолвить все LL ссылки. Т.е. на всякий случай приходится грузить дерево объектов, потому что не ясно какой кусок, когда и кому понадобится.
Так ведь и без ORM пришлось бы все данные загружать, так как LL бы не было в принципе. В чём разница?
Sapienti sat!
Re[24]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Cyberax, Вы писали:
C>>>Почему "до абсурдной"? Оно даже вполне нормально будет работать. A>>Да, до тех пор, пока модуль подсчета стипендии не поменяет группу студента, а ты без детального анализа даже не сможешь найти место где это произошло. C>Точно так же модуль подсчёта стипендии может выполнить "delete from student" и забыть добавить "where". Причём случай с модулем подсчёта стипендий в моём примере отлаживается элементарно — просто смотрим все точки использования метода setParentGroup() (ну или все точки записи свойства, если это C#).
В том-то и дело, что это поле, а не свойство! Свойство == метод. В отличии от него поле допускает безконтрольное изменение объекта. Так же как и anObject.Collection.Add(...)
A>>Ну где там цепочка? Две джоинимые таблицы абсолютно равнозначны с точки зрения входных данных. A>>Хотя я не уверен, что Закон Деметры приминим к SQL. Я, если честно, не могу понять что же в SQL входные параметры, а что тело "метода", ... C>Задам тот же вопрос, что и Синклеру.
C>В чём отличие вот этого кода: C>
C>select pr.id from prefect pr
C>inner join group grp on pr.parent_group=grp.id
C>inner join student st on st.parent_group=grp.id
C>where st.id=?
C>
C>?
Понял.
В обоих случаях нарушается Закон Деметры. В обоих вариантах код плох.
Задам тебе тот же вопрос:
Чем отличается код
select pr.id from prefect pr
inner join group grp on pr.parent_group=grp.id
inner join student st on st.parent_group=grp.id
where st.id=?
от
select pr.id from prefect pr
inner join student st on st.parent_group=pr.parent_group
where st.id=?
?
A>>В том, что за изменение группы студентам будет отвечать ОДИН метод вместо десятка мелкоспециализированных ("переводить студента в группу к другому студенту")? C>Этих "одних методов" в итоге набираются огромные толпы. Я это ВИДЕЛ своими глазами на системе, где так приходилось делать из-за технических ограничений. C>Потом появляются методы TransferIfStudentIsLocal, TransferWithoutReissuingZachetka.
C какой такой стати?!! Я могу, конечно, представить как такое может получитсья. Но голову на плечах все же иметь нужно
Re[22]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Cyberax, Вы писали:
C>>>Таким. Метод Object.AddItem — избыточен, если есть публичная коллекция Object.Items. A>>1) Вы не ответили на вопрос. Как избыточность/неизбыточность соотносится с "методы класс должны заниматься только тем, что требует доступа к его приватным данным"? C>Тем и относится. Добавление в коллекцию не требует доступа к приватным данным, следовательно этих методов быть не должно.
Сама коллекция -- приватные данные. То что ее выкинули наружу -- ошибка проектирования. По-хорошему там достаточно IEnumerable и доступа по индексу, в крайнем случае коллецию нужно сделать ReadOnly. Но не выставлять ее публично всем на растерзание.
A>>2) Ага, и методы get/set_something тоже избыточны, раз есть публичное поле? Ню-ню. C>Тут другая ситуация, get/set методы — это способ организации свойств. Которые ведут себя, как ни странно, почти как простое поле класса. C>Свойства, в свою очередь, — это простой способ организовать специальную обработку установления полей. C>В языках, где можно перехватывать доступ к "полю" (Scala, скажем), get/set методы становятся избыточными.
Ну и что? С чего взялось предупреждение: старайтесь не применять публичных полей, используйте свойства (.net) или геттеры/сеттеры, даже если в них идет обычное присвоение/считыание занчения?
C>>>Да очень простой принцип, неоднократно обсуждали в форуме по архитектуре. См.: http://www.martinfowler.com/bliki/AnemicDomainModel.html (правда, Фаулер считает это антипаттерном). A>>А, ну если так. То почему это плохо? Интересно. C>Это не анти-паттерн, но Фаулер его таковым считает.
Замечательно. Сам сослался на Фаулера, сам его обругал. А я оказался неправ
A>>RichDomainModel противоречит AnemicDomainModel. И что? Это два разных подхода. Они диаметрально противоположны. Что, блин, в этом плохого? C>Обсуждалось в форуме по Архитектуре, поищи там.
Что именно почитать? Что это два разных подхода? Так я это сам знаю.
Ты на какой вопрос отвечал?
A>>Кроме того Закон Деметры НЕ противоречит тому, что
методы класс должны заниматься только тем, что требует доступа к его приватным данным
. A>>Опровергните меня, если уж я не понимаю. C>Кстати! Кто тебе сказал, что строка "student.getParentGroup().getPrefect()" находится в классе Student?
Никто. Вот только кто тебе сказал, что я так считаю?