Помогите советом.
Задача
Реализовать ограничение удаления элемента словаря, на который ссылаются элементы данных.
Как это работает сейчас
При удалении BLL-объект переходит в состояние Deleted, что, к примеру, дает возможность пользователю произвести отмену (повтор) удаления посредством действия Undo (Redo) в памяти, то есть без обращения к хранилищу.
Удаление данных BLL-объекта из хранилища происходит только при сохранении (пользователь жмет на кнопку Save): для каждого BLL-объекта, помеченного состоянием Deleted, соответствующий DAO-объект инициирует удаление данных хранилища. На уровне хранилища (ООБД) реализовано ограничение целостности (по типу реляционного) ООП-кодом: при попытке удаления данных, на которые ссылаются другие данные хранилища, возвращается соответствующее исключение.
Как это сейчас видит пользователь
Пользователь удаляет словарный элемент.
Затем жмет кнопку Save, в ответ на что получает подробное (приведу в общем виде) сообщение вроде такого: "Такие-то данные не могут быть удалены, так как на них ссылаются вот такие-то данные. Отмените удаление этих данных или удалите данные, которые ссылаются на удаляемые — а затем повторно вызовите сохранение".
Действия предлагаемые пользователю в сообщении отрабатывают корректно, то есть одно из двух:при отмене удаления BLL-объект переходит в состояние отличное от Deleted, а значит его DAO уже не пытается инициировать удаление;удаляются BLL-объекты, которые ссылаются на него, также посредством перевода в состояние Deleted, таким образом, если при сохранении их данные будут удалены раньше (этот момент контролируется), данные исходного объекта удаляться корректно.
Что не устраивает
Реализация описанного ограничения в ООБД производится ООП-кодом в DAO-объекте соответствующем BLL-объекту. Вот думаю, неужели на уровне BLL придется продублировать данное ограничение? То есть BLL, видимо, также должен проверять, корректно ли удаление... Понимаю, что в случае реляционной БД данное ограничение присутствует и на уровне БД, и на уровне памяти (и про дублирование и речи не идет), но в случае ООБД... мечта поэта: как бы так сделать, чтобы ничего не делать... то есть делать только один раз (на уровне ООБД)?
Неинтуитивность такого поведения программы (разумеется, для пользователя).
Какие мысли терзают в данный момент
Меня терзают смутные сомнения, что пытаюсь найти простое архитектурное решение, которое не хочет сочетаться с удобным пользовательским интерфейсом (в общем смысле, а не ГИП). В итоге, если превалирует техническая сторона (не хочется вносить дублирование проверки удаления на DAL и BLL), то страдает пользователь. Скажем, пока рассматриваю такие варианты (пока лучшего не увидел нигде, а придумать, видимо, фантазии не хватает):
BLL таки производит данную проверку (чего, конечно, жутко не хочется), то есть при нажатии кнопки Delete, пользователю выводится сообщение: "Такой-то словарный элемент используется в таких-то элементах такого-то реестра. Удалите ссылки с таких-то данных реестра на словарный элемент и повторите удаление" — все, то есть по факту пользователю отказывается в действии.
Тоже самое, но в сообщении второе предложение такое: "Удалить словарный элемент со всеми, ссылающимися на него элементами?" — кнопки OK и Cancel. В итоге при сохранении будет удалено все дерево объектов. Сразу вылезают сложности, которые не очень хочется поиметь: придется хитро анализировать дерево ссылающихся объектов и уведомлять пользователя, что будут удалены все его объекты — это случай, скажем, когда от конкретного реестра к конкретному словарю идут ссылки через другие словари.
Тоже самое, но вместо удаления ссылающихся объектов производить в них только зануление ссылок. Маленькие, и все же есть сложности — по обновлению (приведению в состояние соответствия данным хранилища) BLL-объектов, для которых были занулены ссылки на уровне DLL.
Прозрачно (без уведомления) удалять данные объекта, все ссылки на него занулять. Такое ощущение, что вариант прозрачного удаления жутко не понравится пользователям, с другой стороны, зато нет необходимости в проверке на BLL — понимаю, что это не оправдание...
Вопросы
Какое поведение интерфейса пользователя в данном контексте считается наиболее интуитивным? Возможно, есть какие-то ГИП-рекомендации...
Какое архитектурное решение является наиболее простым (в хорошем смысле, а вовсе не тупым — в стиле "лишь бы написать") в данном случае?
Какое сочетание ответов на вопросы 1 и 2 будет наиболее красивым?
Заранее благодарен.