111111
111111

Reputation: 16168

Good design practice concerning MVC view interface

I don't often have to create GUI's but today I do so I was hoping for some design input.

Basically I have a backend which I intend to add a GUI too using the MVC pattern. The issue is I feel whatever class encapsulates the main GUI window is going to have A LOT of state (all of the sub elements); and on top of that it's going to have a lot of setters, and possibly getter, clear, colour, size, position and refresh functions too.

Any input on the matter would be of great help.

If it makes any difference this is a C++ gui using an ncurses abstraction.

Upvotes: 1

Views: 1397

Answers (3)

Open AI - Opting Out
Open AI - Opting Out

Reputation: 24153

I like to have parts of the model able to instrument themselves:

class Model {
private:
    int value;
public:
    void instrument(Instrumenter& instrumenter);
};

The Instrumenter manages the creation of controls. The model will tell it how it can be controlled and give it access to the data.

void Model::instrument(Instrumenter& instrumenter) {
    instrumenter.addRangeController(0, 100, 5, value);
}

Then for different input devices (e.g keyboard, touchscreen) you can create appropriate controls:

class KeyboardInstrumenter : public Instrumenter {
public:
    void addRangeController(int min, int max, int increments, int& controlled) {
        // create 3 widgets, up arrow, down arrow, and value
    }
};

class TouchscreenInstrumenter : public Instrumenter {
public:
    void addRangeController(int min, int max, int increments, int& controlled) {
        // create slider with min, max and increments
    }
};

Instead of passing in the int directly we could have wrapped it in a controlling object, to aid encapsulation.

Upvotes: 0

David D
David D

Reputation: 1591

There is at least one alternative to the giant interface. Instead of having a function that handles each thing (size, font, color, what-to-display, etc...) have a singular function that accepts a "role" and data that represents the role. This requires some sort of wrapper that can contain multiple data types.

QT's QAbstractItemModel Class Reference has a good example:

QVariant QAbstractItemModel::data ( const QModelIndex & index, int role = Qt::DisplayRole ) const [pure virtual]

What that function will do is return the QVariant that represents the role indicated at the index provided.

The downside of this approach, is you have to know what roles exist, and what they do. QT's default roles are shown here.

Upvotes: 0

HackyStack
HackyStack

Reputation: 5157

It sounds like to me you've thought alot about the M and the V, but not much about the C. The pattern should really be called MCV because the whole idea is that the controller IS the bridge between your model (data) and view (GUI). It sounds like you need a controller with most of the functionality you've mentioned.

Simply put though, your model obviously should know nothing about display and your display (view) should not know how to access the model. You need a controller that reads the data (model) and gives instructions to the display (view). If you have user interaction within the view, the controller can interpret that and modify the model as necessary.

The idea is that you never have to change all 3, but if you change the model or the view, you almost always have to update the controller.

Hope that helps...

Upvotes: 2

Related Questions