I have a question about MVC pattern, concerning the controller part.

Most of the program I happen to write are basically spreadsheet like. They are written in C/GTK+ and Python3/Qt5/Tkinter but share a common design : I separate the gui from the logic (data struct and heavy lifting methods) that seems to be the MVC pattern.

Question Do I really need to pass data from view to model each time I edit the GUI data and want to compute something ? Then pass the new data back from model to view ? Is that how it should be done ? I understand this is fine for a small GUI that does heavy computation in the model. But what about a big GUI, like a big table or a spreadsheet.

Answer Here are the elements that I took from the discussion with @dcorking: You have to update the data yourself. One shortcut is to update on a per-case basis, only what needs to be updated and don't touch the rest. Obviously, if you are sorting the collection after a single change, you may need to re-update the whole GUI eitherway. "Observers" have been mentionned that sounds like an automated way to do as above.

Pseudo/Python Code

Let's consider a basic collection of items (shopping list, book library, ...). My main class Collection contains a list (dozens or hundreds) of Item and methods to be applied on the list.

#The model package

class Collection():
    def __init__(self, name=""):
        self.name = name
        self.items = []
        self.itmesToUpdate = []

    def sort(self):
        self.items.sort(key=lambda x:float(x.price))
        self.itemsToUpdate = []
        self.itemsToUpdate = listItemsThatWereMovedAround()

class Item():
    def __init__(self, name="", price=0.):
        self.name = name
        self.price = price

Now the Gui part:

class Gui():
    #The View part.
    def __init__(self):
        self.collection = model.Collection()
        ...then fill the View with widgets (Menus, EditTexts, Buttons, ...)

    #The Controller part starts here
    def setViewFromModel(self):
        for i in self.collection.itemsToUpdate:
            self.editTextName[i].setText(self.container.items[i].name)
            self.editTextPrice[i].setText(self.container.items[i].price)
        self.collection.itemsToUpdate = []# reset the list

    def setModelFromView(self):
        for i in self.collection.itemsToUpdate:
            self.container.items[i].name = self.editTextName[i].getText()
            self.container.items[i].price = self.editTextPrice[i].getText()

    #CALLBACKS
    def onItemModified(self, index):
        self.collection.itemsToUpdate.append(index)

    def onClickSort(self):
        self.setModelFromView()#Read the GUI data
        self.collection.sort()#Compute in Model
        self.setViewFromModel()#Update the View with new data

Is this design fine ? For spreadsheet-like app ? Thank you.

有帮助吗?

解决方案

MVC does not tell you how small to make the models.

For a spreadsheet, when you find that passing the whole data structure between a View and a Model is too slow, or makes the code too complex, you could make an MVC triad to represent something as small as a single cell.

The model part of the cell could then connect in some appropriate way to a larger business object that represents the entire sheet.

Similarly, the cell views will be embedded in another view to represent a sheet, or a window onto a sheet.

Update

The main aim of MVC is not to improve performance, but to make the code more understandable, and therefore easier to maintain.

If you make an MVC triad for each individual cell, this should be easier to understand and modify than if the triad represents a whole column, or the entire sheet. However, performance may suffer for changes that affect the entire sheet, as you may end up with many small objects sending messages to each other.

One alternative to MVC that you might also want to consider if you want to avoid passing data between Views and Models is direct manipulation. In direct manipulation, the object the user interacts with is the object that stores the business data (the cell value) and the business rules (how the cell value can change.)

许可以下: CC-BY-SA归因
scroll top