Паттерны для приложения с .NET GUI и объектным хранением
От: sergunok  
Дата: 26.07.07 09:31
Оценка:
Добрый день!

Столкнулся с архитектурной проблемой при разработке приложения с использованием
— 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, но внутренний дискомфорт остался.

Поделитись своим опытом! Как жить-то?

С уважением,
Сергей.
Re: Паттерны для приложения с .NET GUI и объектным хранением
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 26.07.07 12:08
Оценка:
Здравствуйте, sergunok, Вы писали:

Обобщенный Model-View-Controller
Автор: Сергей Рогачев
Дата: 23.03.07

Похожий подход реализовал в последнем проекте. Как и у вас ООБД — db4o. На основе generics построен обобщенный DAO-объект (всего один класс!). ЯП Java, в .NET будет даже проще, так как там runtime generics, соответственно информация о типе есть во время выполнения, а значит и через рефлексию, а движок db4o работает как раз через нее. Оописанный в статье шаблон видоизменен в сторону MVP. Undo/Redo работает как по редактированию элемента, так и по изменению коллекции элементов.
Re[2]: Паттерны для приложения с .NET GUI и объектным хранен
От: sergunok  
Дата: 02.08.07 14:17
Оценка:
Спасибо!
А все-так если не секрет, как примерно реализовывали?

1. Есть классы, моделирующие сущности предметной области
(как структуру — поля и свойства, так и логику — методы).
Эти классы ничего не знают про db4o?
У них присутствуют transient поля?
В них есть реализация INotifyPropertyChanged?
Присутствующие здесь коллекции — это обычные List<T>? (никаких там ObservableCollection, BindingList и т.п.)

2.Сам DAL наверно действительно делается с помощью generic-класса..
Некий Serializer<T>, дающий общие операции, а все остальные сериалайзеры кастомизируется в его наследниках:
class CustomerSerializer : Serializer<Customer>
{...}

3. Основной вопрос про классы как назвать-то... ViewModel.
Как их делали? Этот класс — шаблон от T (T — класс (1)).
С помощью рефлекшена определяете где были IList, вместо них заводите ObservableCollection и т.п.
INotifyPropertyChanged здесь же добавляется (если да то как)?
Добавляете Undo / Redo.
И затем байндите контрольки со свойствами классов ViewModel?

Несколько не связанных с этим вопросов:
1. Не пробовали для db4o реализовывать логику удаления с помощью атрибутов?
т.е. размечать те поля, по которым не нужно проводить каскадное удаление с помощью какого-нибудь
атрибута [CascadeDelete(false)]

2. Опять таки в db4o как организуете активацию? В Serializer<T> есть соответствующие методы?
Re[3]: Паттерны для приложения с .NET GUI и объектным хранен
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 02.08.07 16:16
Оценка:
Здравствуйте, 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.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.