There are three types of objects. The Model is our application data, the View is a screen, and the Controller defines the way the View reacts to user input. The views and models use the Publish-Subscribe protocol - when Model data is changed, it will update the View. It allows us to attach multiple Views to the same Model [2]. This is achieved by using the Observer design pattern.
The goal of this pattern is to define the one-to-many relationship between the Subject and the Observers; if the Subject is changed all Observers are updated. The Subject maintains the list of the Observers and can attach and detach objects to the list. The Observer in return exposes an
Update
method on its interface that Subject can use to update all objects it observes. The C# implementation would look like this:public abstract class Subject
{
private readonly ICollection<Observer> Observers =
new Collection<Observer>();
public void Attach(Observer observer)
{
Observers.Add(observer);
}
public void Detach(Observer observer)
{
Observers.Remove(observer);
}
public void Notify()
{
foreach (Observer o in Observers)
{
o.Update();
}
}
}
public class ConcreteSubject : Subject
{
public object SubjectState { get; set; }
}
public abstract class Observer
{
public abstract void Update();
}
public class ConcreteObserver : Observer
{
private object ObserverState;
private ConcreteSubject Subject { get; set; }
public ConcreteObserver(ConcreteSubject subject)
{
Subject = subject;
}
public override void Update()
{
ObserverState = Subject.SubjectState;
}
}
The other component of the MVC pattern is the View-Controller relationship.The View uses the Controller to implement a specific type of response.
The controller can be changed to let the View respond differently to user input.
This View-Controller link is an example of the Strategy design pattern.
Each ConcreteStrategy encapsulates a particular type of response.A Context object has a reference to a Strategy object and can
forward the requests to a specific Strategy though the common interface.
Here is a C# code:
public abstract class Strategy
{
public abstract void AlgorithmInterface();
}
public class ConcreteStrategyA : Strategy
{
public override void AlgorithmInterface()
{
// code here
}
}
public class Context
{
private readonly Strategy Strategy;
public Context(Strategy strategy)
{
Strategy = strategy;
}
public void ContextInterface()
{
Strategy.AlgorithmInterface();
}
}
Now we know that the Model acts as a Subject from the Observer pattern and the View takes on the role of the Observer object. In the other relationship of the MVC, the View is a Context and the Controller is a Strategy object. Combining our knowledge of the two diagrams, we can draw the MVC UML class diagram as below:
Here is the implementation code for the MVC pattern:public abstract class Model
{
private readonly ICollection<View> Views = new Collection<View>();
public void Attach(View view)
{
Views.Add(view);
}
public void Detach(View view)
{
Views.Remove(view);
}
public void Notify()
{
foreach (View o in Views)
{
o.Update();
}
}
}
public class ConcreteModel : Model
{
public object ModelState { get; set; }
}
public abstract class View
{
public abstract void Update();
private readonly Controller Controller;
protected View()
{
}
protected View(Controller controller)
{
Controller = controller;
}
public void ContextInterface()
{
Controller.AlgorithmInterface();
}
}
public class ConcreteView : View
{
private object ViewState;
private ConcreteModel Model { get; set; }
public ConcreteView(ConcreteModel model)
{
Model = model;
}
public override void Update()
{
ViewState = Model.ModelState;
}
}
public abstract class Controller
{
public abstract void AlgorithmInterface();
}
public class ConcreteController : Controller
{
public override void AlgorithmInterface()
{
// code here
}
}
If we leave out the concrete classes for simplicity, we will get a more familiar MVC diagram.
Please note that we use pseudo- rather than proper UML shapes,
where circles represent a group of classes (e.g., Model and ConcreteModel),
not classes as on the UML class diagram on Figure 3.