Software Design Patterns

Florian Rappl, Fakultät für Physik, Universität Regensburg

Software Design Patterns

Introduction to modern software architecture

software architecture

Presentation patterns

Introduction

  • Most applications consist of several layers:
    1. The view that is visible to the user
    2. The data that is presented or manipulated
    3. 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

skinparam classAttributeIconSize 0
class Model {
  +state
}
abstract class View {
}
class ConcreteView extends View {
  +model: Model
}
abstract class Controller {
}
class ConcreteController extends Controller {
  +action()
}
ConcreteController --> Model
ConcreteView --> Model
ConcreteController -> ConcreteView
View -> Controller

Remarks

  • Different aspects of an application are kept separate by using MVC
  • Benefits of such a separation:
    1. The separation of concerns is required for decoupling
    2. 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
    3. Different developers (with different skills) may be responsible for different aspects of the application (e.g. designers for the view)

MVC in action

mvc.png

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

skinparam classAttributeIconSize 0
abstract class Presenter {
}
class ConcretePresenter extends Presenter {
  +action()
}
class Model {
  +state
}
abstract class View {
}
class ConcreteView extends View {
  +stateHolder
}
ConcretePresenter -> Model
View -> Presenter
ConcretePresenter ..> ConcreteView

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

mvp.png

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:
    1. Passive view
      • Interaction is only handled by the presenter
      • View is updated exclusively by the presenter
    2. Supervising controller
      • The view interacts with the model (simple binding)
      • View is updated by the presenter through data-binding

Supervising MVP

mvp_super.png

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

skinparam classAttributeIconSize 0

abstract class View {
}
class ConcreteView extends View {
  +stateHolder
}

interface ViewModel {
  +stateChanged()
}

class ConcreteViewModel implements ViewModel {
  +stateChanged()
  +stateProxy
}

class Model {
  +state
}

ConcreteViewModel -> Model
View .> ViewModel

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

mvvm.png

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:
    1. the MVA (Model-View-Adapter) and
    2. 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

mva.png

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

pca.png

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.