Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
ORM в вопросах и ответах
|
|||
|---|---|---|---|
|
#18+
softwarer UML -> классы -> структура БД -> работа с классами -> конкретные формы Выигрывает по сравнению с вариантом структура БД -> датасет -> форма. Мне кажется, что во многом это дело вкуса и привычки. Ко всему в крупных проектах вариант 2 иногда (сам видел) трансформируется в : UML -> ERD -> структура БД -> датасет -> форма. Разумеется, когда нужно написать простейшее приложение, то можно просто брать и рисовать структуру БД. Но когда этому предшествует долгий анализ предметной области, а над моделью работает целый коллектив, вариант 1 более эффективен. Следует также учесть и судьбу проекта во времени, изменение состава разработчиков, переносимость на другие платформы и т.п. Вероятно конкретные преимущества и недостатки слишком зависят от специфики проекта - очень трудно делать какие-то универсальные умозаключения и обобщения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2005, 15:49 |
|
||
|
ORM в вопросах и ответах
|
|||
|---|---|---|---|
|
#18+
softwarer Собственно, на текущий момент у меня есть впечатление, что объекты удобны для сервера приложений - но клиенту удобнее работать с сервером приложений опять-таки через датасеты (или подобные им структуры). Вот с этим категорически не согласен. Но вероятно впечатления могут сильно зависеть от платформы, на которой идет разработка. С чем работаете вы ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2005, 15:51 |
|
||
|
ORM в вопросах и ответах
|
|||
|---|---|---|---|
|
#18+
Alexey RovdoМне кажется, что во многом это дело вкуса и привычки. Хм. Интересная мысль :) Примерно так меня когда-то убеждали - если долго и упорно пить пиво, оно начнет казаться вкусным. Все же интересны какие-то объективные факторы - быстрее-выше-сильнее. Лишние действия я вижу, следовательно хотя бы для равенства (когда допустимо выбирать по вкусу) нужны какие-то плюсы. Alexey Rovdo Ко всему в крупных проектах вариант 2 иногда (сам видел) трансформируется в : UML -> ERD -> структура БД -> датасет -> форма. Не возражаю, так можно и нужно. Но во-первых, и в первый вариант можно добавить шагов (как вы добавили ERD - то, что я подразумевал под структурой); во-вторых - это прямой, линейный путь. Фактически я не вижу, чем БД -> универсальный интерфейс -> частные формы оказывается хуже (или хотя бы наравне) по сравнению с БД -> универсальный интерфейс -> объекты -> универсальный интерфейс -> частные формы. То есть - пока что я понимаю удобство этого для непропорционально развитого объектного слоя (который есть, например, в app server-е). Для клиента аппсервера, как и для клиента БД - не могу понять. Разумеется, когда нужно написать простейшее приложение, то можно просто брать и рисовать структуру БД. Но когда этому предшествует долгий анализ предметной области, а над моделью работает целый коллектив, вариант 1 более эффективен. Следует также учесть и судьбу проекта во времени, изменение состава разработчиков, переносимость на другие платформы и т.п. Вероятно конкретные преимущества и недостатки слишком зависят от специфики проекта - очень трудно делать какие-то универсальные умозаключения и обобщения.[/quot] ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2005, 15:57 |
|
||
|
ORM в вопросах и ответах
|
|||
|---|---|---|---|
|
#18+
Alexey RovdoВот с этим категорически не согласен. Но вероятно впечатления могут сильно зависеть от платформы, на которой идет разработка. Не вижу зависимости от платформы. Давайте посмотрим какие возможны варианты. 1. Передача информации через некий универсальный интерфейс данных (собственно датасет в том или ином виде). Вариант известен, характеристики понятны. Минус - при операциях на клиенте придется писать код типа DataSet["FieldName"] = Value. В то же время вообще говоря таких операций быть не должно - это делается в объекте, либо по его инициативе (например, инициализация в конструкторе), либо по инициативе других - вызовом методов, например из той же формы. 2. Передача объекта (через сериализацию или еще как-нибудь) на клиента. Минус подхода - нужен достаточно сложный механизм синхронизации "истинного объекта" (на сервере) и его клона на клиенте. Ну а сложный - значит, требующий определенных усилий для использования (Джоэлевский "закон дырявых абстракций" итп). Плюс - мы можем активно манипулировать объектом на клиенте. Был бы весомый плюс для прогов типа "все на клиенте" - но сейчас, пожалуй, менее значим. Клиент манипулирует объектом данных мало; он манипулирует локальными объектами (интерфейсными и прочими) и иногда лениво дергает метод объекта данных. Соответственно, проще протянуть ниточку для дерганья на сервер - то, что в чистом КС делалось хранимками, а в многозвенке может идти через RMI-подобные механизмы. Нейтрально - мы "даром" получаем версионность объектов. Но если они нужны - версионность, транзакции итп - все равно им потребуется неслабая поддержка на сервере. Держать "версию объекта на клиенте" или "версию объекта на сервере" - пожалуй, последнее лучше, ибо универсальнее. Кто сказал, что нам не потребуется версионность сугубо внутри объектного слоя? Например, объект, который автоматически меняет данные.. Здесь главное - мы получили объект, но еще не подключили его к интерфейсу. Это можно сделать опять же двумя способами: 2.1 Универсальная прокладка - в худшем случае тупой генератор кода, в лучшем случае - использование всей мощи, reflection и так далее. Смысл - я хочу "мышкой" указать, что редактор А должен редактировать свойство Б полученного на вход формы объекта. Собственно, хороший механизм. Причем он давно реализован для датасетов. 2.2 Сидеть и тупо кодировать заполнение двадцати редакторов из полей объекта, заполнение полей объекта из двадцати редакторов, тонкости - например, нужно вызвать метод, в редакторе новое значение, в поле еще старое. Минусы вроде как понятны. В морг. Итого - получается, что основа клиента - это датасетные механизмы, возможно, приспособленные для объектной реальности (например, включающие в себя вызов методов объекта). И я не особо вижу, ради чего городить огород. Alexey RovdoС чем работаете вы ? Сложный вопрос. Проект, опыт которого упоминал - на дельфе, он заканчивается. Вопрос вызван тем, что я обдумываю еще один проект и думаю, использовать ли для него ORM-овскую технологию и, возможно, инструменты. Для него я платформу еще не выбрал - есть аргументы за C#, за дельфу и за джаву. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2005, 16:22 |
|
||
|
ORM в вопросах и ответах
|
|||
|---|---|---|---|
|
#18+
Я уже несколько начинаю путаться в ваших диаграммах. В одном месте - это последовательность действий при разработке, а в другом - структура приложения ? Представлю свою точку зрения несколько шире. 1) ORM всегда приводит к замедлению приложения. Очевидно, что прямое обращение к функциям СУБД эффективнее с точки зрения быстродействия. 2) ORM позволяет (и по своей природе подталкивает к этому) рационально разделить приложение на различные функциональные части и работать с каждой из этих частей по отдельности. Например, интерфейсная часть становится более самостоятельной и гибкой. Современные средства разработки все более подводят нас к тому, чтобы мы могли с легкостью подставлять в одно и то же приложение разные "морды" без особого труда. То же самое и с уровнем бизнес-логики. ORM во многом вынуждает выносить логику из хранилища данных и реализовывать ее в приложении в виде отдельного уровня. 3) ORM приводит к изменению процесса разработки. Изменяется порядок отдельных этапов. Это уже хорошо видно из представленных выше диаграмм. Первичными становятся UML-модель и структура классов приложения - структура БД при применении ORM может быть полностью производной от структуры классов приложения и по умолчанию вообще генерируется автоматически. Облегчается документирование в сложных проектах. 4) ORM изменяет логику работы таких механизмов как кэширование и блокировка, переводя ее на уровень отдельных объектов, что может иметь большое значение при разработке приложений определенных классов. 5) Упрощается разработка многозвенных приложений (если в приложении есть четко выраженные различные уровни, то понятнее и проще разделить эти уровни по разным звеньям). 6) Снижаются требования к программистам (нужно просто знать ОО-программирование, знания и опыт использования SQL не обязательны). Как следствие, в сложных проектах снижаются затраты, а небольшие компании получают возможности по созданию и развитию своих продуктов без привлечения дополнительного высококвалифицированного технического персонала. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2005, 16:25 |
|
||
|
ORM в вопросах и ответах
|
|||
|---|---|---|---|
|
#18+
softwarer Минус - при операциях на клиенте придется писать код типа DataSet["FieldName"] = Value. В то же время вообще говоря таких операций быть не должно - это делается в объекте, либо по его инициативе (например, инициализация в конструкторе) ... Конечно, гораздо удобнее обращаться к объектам Object.FieldName = Value без обертки в виде объектов-датасетов и дататаблов. А в случае использования ORM и в конструкторах ничего такого писать не прийдется (в простейшем случае конструкторы вообще можно не писать). softwarer 2. Передача объекта (через сериализацию или еще как-нибудь) на клиента. Сразу уточню. Здесь речь идет исключительно о трехзвенке, в которой ORM-инструментарий применяется на уровне сервера приложений. Именно так, в этом случае мы можем передавать (что кстати не обязательно) на клиента объекты. И существующие технологии: WSDL/SOAP/XML-сервисы для .NET и EJB для Java именно под это и заточены. Но я вообще не вижу здесь специфики ORM - ведь DataSet и DataTable тоже объекты и передаются тем же макаром. А в двухзвенке общение с сервером БД идет через SQL-запросы (что с ORM, что без оного). softwarer Итого - получается, что основа клиента - это датасетные механизмы, возможно, приспособленные для объектной реальности (например, включающие в себя вызов методов объекта). И я не особо вижу, ради чего городить огород. Если датасетные механизмы - основа клиента и вы уверены, что это правильно для вашего приложения (переход на классические ОО модели ведет к ухудшению приложения и/или усложняет его разработку), то конечно ORM только навредит, поскольку ориентирован на другие классы клиентов. softwarer Проект, опыт которого упоминал - на дельфе, он заканчивается. Вопрос вызван тем, что я обдумываю еще один проект и думаю, использовать ли для него ORM-овскую технологию и, возможно, инструменты. Для него я платформу еще не выбрал - есть аргументы за C#, за дельфу и за джаву. Для дельфей сейчас активно продвигается ORM-инструментарий Bold. Лично не юзал, но своих адептов эта система уже имеет. Недостатки тоже есть - в основном из-за молодости продукта. Для .NET уже существует множество решений (Versant Open Access .NET, Hibernate, DeveloperExpress и др.). В целом тоже охарактеризую эти продукты как слишком молодые для того, чтобы с уверенностью говорить о них, как о зарекомендовавших себя в среде разработчиков. Слишком еще молода технология .NET и слишком много в ней неопробованных подводных камней (особенно при построении многозвенных приложений). Тем не менее, знаю что технолдогия активно осваивается и идет немало проектов, в т.ч. и с опорой на ORM-инструменты. На сегодня именно в мире Java достижения ORM-продуктов наиболее высоки. Обусловлено это как относительной зрелостью платформы Java, так и рядом других факторов, таких например, как явная и строгая объектная ориентированность самого языка программирования Java. Именно в мире Java уже есть устоявшаяся спецификация для обеспечения транспарентной сохраняемости объектов - спецификация JDO. А продукты, реализующие эту спецификацию (по сути ORM-инструменты) обкатаны на множестве проектов. Даже сравнивая известные мне ORM-продукты Versant (Open Access JDO и Open Access .NET), я могу сказать, что VOA JDO ушла по своим возможностям гораздо дальше своей "молодой" родственницы VOA .NET. И реализует огромное число возможностей, ускоряющих и разработку, и повышающих эффективность работы JDO-приложений. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2005, 17:02 |
|
||
|
ORM в вопросах и ответах
|
|||
|---|---|---|---|
|
#18+
Alexey RovdoЯ уже несколько начинаю путаться в ваших диаграммах. В одном месте - это последовательность действий при разработке, а в другом - структура приложения ? К сожалению, Judge пока не добавил возможность рисовать UML прямо в форуме. Приходится обходиться ;) Alexey Rovdo 2) ORM позволяет (и по своей природе подталкивает к этому) рационально разделить приложение на различные функциональные части и работать с Это само по себе неплохо - но программа и без ORM может быть хорошо поделена на части. В то же время я вполне представляю, как с помощью ORM написать просто отвратительную программу - соответственно, панацеей ее не назовешь. Alexey Rovdo Современные средства разработки все более подводят нас к тому, чтобы мы могли с легкостью подставлять в одно и то же приложение разные "морды" без особого труда. Да, в общем-то, я и так не вижу труда за исключением реализации N параллельных "морд". Alexey RovdoORM во многом вынуждает выносить логику из хранилища данных и реализовывать ее в приложении в виде отдельного уровня. Само по себе это выглядит скорее минусом. Я понимаю, когда удобно иметь отдельный уровень логики - но в любом случае хотел бы четко управлять распределением логики. Alexey Rovdoструктура БД при применении ORM может быть полностью производной от структуры классов приложения Это нерабочий вариант, если говорить о серьезных проектах и о реляционных базах. Собственно, предыдущий опыт показывает, что куда более близкие между собой ER-диаграмма и DD-диаграмма таки приходится делать заметно разными. Alexey Rovdo и по умолчанию вообще генерируется автоматически. Облегчается документирование в сложных проектах. Cоответственно, получаем мух и котлеты - половина приложения на UML, документируется итп, вне зависимости от базы. Другая половина приложения - что с ORM, что без ORM, генерируется существенно руками и документируется ими же. Alexey Rovdo 4) ORM изменяет логику работы таких механизмов как кэширование и блокировка, переводя ее на уровень отдельных объектов, что может иметь большое значение при разработке приложений определенных классов. Хм. По привычке оппонента хочется спросить, на каком уровне до того находилась блокировка :) Наверное, определенный смысл есть - но я просил преимущества для достаточно обычных задач. То, что собственная реализация и замена стандартных механизмов дает большую свободу действий - факт, который глупо оспаривать и бессмысленно обсуждать. Alexey Rovdo 5) Упрощается разработка многозвенных приложений (если в приложении есть четко выраженные различные уровни, то понятнее и проще разделить эти уровни по разным звеньям). Хм. Помимо предыдущего - пока что никто не постулировал, что многозвенные приложения дают какое-то заведомое преимущество. Собственно, как я уже говорил - если захотеть разрабатывать многозвенку, я вижу смысл для этого на центральном уровне, на appserver-е. То есть - ограниченно согласен. Alexey Rovdo 6) Снижаются требования к программистам (нужно просто знать ОО-программирование, знания и опыт использования SQL не обязательны). Вы знаете, я уже порядка двадцати лет занимаюсь программированием - и почти все это время слышал про подобное светлое будущее. Если не ошибаюсь, лет пятнадцать назад мне показывали Clarion c практически теми же формулировками. Не верю. И не надеюсь увидеть. Пока не увижу - не поверю. Alexey Rovdo Как следствие, в сложных проектах снижаются затраты, а небольшие компании получают возможности по созданию и развитию своих продуктов без привлечения дополнительного высококвалифицированного технического персонала. Алексей, я как высококвалифицированный технический персонал (давайте оставим это сомнительное утверждение на моей совести) хочу понять, насколько стоит связываться с этой технологией. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2005, 18:40 |
|
||
|
ORM в вопросах и ответах
|
|||
|---|---|---|---|
|
#18+
Alexey RovdoЕсли датасетные механизмы - основа клиента и вы уверены, что это правильно для вашего приложения (переход на классические ОО модели ведет к ухудшению приложения и/или усложняет его разработку), то конечно ORM только навредит, поскольку ориентирован на другие классы клиентов. Вот тут я не понимаю. Давайте так - "клиент" это "морда" плюс, возможно, какая-то невизуальная логика. Невизуальная логика - это в любом случае отдельный уровень. То есть - я не вижу большой разницы, между вариантами БД <-> appserver(logic) <-> interface и БД <-> (logic) interface. Тут всего-навсего два уровня соединены в одно приложение либо разнесены в два. Если говорить о серьезном логическом уровне - понятно, что для него нужны объекты. Для несерьезного - возможно, не стоит возиться. Меня больше интересует тот факт, что взаимодействие объектов с интерфейсом хорошо описывается именно dataset-ориентированными механизмами, и собственно не имеет разумной альтернативы. Соответственно, приспособить эти механизмы под работу с объектами представляется мне единственным решением. Ну и помним, что dataset-ы реализуют набор типичных операций, которые понадобятся и для других случаев - сортировку и прочее. В случае двухзвенной схемы следовало бы приспосабливать - но висит вопрос: почему раньше считалось, что логику нужно выносить на сервер, а сейчас мы пихаем ее в клиента. Соответственно, в типовом случае оказывается, что ORM-у места особо нет. В случае трехзвенки - наиболее удобный вариант приспособления, имхо, сочетается с транспортным уровнем. То есть имеем объекты на appserver-е и некие dataset-источники (datasource в терминологии дельфы) на клиенте. Alexey RovdoНа сегодня именно в мире Java достижения ORM-продуктов наиболее высоки. Во многом поэтому и в раздумьях - слишком не нравится сама джава :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2005, 18:59 |
|
||
|
ORM в вопросах и ответах
|
|||
|---|---|---|---|
|
#18+
Прежде всего отмечу, что мои 6 пунктов вовсе не обязательно являются плюсами (и вы это вроде бы заметили). Все зависит от конкретики вашей задачи. >Меня больше интересует тот факт, что взаимодействие объектов с интерфейсом хорошо описывается именно dataset-ориентированными механизмами, и собственно не имеет разумной альтернативы. Соответственно, приспособить эти механизмы под работу с объектами представляется мне единственным решением. Ну и помним, что dataset-ы реализуют набор типичных операций, которые понадобятся и для других случаев - сортировку и прочее. Вот тут вы поднимаете основное отличие объектного подхода. Взаимодействие объектов с интерфейсом совсем не обязательно оптимально при ориентации на dataset-конструкции. Если пользователь в основном работает с таблицами, а не с формами для редактирования объектов (элементов таблиц), а поиск нужных данных осуществляет через сортировку и визуальный перебор записей, то объектный подход здесь не катит. При ОО-программировании нужно уходить от работы пользователя с таблицами. Преимущественно должны использоваться специализированные формы для редактирования конкретных объектов, а поиск должен базироваться в первую очередь на разнообразных методах навигации (по деревьям и другим видам графов, по связям между объектами). Т.е. меняется сама идеология построения интерфейсов и это первое, что вы заметите, когда перейдете на Java - там даже нет много из того, к чему привыкли разработчики Delphi или Access - и некоторая "ломка" поначалу многих напрягает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2005, 19:41 |
|
||
|
ORM в вопросах и ответах
|
|||
|---|---|---|---|
|
#18+
Почитайте это . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2005, 19:43 |
|
||
|
ORM в вопросах и ответах
|
|||
|---|---|---|---|
|
#18+
Alexey RovdoПри ОО-программировании нужно уходить от работы пользователя с таблицами Хм. "Нужно" в этом контексте - это слово с очень красивым идеологическим содержимым и с очень плохими последствиями для кошелька. Нужно - то, что хочет пользователь (и то что отвечает условиям его задач). Не нужна - технология, неспособная удовлетворить требования пользователя. Alexey Rovdo. Преимущественно должны использоваться специализированные формы для редактирования конкретных объектов, Не возражаю. Но и в этом случае гораздо удобнее использовать методы, разработанные для работы с dataset. Alexey Rovdo.а поиск должен базироваться в первую очередь на разнообразных методах навигации (по деревьям и другим видам графов, по связям между объектами). Меня удивляют такие слова от идеолога объектного подхода. Есть датасет или другой набор объектов данных. Есть представление данных - таблица, дерево, граф, диаграмма, что угодно еще. Они связаны, но не привязаны одно к другому. Скажем, у меня в текущем проекте вопрос "отображаются данные деревом или таблицей" - зависит от одной настройки конкретного отображения. Данным это - глубоко непринципиально. И - с моей точки зрения - именно это есть "хорошее разделение уровней" и ООП-стиль. Впрочем, и без уровней, и без ООП хорошее решение делалось именно так. Alexey Rovdo Т.е. меняется сама идеология построения интерфейсов и это первое, что вы заметите, когда перейдете на Java - там даже нет много из того, к чему привыкли разработчики Delphi или Access - и некоторая "ломка" поначалу многих напрягает. Меня напрягает "ломка" клиентов. Я писал по-разному - но я никогда не опускался до того, чтобы убеждать клиента делать "так" просто потому, что я не могу сделать иначе. На самом деле меня интересует в первую очередь вопрос форм работы с конкретным объектом. Таблицы и прочее - гораздо проще. Хотя на самом деле при реализации универсального слоя разницы нет - просто компонентов для коллекций нужно меньше, чем для конкретных объектов. Что касается джавы - меня там действительно напрягает ряд моментов. Например, меня напрягло, что заголовок (Header) у JTable не появляется, если JTable лежит не на JScrollPane. Поскольку я делал окно с авторесайзом "под количество строк в таблице" - я потратил заметное время на поиск этого идиотизма. Но это уже не связанный с ORM вопрос. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2005, 20:00 |
|
||
|
ORM в вопросах и ответах
|
|||
|---|---|---|---|
|
#18+
softwarer Я думаю, что, прежде всего, нужно выяснить 2 момента 1й - что "лучше", dataset или доменный объект (иногда их называют entity, иногда plain-object (в java - pojo aka plain old java object или entity-bean)) Здесь, на мой взгляд, главным является не модель доступа (ds.set("attr_name","some_value") vs pojo.attr_name = some_value), а смысл и способ получения конкретного dataset'а и plain-объекта. Как мы получаем dataset'ы ? ответ - никак - это просто представление результатов работы запроса. Объектная же модель доменов - это устойчивый артефакт ОО-проектирования. Мы именно их получаем применяя оо -методологии разработки. Т.е. если я получил тип Document с определенным набором атрибутов и методов - я могу внятно объяснить, почему я получил его именно таким. В этом главное отличие - в том, что домены - это звенья одной большой цепи, которую называют ООП. Именно поэтому я считаю их сравнение похожим на сравнение плуга с трактором. Здесь, правда, можно порассуждать о том, что физически из себя должен представлять domain-object. Т.е. как организовать доступ к его свойствам - через методы get/set или по-имени. Но я думаю это отдельный разговор. Второй момент: как эти domains'ы получить. Тут есть несколько способов - но сводиться они будут к orm, вопрос только к собственному или стороннему. На самом деле ORM - это средства, выполняющие сервисные функции, связанные с сохранением и извлечением данных в/из СУБД. Здесь, прежде всего, стоит познакомиться с концепцией (паттерном, кому как нравиться) DAO-слоя (data access layer'а). Ознакомиться можно, например, здесь {sun} и здесь {примеры к spring'у} Особенно настаиваю на изучении примеров к spring'у. ВСЕ - это все вопросы, относящиеся к ORM. Ни сериализация, ни количество звеньев и способ построения пользовательского интерфейса к ORM не относятся, и решать вопросы об их целесообразности нужно отдельно. Теперь я бы хотел остановиться на некоторых других вопросах. Я уже 2 года занимаюсь разработкой систем, в которых присутствовал полноценный слой из доменов и считаю, что ничего кроме пользы они принести не могут. Да, могут быть ограничения конкретной платформы, которые могут повлиять на полноту и способ реализации, но сами по себе домены чрезвычайно удобны и полезны. К сожалению, очень часто домены и средства ORM каким-то образом привязывают к вопросу о том, где должна происходить обработка данных или бизнес-логика приложения. Я считаю, что это независимые вещи, и они никак не связаны. Например, я убежден, что обработка должна происходить максимально близко к этим данным. Что суть клиент-сервера в верном распределении обязанностей между участниками. Но с таким же успехом можно реализовать бизнес-логику и на клиенте - для этого не нужно никакого ORM! Т.е. если человек считает что для суммирования оборотов за день нужно их получить на клиента, а затем использовать for(), то он это сделает и без ORM! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.03.2005, 11:40 |
|
||
|
ORM в вопросах и ответах
|
|||
|---|---|---|---|
|
#18+
Я что то не очень понял что такое "домены" в контексте предыдущего сообщения. Другими словами это абстрактные и родительские суперклассы? Posted via ActualForum NNTP Server 1.1 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.03.2005, 13:48 |
|
||
|
ORM в вопросах и ответах
|
|||
|---|---|---|---|
|
#18+
funikovyuri softwarer Я думаю, что, прежде всего, нужно выяснить 2 момента 1й - что "лучше", dataset или доменный объект (иногда их называют entity, Насколько я понимаю, доменным объектом Вы назвали то, что я назвал объектом данных - грубо говоря, объект, созданный вокруг конкретной записи. В этом случае, относительно того, что Вы говорите дальше - для меня на сугубо концептуальном уровне нет заметной разницы, реализован ли такой объект собственно как объект или как запись датасета. Мне интересны плюсы-минусы работы в каждой из реализаций. funikovyuriполучения конкретного dataset'а и plain-объекта. Как мы получаем dataset'ы ? ответ - никак - это просто представление результатов работы запроса. Это несколько произвольное утверждение. "Устойчивый артефакт" - то, что в мыслях у проектировщика. Давайте так: я понимаю, чем объекты замечательны при реализации логики. Соответственно, средний уровень на трехзвенках либо "вся логика на клиенте" - понятно и далее не рассматривается. Меня интересует вопрос клиента, в первую очередь - "достаточно тонкого клиента". Что есть "достаточно тонкий" - многие компрометируют слово "тонкий", подразумевая под ним браузерного клиента; хотелось бы отгородиться от такой трактовки. Я имею в виду клиента, который не содержит логики, а решает задачи интерфейса - отображения данных, переходов между данными, вызова тех или иных функциональных действий с передачей им данных. Вот для такого клиента - я пока не понимаю никаких плюсов ORM-реализации. Вплоть до того, что по моим текущим представлениям, appserver-у целесообразно передавать данные клиенту именно как датасеты (в той или иной реализации). funikovyuri Ознакомиться можно, например, здесь {sun} и здесь {примеры к spring'у} Особенно настаиваю на изучении примеров к spring'у. Спасибо, смотрю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.03.2005, 14:20 |
|
||
|
ORM в вопросах и ответах
|
|||
|---|---|---|---|
|
#18+
funikovyuriК сожалению, очень часто домены и средства ORM каким-то образом привязывают к вопросу о том, где должна происходить обработка данных или бизнес-логика приложения. Я считаю, что это независимые вещи, и они никак не связаны. Пока - не понимаю. Идеологически замечательно, но не понимаю соответствия практике. Допустим, у нас есть обычная двухзвенка. Деликатно говоря, не все сервера БД позволяют реализовать полноценный объектный слой внутри себя. Таким образом, у нас остается два выхода: либо делаем достаточно независимый appserver, либо несем объекты и все с ними связанное на клиента. Третьего варианта я не вижу - а соответственно, не вижу и места для доменного слоя в двухзвенке. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.03.2005, 14:57 |
|
||
|
ORM в вопросах и ответах
|
|||
|---|---|---|---|
|
#18+
Важно понять то, что же вы все-таки имеете ввиду говоря о двухзвенке и трехзвенке. Если у вас нет уровня бизнес-логики, то как можно говорить о том реализован ли он на клиенте или на сервере? Если же у вас на сервере абстрактный уровень бизнес-логики реализован с помощью хранимых процедур и триггеров, то следует понять одну простую вещь - если абстрактный уровень бизнес-логики в приложении имеется (его можно явно выделить в архитектуре приложения), то это как минимум трехзвенная архитектура. Хранимые процедуры и триггеры реализованы внутри СУБД только лишь по причине удобства развертывания и это в некотором смысле ограничение (мы не можем, например, заставить систему отрабатывать триггеры на отдельном сервере). Пожертвовав этим удобством до некоторой степени (усложнив развертывание), вы можете разместить на этом же сервере свое приложение, которое будет отрабатывать всю бизнес-логику и отвечать за передачу данных, например через Web-сервисы, вашему (полу)тонкому клиенту (во всех случаях мы вправе говорить о клиент/серверной архитектуре системы). Т.е. если сам уровень бизнес-логики есть, то его размещение - вопрос отдельный. Но именно наличие этого уровня (как бы он ни был реализован) позволяет отнести приложение к трехзвенному. Именно в такой трактовке трехзвенности я совершенно согласен с funikovyuri - средства ORM зря привязывают к вопросу о том, где должна происходить обработка данных или бизнес-логика приложения. Средства ORM тоже можно разместить как на стороне клиента (толстый клиент), так и на стороне сервера ((полу)толстый клиент). Что же касается различий между "суррогатами-обертками" (ака DataTable и DataSet) и "настоящими объектами", то советую просто сравнить способы доступа к связанным объектам. Т.е. как в обоих случаях мы можем, к примеру, получить список неких сущностей, связаных с исходным объектом каким-нибудь отношением. Разумеется, вы увидите, что в истинных объектах существует возможность НАВИГАЦИИ, тогда как для суррогатов ничего такого нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.03.2005, 15:50 |
|
||
|
ORM в вопросах и ответах
|
|||
|---|---|---|---|
|
#18+
softwarer Насколько я понимаю, доменным объектом Вы назвали то, что я назвал объектом данных - грубо говоря, объект, созданный вокруг конкретной записи. Верно, если грубо говоря, то верно. Фактически в РБД мы манипулируем записями в ОО-мире - объектами. Объекты могут выполнять разные функции, но домены - это объекты из предметной области. Т.е. это пользовательские типа. Ну и ясно что один объект может физически храниться в разных местах схемы БД. В этом случае, относительно того, что Вы говорите дальше - для меня на сугубо концептуальном уровне нет заметной разницы, реализован ли такой объект собственно как объект или как запись датасета. Мне интересны плюсы-минусы работы в каждой из реализаций. Тоже верно. Если к рекордсетам относиться как к доменам - то разница только в реализации. НО есть нюансы, например, - 1) можно инкапсулировать в объекте не только данные, но и поведение (это не бизнесс-логика приложения, это логика этого конкретного типа. Например тип String и его методы типа конкатенации.). 2) объект более устойчив к изменениям. Т.е. с ним проще соблюдать старый контракт при новой реализации. Объект заменяем. 2) моделировать отношения между обектами мне кажется проще чем между датасетами (то о чем говорит Alexey Rovdo) Фактически датасет заточен для другого - для временного хранения результатов запроса к БД. И я уже замечал, что можно реализовать домены можно и в виде датасет-подобной структуры. Главное понимать что это такое. Т.е. понимать результатом каких процессов они являются. "Устойчивый артефакт" в смысле что проектировщик однозначно может ответить почему тот или иной domain-object имеет именно такую структуру и поведение. Опираться он при этом будет на ООПроектирование. Тоже может сказать архитектор БД смотря на сущность в ER-моделировании. Вот для такого клиента - я пока не понимаю никаких плюсов ORM-реализации. Плюсы есть и серьезные. Во-первых намного более строгая, поддающаяся анализу архитектура, а значит намного более высокая степень повторного использования кода и его сопровождения и развития. Во-вторых, возмодность разделить работу между различными участниками. Т.е. нет form-oriented архитектуры, когда не знаешь какой структуры нужен датасет пока не нарисуешь форму, которая и сформирует требования к этой структуре. Здесь есть домен со своим контрактом. Далее разныее люди могут писать от presentation до service tier'ов и использовать этот домен. Вплоть до того, что по моим текущим представлениям, appserver-у целесообразно передавать данные клиенту именно как датасеты (в той или иной реализации). Это почему? По-моему минимум все равно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.03.2005, 16:55 |
|
||
|
ORM в вопросах и ответах
|
|||
|---|---|---|---|
|
#18+
funikovyuriТоже верно. Если к рекордсетам относиться как к доменам - то разница только в реализации. НО есть нюансы, например, - 1) можно инкапсулировать в объекте не только данные, но и поведение (это не бизнесс-логика приложения, это логика этого конкретного типа. Например тип String и его методы типа конкатенации.). Не совсем понял, если честно, поэтому отвечу общим: никто не мешает отнаследоваться от датасета и добавить туда необходимые методы - и бизнес-логику, и все остальное. Я, правда, до сих пор предпочитал чуть другой подход - использовать дельфовый объект Data Module как менеджер объектов и место реализации логики; то есть он представляет решение определенной задачи, умеет возвращать датасеты, потребные в других местах, и выполнять необходимые операции. Подход - следствие в первую очередь удобной реализации этого в дельфе. funikovyuri2) объект более устойчив к изменениям. Т.е. с ним проще соблюдать старый контракт при новой реализации. Объект заменяем. Хм. Не вижу большой разницы. Грубо говоря, я могу как угодно менять свойство SQL датасета до тех пор, пока соблюдаю контракт на возвращаемые данные. Если я делаю что-либо принципиально некорректное - например, меняю SQL снаружи, из клиентских модулей - да в общем сам виноват, подход тут не при чем. funikovyuriФактически датасет заточен для другого - для временного хранения результатов запроса к БД. Я бы сказал чуть шире - фактически это "универсальная коллекция с гибким интерфейсом работы с ней". Я, например, достаточно часто использую хранение в XML для всякого рода локальных данных. funikovyuri"Устойчивый артефакт" в смысле что проектировщик однозначно может ответить почему тот или иной domain-object имеет именно такую структуру и поведение. Это само собой. funikovyuri Опираться он при этом будет на ООПроектирование. Тоже может сказать архитектор БД смотря на сущность в ER-моделировании. Одно не мешает другому. На клиенте я в любом случае манипулирую объектами, отражающими то, что нужно пользователю - если ему нужен, допустим, "список просроченных платежей", значит на клиенте у меня будет список просроченных платежей, хотя с точки зрения базы он может собираться из десяти таблиц. funikovyuri Вот для такого клиента - я пока не понимаю никаких плюсов ORM-реализации. Плюсы есть и серьезные. Во-первых намного более строгая, поддающаяся анализу архитектура, а значит намного более высокая степень повторного использования кода и его сопровождения и развития. Архитектура чего именно? Клиента? По сравнению с чем более строгая? Я понимаю, что пока нахожусь максимум на "не умеешь их готовить" - но пока не понимаю. Можно пример - мол, с датасетами мы работаем так, с ORM мы работаем этак.. funikovyuri Во-вторых, возмодность разделить работу между различными участниками. Хм. Я очень удивлен предположению, что с датасетами это вызывает проблемы. funikovyuriТ.е. нет form-oriented архитектуры, когда не знаешь какой структуры нужен датасет пока не нарисуешь форму, которая и сформирует требования к этой структуре. Ээ.. А кто заставляет работать настолько странным образом? funikovyuriЗдесь есть домен со своим контрактом. Далее разныее люди могут писать от presentation до service tier'ов и использовать этот домен. Вопрос в том, что эти разные люди в результате делают работу, необходимость которой мне непонятна. По моим представлениям, наращивание сложности структуры само по себе приводит к росту трудоемкости. Чем это компенсируется - пытаюсь понять. funikovyuriВплоть до того, что по моим текущим представлениям, appserver-у целесообразно передавать данные клиенту именно как датасеты (в той или иной реализации). Это почему? По-моему минимум все равно. Несколько причин. 1. Если делать противопоставление "датасетов" "доменным объектам" - это противопоставление "универсальных датасетов" "конкретным, предметно-ориентированным объектам". Для создания интерфейса универсальные источники данных намного удобнее. Как минимум они избавляют от генерации большого количества тупого кода. 2. Существует огромное количество хороших решений, ориентированных именно что на датасеты (уже имеющиеся классы) и на универсальный интерфейс как на идеологию. Чтобы так работать с объектами - надо делать еще один специальный слой "универсализации" объектов. Я как раз такой сделал - после чего отметил, что на клиенте практически везде работаю через него и практически нигде не использую "сильно типизированные" объекты. 3. Функциональность, присутствующая в датасетах - выверена на соответствие задачам, актуальным для клиентских приложений. В лучшем случае ее надо повторять, в худшем - повторяя Алексея, объяснить пользователю, что ему нужен тот интерфейс, который мои объекты позволяют сделать. 4. Слияние. В сложных задачах далеко не всегда требуется работать с объектом как он есть; это похоже на мысли отказаться от использования нескольких таблиц в select-е. Соответственно, появляется уровень, цель которого - подготовка данных в том виде, в котором они нужны клиенту - с лукапами, с сопоставлениями и всей прочей функциональностью, обеспечиваемой join-ами. Отталкиваясь именно от объектов - придется реализовывать большой уровень конвертации из "нормализованных", "предметных" объектов, объектов сервера, в "отображаемые" объекты, объекты клиента. При более активном использовании датасетов этот уровень исчезает - реализованный сервером БД. Заодно легче достичь необходимой производительности - все-таки сервер БД в этом смысле намного развитее самого совершенного API. Допустим, что у нас самый лучший случай и все эти задачи решены. Что тогда? Как минимум, остается лишняя сущность. Если мы реализуем тонкий клиент - я не нахожу на нем задач, ради которых требовались бы объекты. Мы создаем их только ради того, чтобы нагрузить приложение еще парой уровней - тем же presentation - а потом засунуть на вход "универсализатора", сделанного для интерфейса. Вторая важная вещь, которую я здесь вижу, связана как раз с сопровождением. Я считаю, что имею здесь право на определенную категоричность, поскольку неоднократно слышал от коллег, что с моим кодом очень легко работать. Так вот: легкость сопровождения однозначно определяется отсутствием тупого кода и минимальностью технических действий. Код должен быть осмысленным, каждая строка должна быть оправдана с точки зрения решаемой задачи. Если рассматривать обычный КС - код Код: plaintext 1. совершенно идеален с точки зрения понимания - а следовательно, и сопровождения. "Объектный" аналогичный код - как минимум, занимает намного больше места на технические действия, на конвертации и переходы между уровнями. Да, такой код написан в соответствии с паттернами (а очень сильно - просто автосгенерирован). В лучшем случае, это большая куча, в которой опытный человек знает, где искать ту самую единственно нужную строку. В худшем случае - в этом похожем на самый обычный код будут еще какие-то неочевидные тонкости - с понятными для сопровождения последствиями. P.S. Все время получается так, что я активно атакую технологию. На самом деле я не имею целью ее хаять - я хочу научиться/оценить, для чего "пробую на зуб". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.03.2005, 19:02 |
|
||
|
ORM в вопросах и ответах
|
|||
|---|---|---|---|
|
#18+
softwarer Хм, дело в том что вы по-сути используете свой ОРМ :) Я о такой возможности уже говорил. Т.е. вы делаете эти domain-objects на основе TDataModule (опять же влияние платформы) и именно в Дельфи с датасетами удобнее работать так как там всё gui работает через них. В java с этим проще и тот же hibernate просто сделал бы работу за вас приведя к релультату типа Код: plaintext Это если коротко, пока прочитал ваш пост только бегло... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.03.2005, 19:37 |
|
||
|
ORM в вопросах и ответах
|
|||
|---|---|---|---|
|
#18+
vadiminfo Ограничения целостности, которые нельзя выразить декларативно в РСУБД в разных источниках назваются по разному: корпаративные ограничения целостности, ограничения общего вида, бизнес ограничения. ... Если это реализовать в приложении, а не хранить в виде триггера вместе с данными, то будет зависимость данных от приложения (без этого приложения этого правила нет, и целостность данных зависит от этого приложения). ... Целостность данных - одна из трех составных частей модели данных. ... зачем нужны ограничения целостности в модели данных. Ну, можно предположить, что ограничения целостности это свойства, которые должны быть либо истинными, либо ложными для каждого возможного состояния данных. Т.е. они обеспечивают логические правила, которым отвечают данные в БД в любом состоянии. Их вводят как для повышения семантичности модели данных так и расширения возможностей поддержки целостности данных. Разве мы в этом не заинтересованы? Т.е. польза от них есть? Но необходимы ли они? В РМД скорее всего да. Без них модель менее адекватно отображает предметную область (ПО). А цель моделирования максимально адекватно отобразить ПО. Про ООМД, что-то читал, что там с ними сложности, но точно не помню. Ну сложности совершенно очевидны. И они проистекают из того, что в ООБД могут храниться объекты любых классов (типов). Строгая типизация, характерная для РСУБД позволяет системе свободно обращаться с данными, поскольку операции над этими данными уже определены и сама СУБД их знает и умеет исполнять. Т.е. когда нам нужно ограничить, например, максимальное значение, то мы можем спокойно вписать ограничение вида «не больше». Но как сравнивать объекты, операция сравнения которых не определена или переопределена в классах-потомках? И даже если сам код этой операции хранится вместе с описанием соответствующего класса, то всегда ли эффективно выполнять этот код «внутри» СУБД? Пока что на эти вопросы нет однозначного ответа. Versant проповедует подход, позволяющий отдать решение этой проблемы на откуп разработчику. GemStone хранит и исполняет методы средствами сервера БД, т.е. все вопросы должны решаться внутри СУБД. И все-таки я, не отрицая полезности хранения правил и ограничений целостности вместе с данными, придерживаюсь более гибкого взгляда на, то где эти правила целесообразно отрабатывать. Рассмотрим примеры Выше mir привел пример с необходимостью использования триггера для обеспечения целостности данных при наличии неких аггрегатов (типа суммы). Кажется, что в данном примере наличие триггера действительно ТРЕБУЕТСЯ для обеспечения целостности данных. Но давайте разберемся в этом детальнее. Рассмотрим две крайних ситуации. 1) Предположим у нас есть таблица с полями v1, v2, v3, vAgr. В такой ситуации я безо всякого тригера наложу ограничения, которые запретят запись в поле суммы vAgr любых значений, не равных сумме полей данных (v1, v2, v3), а в поля данных - любых значений кроме тех, которые не противоречат существующему значению суммы. В результате целостность данных будет обеспечена, но приложение просто должно будет вычислять сумму самостоятельно и изменять соответствующее поле в рамках одной транзакции с изменениями полей данных. 2) Предположим теперь, что vAgr должно содержать наибольший общий делитель значений v1, v2, v3 или наименьший по модулю корень кубического уравнения, коэффициенты которого определяются значениями v1, v2, v3 или т.п. Что же оказывается? В первом случае для обеспечения целостности нам триггер в принципе не обязателен, а во втором – реализовать все необходимые вычисления даже в рамках триггера проблематично, да и не факт, что это будет разумно с точки зрения распределения вычислительной нагрузки между серверами и клиентами. Вопросы, вопросы, вопросы... Где же та граница, за которой мы можем говорить, что вот «это» относится к целостности данных и должно отрабатываться внутри СУБД (с помощью триггеров, ХП или как-то еще), а вот «то» уже нет и имеет право быть перенесенным в приложение? По какому критерию мы относим одни правила к модели предметной области, а другие готовы признать функцией приложения? По логике некоторых постов в этой ветке мы должны реализовать в виде хранимых процедур все. Причем реализовывать бизнес-логику в виде хранимых процедур даже правильнее, чем как-то иначе! Почему так? Что, кроме соображений быстродействия и удобства развертывания за этим стоит? Целостность данных? Но бизнес-правила могут измениться и тогда в процессе переписывания и доработки хранимых процедур целостность данных окажется под угрозой. А если обработка бизнес-правил вынесена на сервер приложений, то беспокойства по крайней мере за судьбу уже накопленных данных быть не должно. Читая посты некоторых товарищей вобще приходишь к выводу, что выделять отдельный уровень бизнес-логики в приложениях нет необходимости – за все в ответе СУБД? Проблема распределения вычислительной нагрузки Зачем же я задаю столько вопросов и не даю на них четких ответов? Мне кажется, что нет никаких четких критериев, по которым мы можем относить одни ограничения и правила к компетенции СУБД, а другие – к компетенции приложения. На практике все определяется задачами разделения вычислительной нагрузки и удобством разработчика. Т.е. когда разработчик хочет снять нагрузку с сервера БД, он включает вычисления и проверки в приложение, а когда ему хочется облегчить управление проектами, где множество разных приложений пишется для работы с одной базой, а нагрузка на сервер разрешена большая, он реализует многие обработки в виде хранимых процедур и триггеров. Очевидно, что в идеале мы должны иметь возможность гибко выбирать то звено приложения, на котором мы хотим исполнить наш код (проверка бизнес-правила, реакция на событие и т.п.). Т.е. вот захотели, чтобы эта процедура выполнялась на сервере приложений – поставили птичку и забыли. А эта на сервере БД – пожалуйста. На клиенте – нет проблем. В таком контексте хранимые процедуры на SQL становятся скорее тормозом, ограничивающим гибкоть приложений. Ведь не зря сейчас пошла волна встраивания в СУБД поддержки платформонезависимых языков (Java, да и .NET), выполнение кода которых можно легко перемещать между различными серверами/клиентами. Выводы Какой вывод я бы хотел сделать из всего сказанного? Вероятно очень важно хранить вместе с данными (или где-то рядом) формальные описания правил обеспечения целостности этих данных. Но вот вопрос о том, в каком звене информационной системы (клиент/сервер приложений/сервер БД/ ... ) эти правила следует отрабатывать не столь однозначен. Сегодня исходные тексты (или байт/IL-коды) процедур/методов, написанных на Java или языках платформы .NET в принципе можно хранить в БД. Это поддерживает Oracle (ХП на Java), Юкон (.NET), Versant Developer Suite (Java) да и любая СУБД (по большому счету нет проблем хранить исходники в БД). Но возможность переноса нагрузки пока только в незначительной мере реализуется системами с полноценными серверами приложений. Это так хотя бы потому, что реализуя всю бизнес-логику и правила обеспечения целостности в рамках сервера приложений мы можем решать, ставить ли нам сервер приложений на тот же компьютер, где у нас стоит сервер БД или на отдельный. Если же вся бизнес-логика реализована в виде ХП внутри одной БД и лежит вместе с данными, то современные РСУБД не дают нам никакого выбора – отработка этих ХП будет происходить на том же сервере. На мой взгляд вполне можно смотреть на связку «СУБД+сервер приложений» как на единое хранилище данных и методов и именно эту пару рассматривать, как систему, обеспечивющую непротиворечивость и целостность данных, а также как на собственно реализацию модели предметной области. И все равно это будет только некоторым приближением, поскольку и приложение тоже не является только витриной к хранящимся данным и некоторые элементы бизнес-логики иногда логичнее реализовывать именно в рамках пользовательских приложений (какие именно – решает разработчик в свете реальных требований в конкретных ситуациях). vadiminfo Про Дейта. Он безапеляционно отверг сам SQL как "искажение" реляционной модели, а вместо него вместе с Дарвеном предолжил язык D (1992). Насчет триггеров ничего не ясно из моих источников, ... А почему Вы упомянули Дейта? Ведь даже Кодд - отец РМД, но он выпустил Джина. Включились значительные интеллектальные ресурсы. Их не сбросишь со счетов. Разве та теория множеств Кантора, которую он сам создавал не называется сегодня "наивной". Хотя безусловно он отец теории множеств вообще и гений гениев. Но тысячи спецов, среди которых были и выдающиеся не зря ведь работали. Были созданы новые разделы в математике. Она вообще приняла другой вид... Согласен. Я тут на досуге немного поисследовал – за что же Дейт критиковал ООСУБД в ряде своих статей. Забавный перечень: 1. Совместное использование данных приложениями 2. Физическая независимость данных 3. Непредвиденные запросы 4. Представления и логическая независимость данных 5. Независимые от приложений декларативные ограничения целостности 6. Владение данными и гибкий механизм безопасности 7. Управление многопользовательским доступом 8. Каталог общего назначения 9. Независимое от приложения проектирование базы данных Создается впечатление, что разработчики ООСУБД последние 10 лет работали строго в направлении, указанном Дейтом, и старательно исправляли все названные недочеты. Сегодня практически по всем пунктам в ООСУБД есть соответствующая функциональность и только некоторые вызывают вопросы, причем вопросы эти носят скорее концептуальный, чем технический характер. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.03.2005, 15:39 |
|
||
|
|

start [/forum/topic.php?fid=32&msg=32979522&tid=1545961]: |
0ms |
get settings: |
17ms |
get forum list: |
24ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
66ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
68ms |
get tp. blocked users: |
6ms |
| others: | 255ms |
| total: | 456ms |

| 0 / 0 |
