Software Design Patterns
Florian Rappl, Fakultät für Physik, Universität Regensburg
Software Design Patterns
Introduction to modern software architecture
Presentation patterns
Introduction
- Most applications consist of several layers:
- The view that is visible to the user
- The data that is presented or manipulated
- The logic that is responsible for driving the application
- Presentation patterns try to decouple these layers
- Additionally they aim for a maximum of flexibility
- Ideally they also support portability
Terminology
- The classes carrying the data are often called models
- A model is usually logic-free (a plain container)
- The various patterns now just differ in how these models are used
- Some use a controller to connect model and view
- Others use a presenter to actively modify the view with the model
- Then there are highly dynamic models that bridge the two like in MVVM
Model-View-Controller
- First appearance in the first GUI created by Xerox (Smalltalk)
- A controller connects model and view
- A view uses a model to generate an output representation
- A model contains information
- In a passive MVC the model is silent, however, in active MVC the model can send notifications (e.g. events) when changing
- These events can then be used by the controller or the view
MVC diagram
Remarks
- Different aspects of an application are kept separate by using MVC
- Benefits of such a separation:
- The separation of concerns is required for decoupling
- An application might have more than one representation (client, console, web) and the elements of the user interface need to be kept separate from the parts that are common to each
- Different developers (with different skills) may be responsible for different aspects of the application (e.g. designers for the view)
MVC in action
Model and view
- Model:
- Represents data and rules that govern access to and updates of it
- Simple real-world modeling techniques apply when defining the model, since usually it is basically a real-world approximation
- View:
- Renders the contents of a model
- Accesses data through the model and chooses data representation
- Responsible for maintaining consistency when the model changes
The controller
- The controller translates interactions with the view into actions
- These actions are performed by the model
- e.g. in a stand-alone GUI client, user interactions could be button clicks, whereas in a web app, they appear as HTTP requests
- The actions performed by the model include activating business processes or changing the state of the model
- Based on the user interactions and the outcome of the model actions, the controller responds by selecting an appropriate view
Web implementation
- A class (called router) is required to interpret incoming requests and direct them to the appropriate controller
- The corresponding method (called action) is then called
- The controller might update the model based on the request
- Finally a response in chosen in form of a view, which might be HTML
- This requires access to some class that can be used to display the appropriate view
Guess a number
public interface IView<T> where T : Model
{
T Model { get; set; }
BaseController Controller { get; set; }
}
public abstract class BaseController
{
public abstract void Command(string value);
}
public class Model
{
public event EventHandler Changed;
protected void RaiseChanged()
{
if (Changed != null)
Changed(this, EventArgs.Empty);
}
}
class GuessModel : Model
{
string name;
int maxtrials;
int numtrials;
string lastname;
public string Name
{
get { return name; }
set { name = value; RaiseChanged(); }
}
public bool IsCorrect
{
get { return lastname == name; }
}
public int MaxTrials
{
get { return maxtrials; }
set { maxtrials = value; RaiseChanged(); }
}
public int NumTrials
{
get { return numtrials; }
}
public void EnterTrial(string name)
{
numtrials++;
lastname = name;
RaiseChanged();
}
}
public abstract class ConsoleView<T> : IView<T> where T : Model
{
T model;
public T Model
{
get { return model; }
set
{
if (model != null) model.Changed -= ModelChanged;
if (value != null) value.Changed += ModelChanged;
model = value;
RaiseModelChanged(model);
}
}
public BaseController Controller { get; set; }
protected void PrintOutput(string output)
{
Console.WriteLine(output);
}
void ModelChanged(object sender, EventArgs e)
{
RaiseModelChanged(model);
}
protected abstract void RaiseModelChanged(T model);
}
class GuessMyNameView : ConsoleView<GuessModel>
{
protected override void RaiseModelChanged(GuessModel model)
{
if (!model.IsCorrect)
{
if (model.NumTrials == model.MaxTrials)
{
PrintOutput(string.Format("The name {0} would have been correct!", model.Name));
}
else
{
PrintOutput(string.Format("Trial {0} / {1}. What's the name?",
model.NumTrials + 1, model.MaxTrials));
var input = Console.ReadLine();
Controller.Command(input);
}
}
else
{
PrintOutput(string.Format("The name {0} is correct (guessed with {1} trials)!",
model.Name, model.NumTrials));
}
}
}
class GuessMyNameController : BaseController
{
IView<GuessModel> view;
GuessModel model;
public GuessMyNameController(IView<GuessModel> view, GuessModel model)
{
this.view = view;
this.model = model;
this.view.Controller = this;
}
public void Start()
{
view.Model = model;
}
public override void Command(string value)
{
model.EnterTrial(value);
}
}
Practical considerations
- Today MVC is mostly used in web development
- Popular frameworks contain a very useful basis
- ASP.NET MVC (.NET)
- Rails (Ruby)
- Spring (Java)
- AngularJS (JavaScript)
- CakePHP (PHP)
- Usually writing an MVC framework from scratch is not recommended
Model-View-Presenter
- In contrast to MVC, all presentation logic is pushed to the presenter
- A model is an interface defining the data to be displayed
- A view is a passive interface that displays data (the model) and routes user commands (events) to the presenter to act upon that data
- A presenter acts upon the model and the view
- The presenter formats data for display in the view
- There is a single presenter for each view
MVP diagram
Remarks
- Real two-way communication with the view
- Every view implements some sort of
View
interface - In the view an instance of the presenter is referenced
- Events are forwarded to the presenter by the view
- The view never passes view related code (e.g. UI controls) to the presenter
MVP in action
Model and view
- Model:
- Communication with DB layer
- Raising appropriate event when dataset is generated
- View:
- Renders data
- Receives events and represents data
- Have basic validations (e.g. invalid email, ...)
The presenter
- Decouples a concrete view from the model
- Supports view in complex decisions
- Communicate with model
- Complex validations (e.g. involve other data sources)
- Queries model
- Retrieves data from model, formats it and sends them to the view
- The view is updated through the same event approach that MVC uses
Implementation concept
public interface IUserView
{
void ShowUser(User user);
}
public partial class UserForm : Form, IUserView
{
UserPresenter _presenter;
public UserForm()
{
_presenter = new UserPresenter(this);
InitializeComponent();
}
private void SaveUser_Click(object sender, EventArgs e)
{
User user = ConstructUser();
_presenter.SaveUser(user);
}
/* ... */
}
public class UserPresenter
{
IUserView _view;
public UserPresenter(IUserView view){
_view = view;
}
public void SaveUser(User user)
{
/* ... */
}
/* ... */
}
Practical considerations
- Today MVP is mostly used in client development
- Popular frameworks contain a very useful basis like MVC# (.NET, strange name) or GWT (Java for web development)
- In general the difference to MVC is subtle
- Sometimes the general outline looks like MVP, but it is in fact MVC
- As with MVC it is not necessary to start writing a custom framework
- Today MVVM is more popular for client development
MVP modes
- There are two main modes for MVP:
- Passive view
- Interaction is only handled by the presenter
- View is updated exclusively by the presenter
- Supervising controller
- The view interacts with the model (simple binding)
- View is updated by the presenter through data-binding
- Passive view
Supervising MVP
Model-View-ViewModel
- MVVM tries to gain the advantages of MVC (separation) and data-binding
- A model has practically the same role as a model in MVC
- The view is also just the pure representation as with MVC
- A ViewModel is an abstraction of the view, that serves as target for data binding (kind of a controller, but only for data conversion)
- The role of the controller or presenter is now outsourced in a generic Binder, which is responsible for updating the UI or model (two-way)
- The binder is provided by the framework and should not be touched
MVVM diagram
Remarks
- First implementation of MVVM is in the WPF framework
- Here we have two-way communication with the view
- The VM represents the view in a representation independent way
- The view binds directly to the ViewModel
- A single ViewModel should be used for each view
- Since the binder is the actual key part the pattern is sometimes called MVB (Model-View-Binder)
MVVM in action
The ViewModel
- It is the model of the view
- Could be seen as a mediator between view and model
- Contains the generic data binding capabilities that can be used by the view (binding to the conceptual state of the data)
- It could be seen as a specialized aspect of what would be a controller in the original MVC pattern
- Acts as a converter that changes model information into view information and passes commands from the view into the model
A very simple ViewModel
public class StudentData : INotifyPropertyChanged
{
string _firstName;
double _gradePointAverage;
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public string StudentFirstName
{
get
{
return _firstName;
}
set
{
_firstName = value;
OnPropertyChanged("StudentFirstName");
}
}
public double StudentGradePointAverage
{
get
{
return _gradePointAverage;
}
set
{
_gradePointAverage = value;
OnPropertyChanged("StudentGradePointAverage");
}
}
}
Practical considerations
- Usually one does not directly implement the interface
- Abstract base classes with useful helpers are preferred
- Instead of naming the changed property with a string strong names should be used (compiler generated or reflection)
- Commands also need some kind of special interface, which is usually called ICommand or similar
- A command usually consists of a run and canrun method
- The latter determines the state of buttons which invoke the command
When to use what
- MVC
- Connection between the displayed view and the rest is impossible
- If there could be no binding context
- MVP
- General binding is not possible, but specialized binding is
- Use in situations like MVC, but where a connected view exists
- MVVM
- General binding is possible and realized automatically
- The view is directly connected and highly interactive
More patterns
- There are many more presentation patterns
- However, differences are even more subtle
- The two most important other presentation patterns:
- the MVA (Model-View-Adapter) and
- the PCA (Presentation-Abstraction-Control)
- They are also quite close to the original MVC pattern
- It is more natural to see them as an extension of MVC
Model-View-Adapter
Remarks
- Here the adapter is a real adapter, acting as a mediator between model and view
- This breaks the classic MVC triangle
- Chance: The view is completely decoupled from the model
- Pitfall: The adapter is strongly coupled on both
- To solve this one might use multiple lightweight adapters
Presentation–Abstraction–Control
Remarks
- Quite close to MVA, however, control and abstraction are stronger coupled
- Main difference: Division into independent PCA cells
- The abstraction component retrieves and processes the data
- Generally this is an hierarchical layout
- A PCA controller can with other PCA controllers (children)
- Addtionally it handles the flow of control and communication between presentation and abstraction
Literature
- Buschmann, Frank; Meunier, Regine; Rohnert, Hans; Sommerlad, Peter; Stal, Michael (1996). Pattern-Oriented Software Architecture Vol 1: A System of Patterns.
- Garofalo, Raffaele (2011). Building Enterprise Applications with Windows Presentation Foundation and the Model View ViewModel Pattern.
- Guermeur, Daniel; Unruh, Amy (2010). Google App Engine Java and GWT Application Development.