Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Background

We use the Model-View-Presenter design pattern along with the abstract factory pattern and the "signal/slot" pattern in our application, to fullfill 2 main requirements

Enhance testability (very lightweight GUI, every action can be simulated in unit tests) Make the "view" totally independant from the rest, so we can change the actual view implementation, without changing anything else In order to do so our code is divided in 4 layers :

Core : which holds the model Presenter : which manages interactions between the view interfaces (see bellow) and the core View Interfaces : they define the signals and slots for a View, but not the implementation Views : the actual implementation of the views When the presenter creates or deals with views, it uses an abstract factory and only knows about the view interfaces.

It does the signal/slot binding between views interfaces. It doesn't care about the actual implementation. In the "views" layer, we have a concrete factory which deals with implementations.

The signal/slot mechanism is implemented using a custom framework built upon boost::function.

Really, what we have is something like that : http://martinfowler.com/eaaDev/PassiveScreen.html

Everything works fine.

The problem

However, there's a problem I don't know how to solve.

Let's take for example a very simple drag and drop example.

I have two ContainersViews (ContainerView1, ContainerView2). ContainerView1 has an ItemView1. I drag the ItemView1 from ContainerView1 to ContainerView2.

ContainerView2 must create an ItemView2, of a different type, but which "points" to the same model object as ItemView1.

So the ContainerView2 gets a callback called for the drop action with ItemView1 as a parameter. It calls ContainerPresenterB passing it ItemViewB

In this case we are only dealing with views. In MVP-PV, views aren't supposed to know anything about the presenter nor the model, right ?

How can I create the ItemView2 from the ItemView1, not knowing which model object is ItemView1 representing ?

I thought about adding an "itemId" to every view, this id being the id of the core object the view represents.

So in pseudo code, ContainerPresenter2 would do something like

itemView2=abstractWidgetFactory.createItemView2(); this.add(itemView2,itemView1.getCoreObjectId()) I don't get too much into details. That just work. The problem I have here is that those itemIds are just like pointers. And pointers can be dangling. Imagine that by mistake, I delete itemView1, and this deletes coreObject1. The itemView2 will have a coreObjectId which represents an invalid coreObject.

Isn't there a more elegant and "bulletproof" solution ?

Even though I never did ObjectiveC or macOSX programming, I couldn't help but notice that our framework is very similar to Cocoa framework. How do they deal with this kind of problem ? Couldn't find more in-depth information about that on google. If someone could shed some light on this.

I hope this question isn't too confusing ...

share|improve this question
add comment

1 Answer

up vote 1 down vote accepted

Finally we found a solution : - When you start dragging an object, the view sends a "drag" signal to it's controller. The controller gets the model object and puts a pointer to it in a shared "DragandDrop-board" (think of it as a clipboard)

  • When you drop, the view sends a "drop" signal to it's controller. The controller gets the object from the drag and drop board, and updates the model accordingly.

If you use a kind of a smart pointer that's quite easy to make sure the pointer is still valid after the drop .

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.