Proper MVC

Registered by Michael Rooney on 2008-05-29

The current model-view-controller architecture was a good idea but wasn't implemented well. It uses pubsub, which is a great way to do it, but it uses it incorrectly. The announcements are made in the GUI and really only picked up on by other GUI parts, while the model calls methods on the controller directly, which makes no announcements.

Method 1: When something happens in the GUI, it should make an announcement, but not actually DO anything else. If the user clicks the remove account button, show the proper warning, and if they agree, send the appropriate pubsub message. Don't actually remove anything. Then the controller picks up on this message, does the appropriate things with the model, and sends a message an account was removed. The GUI picks up on this and actually removes the item. All is well!

The problem with this method is that the GUI requires a controller to exist and do something, and send back the message. In theory, shouldn't the GUI be able to exist on its own, allowing the user to remove and add items in it whether or not anything is listening or doing anything?

Method 2: 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). 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.

This method isn't as simple or clean perhaps, but makes the messaging simpler in ways, and allows for components to be more independent. Also it allows for there to be multiple views/controllers and everything should work fine. For example if an account is removed, whether in controller or GUI, another GUI will respond to the first message about it, do the appropriate thing, and ignore the rest.

Blueprint information

Status:
Complete
Approver:
None
Priority:
Essential
Drafter:
None
Direction:
Needs approval
Assignee:
Michael Rooney
Definition:
Approved
Series goal:
None
Implementation:
Implemented
Milestone target:
milestone icon 0.5
Started by
Michael Rooney on 2008-07-11
Completed by
Michael Rooney on 2009-02-01

Related branches

Sprints

Whiteboard

michael: After researching MVC more (http://en.wikipedia.org/wiki/Model-view-controller), I remember that the view is supposed to be really dumb, so Method 1 might not be inappropriate at all.

On the other hand I see no problem with a wxPython GUI that knows how to update itself based on user input, as long as it has no coupling or clue about any underlying structure. I really like the idea of a View being able to exist on its own, and inherent support of multiple Views and Models with zero extra work.

I will do some more thinking and probably go with whichever solution seems more elegant and robust.

I think much of what I put in the controller may belong in the Model. A way to alter this would be to have a BaseModel class which performs the business logic, with subclasses handling specific persistence mechanisms:

class BaseModel:
    def addAccount(accountName):
        if accountName in self.getAccounts():
            raise Exception
        else:
            self._addAccount(accountName)

class XMLModel(BaseModel):
    def _addAccount(self, accountName):
        self.xml += "<Account>%s</Account>"%accountName

...or something like that.

2008.07.11 michael: Okay, I think an acceptable solution for now is to continue calling controller functions from the view but move the messaging to the controller, and have the view subscribe where appropriate, not assuming every change always comes from itself. This is more sane.

2008.10.12 michael: This will probably be fully implemented if/when the OLV branch gets finished and merged.

2009.01.31 mrooney: okay phew, this is done in 0.5.

(?)

Work Items

This blueprint contains Public information 
Everyone can see this information.