The Model-View-Controller Pattern

Other Names

MVC, Model-View-Controller architecture, Model-View architecture, Model-View Separation pattern, Document-View architecture.

Problem

User interface is the component most susceptible to change. These changes shouldn't propagate to application logic and data.

Solution

Encapsulate application logic and data in a model component. Presentation logic and data is encapsulated in associated view-controller components. There are no direct links from the model to the view-controllers.

Static Structure

Object Diagram

In a spread sheet application the model's state is a two-dimensional array of cells containing numbers and formulas. Typical views include pie charts, bar graphs, and work sheets. Typical controllers include menus, toolbars, and dialog boxes.

A UML object diagram shows instances of classes (objects) and associations (links) appearing in the class diagram.

Another Problem

How will the model notify its views that its state has changed if it has no direct links to its views and the number and types of views vary dynamically?

We can use the publisher-subscriber pattern to solve this problem. Views should subscribe to an event manager component or a publisher base class component that will notify them of the model's state changes.

Dynamic Structure

Implementing the Model and View

class Model: public Publisher {
public:
   void setState(const State& newState) {
      state = newState;
      notify(); // notify subscribers of state change
   }
   State getState() const { return state; }
   // etc.
private:
   State state;
};

class AView: public Subscriber {
public:
   AView(const Model* m) {
      myModel = m;
      myModel->subscribe(this);
   }
   ~AView() { myModel->unsubscribe(this); }
   void update() {
      repaint(myModel->getState(), ...);
   }
   void repaint(const State& s, ...); // draws view's window
private:
   Model* myModel;
};