Добрый день!
Столкнулся с архитектурной проблемой при разработке приложения с использованием
— WPF (для UI)
— объектнойе СУБД db4o (в качестве DAL)
Суть проблемы в следующем.
Так или иначе существуют классы, моделирующие предметную область (Domain).
В идеале они ничего не должны знать про UI и DAL.
Для эффективной связки Domain с UI в случае .NET кроме собственно реализации реакций на команды (сообщения)
необходима прослойка, в которую могут войти:
(1) нотификация об изменения свойств объектов (реализация INotifyPropertyChanged)
(2) ObservableCollection и BindingList для коллекций
(3) возможности копирования состояния объекта для реализации Cancel (Undo)
как для отдельных объектов, так и для коллекций.
Валидацию не включаю — она может быть в Domain.
Все перечисленное должно быть в этой "прослойке", если же эти возможности добавлять
в Domain, то возникает проблема с DAL, поскольку объектному DAL-у все эти возможности и связанные с ними
поля-данные не нужны..
Покопался в интернет, нашел, библиотеку csla. Все вроде как хорошо, но в суловиях объектного хранилища
пришлось бы вести две параллельные версии классов.. Одни — "чистый Domain", другие — Domain c доп.
возможностями (1)-(3)..
В итоге все-таки добавил часть фич, а конкретно (1) и (3) в Domain, но внутренний дискомфорт остался.
Поделитись своим опытом!

Как жить-то?
С уважением,
Сергей.
Здравствуйте, sergunok, Вы писали:
Обобщенный Model-View-ControllerАвтор: Сергей Рогачев
Дата: 23.03.07
Похожий подход реализовал в последнем проекте. Как и у вас ООБД — db4o. На основе generics построен обобщенный DAO-объект (всего один класс!). ЯП Java, в .NET будет даже проще, так как там runtime generics, соответственно информация о типе есть во время выполнения, а значит и через рефлексию, а движок db4o работает как раз через нее. Оописанный в статье шаблон видоизменен в сторону MVP. Undo/Redo работает как по редактированию элемента, так и по изменению коллекции элементов.
Здравствуйте, sergunok, Вы писали:
S>А все-так если не секрет, как примерно реализовывали?
См. ссылку выше.
S>1. Есть классы, моделирующие сущности предметной области
S>(как структуру — поля и свойства, так и логику — методы).
S>Эти классы ничего не знают про db4o?
Ничего.
S>У них присутствуют transient поля?
Нет, но это непринципиально, просто мне не понадобилось.
S>В них есть реализация INotifyPropertyChanged?
Есть, только, как говорил, в данный момент framework пишу на Java. Хотя в статье, ссылку на которую дал выше, приводил и реализацию на C#, в том числе и роль INotifyPropertyChanged описывал.
S>Присутствующие здесь коллекции — это обычные List<T>? (никаких там ObservableCollection, BindingList и т.п.)
В Java — да, простые коллекции, там проще всего пользоваться HashSet<T>. В C# — BindingList<T>, опять же, подробнее все это описано в статье.
S>2.Сам DAL наверно действительно делается с помощью generic-класса..
S>Некий Serializer<T>, дающий общие операции, а все остальные сериалайзеры кастомизируется в его наследниках:
S>class CustomerSerializer : Serializer<Customer>
S>{...}
Да, один абстрактный класс ModelDAO<T>. В Java во время выполнения нет информации о generic-типах, а потому в наследниках приходится реализовывать метод getClass для конкретного подставляемого вместо generic типа, чтобы Db4o смог отличить его от класса Object. В C# же generic будет работать с Db4o без лишних телодвижений.
Правда, посчитал нужным еще реализовать в DAO-объекте защиту ссылочной целостности по типу реляционной. К примеру, если на объект Employee ссылается на объект Company, то вызов метода delete объекта ModelDAO<Company> должен пробросить исключение, к примеру, DbDeleteConstraintException. Это слегка усложнило DAL, но не сильно. Описывал здесь:
Delete constraintsАвтор: rsn81
Дата: 25.07.07
— там слегка и по общей логике приложения есть.
S>3. Основной вопрос про классы как назвать-то... ViewModel.
S>Как их делали? Этот класс — шаблон от T (T — класс (1)).
S>С помощью рефлекшена определяете где были IList, вместо них заводите ObservableCollection и т.п.
S>INotifyPropertyChanged здесь же добавляется (если да то как)?
S>Добавляете Undo / Redo.
S>И затем байндите контрольки со свойствами классов ViewModel?
Что вы имеете в виду под ViewModel не знаю, по-крайней мере функционал Undo/Redo никак не связан с представлениями. Все действия над моделью в MVC делает контроллер, а в MVP — предъявитель: это и редактирование, и сохранение, и загрузка, и отмена, и повтор изменений, и клонирование, и создание нового экземпляра и т.д. и т.п.
S>Несколько не связанных с этим вопросов:
S>1. Не пробовали для db4o реализовывать логику удаления с помощью атрибутов?
S>т.е. размечать те поля, по которым не нужно проводить каскадное удаление с помощью какого-нибудь
S>атрибута [CascadeDelete(false)]
Каскадное удаление не допускаю (не использую): просто не вижу в этом необходимости, а заказчик не просит.
S>2. Опять таки в db4o как организуете активацию? В Serializer<T> есть соответствующие методы?
Что конкретно вы имеете в виду под активацией, зачитывание данных хранилища, отменяющее произведенные изменения в BLL-объекте? Тогда посмотрите метод refresh у класса ExtObjectContainer.