[wxpython-dev] Google SoC Project - MVC
Kevin Ollivier
kevino at theolliviers.com
Fri May 30 13:31:50 PDT 2008
Hi Mike,
On May 30, 2008, at 12:17 PM, Mike Rooney wrote:
> Robin Dunn wrote:
>> Kevin Ollivier wrote:
>>> Hi Peter,
>>>
>>> On May 29, 2008, at 1:57 AM, Peter Damoc wrote:
>>>
>>>> Hi Keith,
>>>>
>>>> My suggestion is to investigate Cells technology (pycells and
>>>> Trellis) integration with wxPython
>>>
>>> Definitely worth taking a look at, but I think a better approach
>>> would be to simply allow wxPython controls to take a model and
>>> controller, and use them when set. This way we're not trying to re-
>>> invent wxPython or trying to get fundamentally different
>>> frameworks with different design philosophies and target audiences
>>> to try and play nice together. We're just extending it to be MVC-
>>> friendly. We can use something like wx.lib.pubsub to send
>>> notifications when either the model or the view changes, and the
>>> controller sets up listeners for these events and handles any
>>> changes that needs made.
>>
>> I'm not sure how to go about implementing this, but some thoughts
>> I've had about MVC in wxPython are that it would be nice to be able
>> to have some sort of modular controller and/or model. In other
>> words, each widget involved in the view would have an associated
>> component that would automatically integrate itself into a
>> composite controller or model of some sort. Then there would be a
>> standard but flexible way to hook that to the application's model.
>> This would allow the app model to be whatever it needs to be for
>> the app or the programmer's preferences, and just use a flexible
>> but well defined interface for communicating with the rest of the
>> system, which was all built automatically based on how the UI is
>> put together.
>>
>>
>
> Yes, I have been trying to brainstorm something like this for one of
> my projects. To me the most elegant solution is a model, view, and
> controller which can each exist independently and don't need any of
> the other parts.
>
> So you can have a View (wxPython app), say a contact list, that
> allows you to add, edit, and remove entries. The View knows what
> boxes to pop up, how to add entries to the View's list when you
> click Add, etc. When "changes" occur (whatever ultimately requires
> an updated Model), you just use pubsub like
> pubsub.Publisher().sendMessage("CONTACT ADDED", ('Bob',
> '755-555-1212', 'bob at aol.com')), or something like that. The View
> doesn't care if anything is listening. The controller can pick up on
> this, and make the appropriate model calls. Without a controller,
> there is just no data persistence.
>
> When the View launches it would send a pubsub message, informing
> anyone that may be listening that it can be populated with
> information. Now if a controller is there, it could iterate over its
> contacts, sending the identical messages ("CONTACT ADDED", ('Bob',
> '755-555-1212', 'bob at aol.com')), and the View knows the appropriate
> way to represent that contact.
No, if we're talking about MVC here, the view should not know how to
represent a contact; the controller would store that logic. A view's
sole purpose is to visualize data, and in order for the view to be as
reusable as possible, it must know as little about the semantic
meaning of that data as possible. A view should only know what type of
data to draw (e.g. bool, string, number, custom) and where to draw it.
In other words, a view should not know how to respond to a "CONTACT
ADDED" message, because it should have no knowledge of the model, nor
should it directly be passed data from the model like you suggest
here. Instead, the "contact added" message should be sent from the
model to the controller and the controller will do the work to add the
contact to the view. (Or, the view will send a "Load data" message to
the controller, and the controller will read through the model and
populate the view with its data.)
The best way to think of the controller, IMHO, is to think of it as a
translator. When something happens in the model, the controller
translates it into terms the view can understand (e.g. a series of
commands needed to visualize the change in the model), and when
something happens in the view, the controller translates it into terms
the model can understand (e.g. a series of data manipulations). I
don't see the purpose of the controller sending out messages, as its
entire purpose is to respond to messages from the model and view. From
your comments, however, you seem to be visualizing the controller as
just passing messages around, but really in that case, why can't the
view just send messages directly to the model and vice-versa?
>
> You can also import the controller from a command-line and manually
> call whatever functions the controller binds to the appropriate
> pubsub messages (addContact(self, Name, Phone, Email)), (or you
> could do it with pubsub :) without a need for the View.
>
> Using a solution like this and using pubsub, you can have multiple
> Views for the same data and multiple Models storing the data in
> completely different ways, without any extra work at all. You have
> all these components just announcing occurrences, and anything that
> wants to act on it can do so in the way it defines as useful.
>
> In less abstract words (from my blueprint at https://blueprints.launchpad.net/wxbanker/+spec/proper-mvc)
> : "Have the GUI and the controller send the same messages when the
> same action is performed, with unique IDs created by the generator.
> Each component maintains a list of uIDs to ignore, and a uID is
> added to it either when it has already responded to it or has
> generated it itself. For example, the user removes an account in the
> GUI. The GUI sends ("ACCOUNT REMOVED", (uID, accountNum)). The
> Controller receives this, realizes IT didn't generate the message
> (based on the uID), and acts on it. It then sends the same message
> (with the same ID). The GUI will ignore it, since it sent it and has
> already done the appropriate GUI things. The Controller will also
> ignore this message since it will have added the ID to its "sent"
> list as well."
>
> So one way to accomplish better MVC in Python would to wrap pubsub
> in a way which allows each component to send messages in a standard
> way, and handling the aforementioned situations so each thing only
> responds to the message once, and making this transparent to the user.
>
> Note all of this isn't strict MVC. To do it strictly (or as strict
> as you can in wxPython) you would have to Bind all wxPython events
> directly to the controller's appropriate functions. But this
> requires a controller which not only knows details about the View,
> but a View that REQUIRES an underlying controller. I don't see this
> as being particularly elegant or useful.
A wxPython control/view will not require an underlying controller,
unless you're using MVC, of course. ;-) If you do want to use MVC,
though, yes, you absolutely need all three parts - a Model, a View,
and a Controller. I personally think that calling Bind to bind view
events to the controller for handling is not only useful but
necessary. You do have to write that code somewhere - the only
question is where. If it's not in your Controller class, then you're
either tying your view to your model, or vice-versa, and making both
less reusable with other controls because the controller parts will
need re-written for each view.
AFAICT, your goal seems to be cutting all connections between the
three components, but the reason we have the controller in the first
place is because there needs to be something that links the model and
the view together, and thus that must have knowledge of both of them.
Now, you can merge the controller into the view (or the model) if you
want, but the controller is still there (i.e. it's whatever code
responds to "CONTACT ADDED"). The only difference is that you've now
tied your view and model together, which IMHO is not a good thing if
you want to reuse that code in another view.
Regards,
Kevin
>
> Okay, sorry for the long post, but I wanted to contribute my ideas
> and ideally get some feedback as well.
>
> Thanks for reading, if you made it this far!
> - Mike Rooney
> _______________________________________________
> wxpython-dev mailing list
> wxpython-dev at lists.wxwidgets.org
> http://lists.wxwidgets.org/mailman/listinfo/wxpython-dev
More information about the wxpython-dev
mailing list