The Model-View-Controller (MVC) pattern has become a familiar one application design where a graphical user interface is used.
An application is seen as a data manipulator, and operations on the data are requested through a user interface. The data is stored in a Model which has a public interface through which the stored data can be retrieved and altered. The Model is Viewed through a user interface that provides both a passive display and an active interface. Very often the View is implemented using the Observer pattern - the Model is observed by the view, and the View changes when the Model changes. The Controller is the part of the system that mediates between the Model and the View. It translates Model changes into operations on the View. It also usually creates the view in the first place.
In the sample system presented here a repetiive pattern of sounds - a "beat" is produced in a Model that interfacesd with the MIDI (Musical Instrument Digitial Interface) subsystem in Java. The changeable data stored in the Model is simply the number of beats per minute. The View consists of a passive display of the number of beats per minute and a progress bar showing the pulsing of the beat, and an active interface that can request a change in the beats per minute, and also start and stop the beats. The two aspects of the View are set up as observers of the Model. The essential elements of the Model are:
class BeatModel {
Sequencer sequencer;
ArrayList beatObservers = new ArrayList();
ArrayList bpmObservers = new ArrayList();
int bpm = 90;
Sequence sequence;
Track track;
...
}
sequencer, sequence and track contain the MIDI information; beatObservers is a list (actually only one) of observers of the beat changes; bpmObservers is a list of beats per minute observers. Beats per minute are changed by:
public void setBPM(int bpm) {
this.bpm = bpm;
sequencer.setTempoInBPM(getBPM());
notifyBPMObservers();
}
This method changes the BPM, sets the MIDI track to play back at this tempo and notifies the BPM observers to update the display. It implements the Controller interface:
The Controller encapsulates the Model and the View:
class BeatController implements ControllerInterface {
BeatModelInterface model;
DJView view;
...
}
When the Controller is created it is passed the Model reference, creates the view and initializes the Model:
public BeatController(BeatModelInterface model) {
this.model = model;
view = new DJView(this, model);
view.createView();
view.createControls();
view.disableStopMenuItem();
view.enableStartMenuItem();
model.initialize();
}
The view itself consists of a reference to the Controller, the View and various interface elements. I implements the observer interfaces:
class DJView implements BeatObserver, BPMObserver {
BeatModelInterface model;
ControllerInterface controller;
JFrame viewFrame;
JFrame controlFrame;
...
}
The client driver simply creates the Model object and the Controller object which starts the whole system:
public class DJTestDrive {
public static void main (String[] args) {
BeatModelInterface model = new BeatModel();
ControllerInterface controller = new BeatController(model);
}
}
You can view complete code for the system