Фон
Мы используем шаблон проектирования Model-View-Presenter вместе с абстрактным заводским шаблоном и шаблоном "сигнал / слот" в нашем приложении, чтобы выполнить 2 основных требования
- Улучшение тестируемости (очень легкий графический интерфейс, каждое действие может быть смоделировано в модульных тестах)
- Сделайте «представление» полностью независимым от остальных, чтобы мы могли изменить фактическую реализацию представления,без изменения чего-либо другого
Для этого наш код разделен на 4 слоя:
- Ядро: в котором содержится модель
- Ведущий: которыйуправляет взаимодействиями между интерфейсами представления (см. ниже) и ядром
- Интерфейсы представления: они определяют сигналы и слоты для представления, но не реализацию
- Представления: фактическая реализация представлений
Когда докладчик создает представления или работает с ними, он использует абстрактную фабрику и знает только об интерфейсах представления.
Выполняет привязку сигнал / слот между интерфейсами представлений.Это не заботится о фактической реализации.В слое «views» у нас есть конкретная фабрика, которая имеет дело с реализациями.
Механизм сигнал / слот реализован с использованием пользовательской инфраструктуры, основанной на boost :: function.
Действительно, чтоу нас есть что-то вроде этого: http://martinfowler.com/eaaDev/PassiveScreen.html
Все отлично работает.
Проблема
Однако есть проблема, которую я не знаю, как ее решить.
Давайте возьмем, к примеру, очень простой пример перетаскивания.
У меня есть два ContainersViews (ContainerView1, ContainerView2).ContainerView1 имеет ItemView1.Я перетаскиваю ItemView1 из ContainerView1 в ContainerView2.
ContainerView2 должен создать ItemView2 другого типа, но который «указывает» на тот же объект модели, что и ItemView1.
Таким образом, ContainerView2 получаетобратный вызов вызывается для действия удаления с ItemView1 в качестве параметра.Он вызывает ContainerPresenterB, передавая ему ItemViewB
В этом случае мы имеем дело только с представлениями.В MVP-PV представления не должны ничего знать ни о докладчике, ни о модели, верно?
Как я могу создать ItemView2 из ItemView1, не зная, какой объект модели представляет ItemView1?
Я думал о добавлении "itemId" к каждому представлению, этот идентификатор является идентификаторомБазовый объект, который представляет представление.
Таким образом, в псевдокоде ContainerPresenter2 будет делать что-то вроде
itemView2=abstractWidgetFactory.createItemView2();
this.add(itemView2,itemView1.getCoreObjectId())
Я не слишком подробно разбираюсь.Это просто работа.Проблема, с которой я столкнулся, заключается в том, что эти идентификаторы предметов похожи на указатели.И указатели могут быть висящими.Представьте, что по ошибке я удаляю itemView1, а это удаляет coreObject1.У itemView2 будет coreObjectId, который представляет недопустимый coreObject.
Нет ли более элегантного и «пуленепробиваемого» решения?
Несмотря на то, что я никогда не занимался программированием на ObjectiveC или macOSX, я не мог не заметить, что наша платформа очень похожа на инфраструктуру Cocoa.Как они справляются с такой проблемой?Не удалось найти более подробную информацию об этом в Google.Если бы кто-то мог пролить свет на это.
Надеюсь, этот вопрос не слишком запутанный ...