Publications»MVC Pattern

MVC Pattern

1. Model-View-Controller (MVC)

(or Model-View Separation principle) divides an interactive application into three components. The model contains the core functionality and data (model is a synonym for the domain layer of objects). Views displays information to the user, but are also the boundary that receives events and data from the user (view is a synonym for UI objects). Controllers handle and interprets user input (controllers are the workflow objects in the application layer). Views and controllers together comprise the user interface. A change-propagation mechanism ensures consistency between the user interface and the model when changes occur in the model.

1.1 Advantages

  • Layering, user interaction is separated from the the business logic. Do not connect or couple non-UI objects directly to UI objects.
  • The model objects should not have direct knowledge of view objects.
  • No application logic should be put in the UI object methods. UI objects should only initialize UI elements, receive UI events, and delegate requests for application logic on to non-UI objects (such as domain objects).


The first two bullets are accomplished by using the Observer pattern, it isolates the Model from referencing Views (and Controller) directly.

1.2 Model event

The change-propagation mechanism (Publisher-Subscriber or Observer pattern), all views and controllers register their need to be informed about changes in the model. Changes to the state of the model trigger the change-propagation mechanism. During initialization all views are associated with the model, and register with the change-propagation mechanism. Between views and controllers there is a one-to-one relationship. FIGUR!!!

1.3 View event

Implement the update procedure to reflect changes to the model. The easiest approach is to create a draw method. The draw method could either fetch or receive data. In addition to the update and draw methods, each view needs an initialization method. The initialization method subscribes to the change-propagation mechanism of the model and sets up the relationship to the controller.

  1. The user trigger some function which result in an event from the view to the controller.
  2. The UI class represents the visual user interface the user interacts with. The logic behind is done by the View class.
  3. The Controller interprets the event from the View, and activates a service in the Model.
  4. The Controller can have som logic attaced to the event it interprets. This could be enabling or disabling of certain user functions. The Control set the View depending on the state of the Model. E.g. a menuitem changes the displayed text when it is pressed.
  5. The Controller sends a response for the interpreted event to the View.
  6. The Service is received in the Model. E.g. this could be initializing the Model class.
  7. The Model performs the requested service, which is performing some logic. This result in a change to its internal data.
  8. When the Model is finished with the service request, it notifies its observers, by calling the update method.
  9. The observer (in this case the View, can also be the Controller) is notified (through the Update method) that the model has changed its data.
  10. The observer access the models interface and receive/request the new/updated data to be displayed.
  11. Each registered Controller retrieves data from the Model. (Same as 9 and 10).

FIGUR!!!

1.4 Model

The model component encapsulates core data and functionality. Responds to requests for information about its state (usually from the view), and responds to instructions to change state (usually from the controller). Registers dependent views and controllers. The model notifies all dependent components whenever its data changes (the Model is "observed" by the View). More concrete the Model will have a reference to the View. When the Model changes, it will call the Notify() method and pass a reference to itself and notify the View of a change by calling the Update() method of the View.

The model should provide and interface for the following:

  • access interface for modification of data, E.g. by a controller
  • factory functions for view access to data

1.5 View

View components display information to the user. A view obtains the data from the model. There can be multiple views of the model that presents the information of the model in different ways. For the View to be aware of changes in the Model, use the (GOF) Observer pattern. Each view defines and implements an update method that is activated by the change-propagation mechanism (the View is "observing" the Model). Each view creates and initializes it's associated controller.
makeController()

1.6 Controller

Each view has an associateted controller component. The controller ties the View and Model together. Controllers receive input, usually as events. Events are translated to serivce requests for the model or display requests for the view (E.g. enable or disable certain user function). Implements the update method if required.
From the View method that handle the user interaction, the Controller is called. All Controller methods should be prefixed with Request. The Controller method call the right Model method, and alternatively a SetView() method (local method in the Controller) that perform some business logic and thereafter a View method is called.
handleEvent()

1.7 Architecture Overview

User requests will be initiated from the View and handled by the Control.

So, now we have seperated the UI from the business logic, we take a step back an look at the architecture and the layer division. All interaction between layers should be defined in a contract.

UI Layer

View
Own project in Visual Studio. Possibly an executable.

AL Layer

Model and Control
Own project in Visual Studio. Most likly a Class Library.

PS Layer

Database and/or XML files

Circular dependencies

The Control points to View and Model, the View points to Control and further. When split into separate packages this gives us a circular dependency. The figur below describes how this could be avoided. The GUI package needs a reference to AL package to interact with it. Since the interface implementet by the GUI package is defined in the AL package, the AL package do not need a reference to GUI package when the interaction go through the interface. FIGUR

Contract

How sholuld a component in C# show its interface/contract? An contract that could be used in one layer or across layers.

If the Model, View and Controller are different Visual Studio project, we can get a problem with circular dependencies if we dont use interface. View has a reference to Control and possible Model, Control has reference to View and Model. Instead let the Control define the interface the View should implements, this will typically be the functions the Control want to call on the View. (This way the Control will work with new Views that implements the interface). The View will have a reference to the Control, the View will then give a concrete class reference (use interface) to the Control, since the Control know about the interface it dont need a reference to the View, and Control can now call metohods on the View. (TEST DETTE).

Through Class? In a component all Public methods in a Public class will be available for other components. So only methods that should be available for others should have Public visibility. This mean use Public Sealed for the public interface. In this way the public interface cannot be changed by the client. If the public interface are extended the client only have to recompile if it want to make use of the new functions in the interface. Functionality used between classes in the component should have Internal visibility. All other methods in a class should have private, protected internal or only protected if it should be inherited by a class in another component.

Well thats how modifiers can contribute to a clean interface, but how could we also make the code more readable? With C++ we had header files and different patterns to help us build clean interfaces. In C# we have partial classes, but the code and definition are all in one file.

I DONT AGREE ANYMORE!! A class definition can represent a components public interface to other component, following the rules in the previous section. There is no build dependencies either when using class and chaning the implementation in the component used by a client. But do we want the client to know directly about the implementation they are using. And across layers we want to decouple the layers, E.g. UI from AL and further. So we define and use interface for interaction between components. So the client initialize and interface and not a class, this will isolate interactions between layers. This will also result in more readable source code.

FIGUR!!!

1.8 Implementation

The Model, View and Controller can be designed as Interface.





2. Data-Access-Object (DAO)



Presentation-Abstraction-Control (PAC)
Especially applicable to systems that consist of several self-reliant subsystemes.

Good component design, split into layers, the MVC pattern support all of this. To get some reflection on how to use the pattern with C#, I will write some notes on this in the near future.

3.  References

[1] Frank Buschmann, Regine Meunier, Hans Rohnert, Peter Sommerland, Michael Stal. "Pattern-Oriented Software Architecture - A System of Patterns," 1996.
[2] Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides. Design Patterns - Elements of Reusable Object-Oriented Software (GoF), 1994.
[3] Craig Larman. Applying UML and Patterns - An Introduction to Object-Oriented Analysis and Design and Iterative Development, 2005.
[4] CoderSource.NET - Model View Controller
[5] C# Corner - Introduction to Model View Controller (MVC) Pattern using C#
[6] MSDN - Model-View-Controller
[7] MSDN - Implementing Model-View-Controller in ASP.NET
[8] CodeProject - Model View Controller Using C#, Delegates and Events in .NET
[9] MSDNMag - Model View Presenter (MVP) pattern