What does MVC stand for

8.2 The presentation layer: model, view, controller (MVC)

A very significant part of the functionality of object-oriented systems also takes place in the interaction with the software user. There are different approaches for modeling this interaction in the presentation layer. The so-called MVC approach (Model-View-Controller) is the most widespread.

Model-View-Controller (MVC) describes an interaction pattern in the presentation layer of software. MVC is probably one of the most colorful terms in the field of object-oriented programming. Many variants have emerged, partly simply due to a wrong understanding of the original MVC pattern, partly as a further development or adaptation to new use cases.

Since MVC is still the most important and most widespread pattern for the presentation layer of object-oriented applications, we will go into it in detail in this chapter.

8.2.1 The observer pattern as the basis of MVC

A very central type of information in object-oriented systems is the information that an object has changed its state.

Interactions in the presentation layer

The interactions that arise here can be complex. However, according to the principle of responsibility, you should avoid the objects concerned having to know each other. For such cases it is advisable to use the design pattern »observed - observer«. The pattern is also called the observer pattern for short. In Section 5.4, "Multiple Inheritance", we already presented an example. Figure 8.1 shows the classes involved in the application of the pattern again in the overview for the general case.

Figure 8.1Observer and observed objects

The figure shows that the observers can register via the operation (). When they have done this, they are informed of changes in the state in the observed object. This is done by the fact that this object calls its own operation after changes have been made (). This will go through all registered observers and call their operation update (). This means that all observers have the opportunity to react to the change in state.

Within MVC, the pattern is used to communicate changes to a model to the objects that represent the model, the so-called views. The models should not have to know anything about which objects they are being represented by.

8.2.2 MVC in Smalltalk: As it was originally

For an overview, let's start right at the beginning: MVC was introduced together with the object-oriented programming language Smalltalk. MVC was originally a concept that was supposed to cleanly separate the interactions of a user (especially via mouse actions) from the data and its representation that were changed by it.

Controller: processing of inputs

The controller is responsible for processing the inputs (e.g. mouse clicks) and for communicating them to the model. The model is passive, it is questioned and modified by the controller. The view [It is common to use the English term view for a display component. However, there is disagreement as to whether the article should now be selected as "the view" or "the view". In the following, we will use the version of "the view". ] asks the model in order to adapt its representation on this basis.

As shown in Figure 8.2, the relationship between the view and the controller is clearly defined: They always appear as a pair, and each knows the other. However, a model can be managed by any number of view / controller pairs, which opens up the possibility of different views of the same model.

Figure 8.2Relationship between model, view and controller in Smalltalk

The interaction via the observer pattern takes place between the model and the view. Figure 8.3 shows how the pattern is used for these two components to work together.

Figure 8.3Observer pattern in MVC

In the example shown, changes to a customer model are communicated to all participating views. In this case, a customer has only assigned a name. If this name is changed, the model calls the Update operation. If KundenHtmlView has registered with the model by calling the operation () as an observer, he will be notified and can adjust the display of the name in the update method ().

8.2.3 MVC: Clarification of terms

Although the separation of model, view and controller originally introduced in Smalltalk is quite clear, in discussions we will encounter very different understandings of what a model and what a controller is.

One of the reasons for this is that certain tasks, for which a controller in Smalltalk, for example, was responsible, are now taken as a matter of course. That's why we first clarify what is meant by model, view and controller.

What actually is a controller?

A controller has a very generic task in MVC: It must receive the interactions of a user via the various input options such as keyboard or mouse and forward them in a consolidated form.

Controller in MVC (input controller)

In the MVC variant of Smalltalk, a controller has the task of isolating the application from the complexities of the input mechanisms. For example, he is responsible for assigning mouse events to a specific screen area.

The functionality of the controller is now mostly integrated quite naturally in basic libraries that application programmers usually don't even see.

As a rule, you no longer need an explicitly specified controller to assign a mouse click to a specific input element of a view. These things are usually done for you by modules that are integrated in the operating system or basic libraries.

We use the term input controller to refer to this type of controller. However, an application developer rarely has to deal directly with input controllers.

You should also differentiate the input controller as clearly as possible from an application controller that controls processes within an application. For example, this is responsible for determining a subsequent dialog based on user input. However, this has little to do with its original use in MVC. Even in Smalltalk, MVC was never a complete architecture model, but a solution for a very specific sub-task: to separate the interactions in the presentation layer neatly.

So what exactly is a model?

There are also occasional ambiguities with regard to the model within MVC. This may also be due to the fact that practically every object can act as a model, especially in Smalltalk.

However, this only means that, at least in theory, every Smalltalk object can be displayed and react to messages that may cause a change in status. However, it is crucial that the model manages the state of the entire construct and serves as a reference for the representation.

As a rule, the model will make use of additional components, which then implement the technical functionality, but the model itself is only defined by the properties mentioned above.

Model in MVC

A model in MVC must therefore have the following properties:

  • It must be able to manage a state.
  • It must be representable.
  • It must be able to respond to requests for changes.

A model thus initially has absolutely nothing to do with the logic in the domain, not even necessarily with persistence.

And finally the view

Views in the MVC model are the components that are responsible for displaying the model. The types of representation are not restricted. In principle, a view could also read out the data of the model using a speech generation module. In this case, however, the designation View no longer appears completely adequate.

Views should only deal with the presentation and should not contain any technical logic if possible. However, in some cases functions of the controller are integrated into the view.

View and controller combined

Controllers usually do very uniform tasks. Smalltalk already has a small set of standard controllers, each of which is then assigned to a view and a model.

With the Microsoft Foundation Classes (MFC) as well as with the Java user interface library Swing, the controller is no longer an independent entity. At Microsoft the whole thing is called Document View, at Swing the process is sometimes called Model Delegate.

Even if the terms are a bit confusing here, both cases involve modeling in which view and controller coincide. At Microsoft in the View, at Swing in the Delegate - the user interface component that is responsible for displaying and handling user input.

Caution, trap number 1: MVC is not a layered model

We have often found an interpretation of MVC in practice and in the literature that, in our opinion, is simply wrong.

MVC is a pattern for interactions in the presentation layer. It already assumes that we have fundamentally accepted an architecture that provides layers and separates the presentation from the rest of the application.

MVC is not a complete architecture.

In practice and in the literature, however, we have often seen an interpretation of MVC that elevated this pattern to a complete architecture for an application. In addition, the role of the model is often overstretched by assigning responsibility for business logic, persistence or other central aspects to it.

Under no circumstances should you confuse MVC with the layered architecture. This is because the model is not responsible for implementing the application logic layer. Of course, both tasks (provision of the application logic and representability in the presentation layer) can in practice be taken over by the same objects. So you can of course use an Enterprise Java Bean as a model to represent it directly via the presentation layer. The model property is still completely independent of the other properties of the EJB, such as B. the ability to make data persistent.

Caution, trap number 2: Not every view needs its own controller class

Due to the existing 1: 1 connection between views and controllers in MVC, one could easily get the idea that this relationship could apply not only to the instances but also to the classes.

However, this was never planned that way in the original version of MVC in Smalltalk. There each view is assigned its own special copy of a controller, since a controller also has a status that is directly related to the view. But there were a small number of controller classes in Smalltalk, and their instances were created along with their specific views.

In Smalltalk, the controllers were also responsible for tasks that you usually no longer perceive as a task when developing an application because they are taken over by libraries, which we now take for granted. As a rule, you no longer have to deal with how you can determine from the coordinates of a mouse click which element of the surface is affected and how. But that was one of the tasks of controllers in the original MVC.

8.2.4 MVC in web applications: called »Model 2«

With reference to web applications, use of the MVC pattern is also spoken of. Sun introduced two flavors of the recommended MVC pattern, called Model 1 and Model 2, in early versions of the J2EE specification. [Pronounced as Model One and Model Two. ] These terms have remained, although they are no longer included in the specification.

Model 1

Model 1 is a very simple variant, with access to models (mostly Java Beans) directly from JSP pages [JSP (Java Server Pages) are a standardized mechanism by which Java code can be integrated into HTML pages. A JSP page is an HTML document that is dynamically modified and enriched with data when it is displayed. ] take place out. The following figure shows an interaction based on this model.

Figure 8.4Model 1 for web applications

Model 1 is very simple and straightforward, but only recommended for relatively small applications. Changes to the navigation structure through the various pages can only be carried out with great effort, as this requires direct intervention in the JSP pages.

Model 1 for web applications

Model 1 is a simple architecture for interacting with the presentation layer of web applications. There is no controller, but the view (a JSP page) communicates directly with the model. The model is usually represented by a so-called Java Bean. Java beans are simple Java classes that adhere to conventions for the names of operations that access their data.

When using Model 1, the decision as to which subsequent page is displayed lies solely with the current JSP page. As a reaction to a certain user input, a decision is made directly there about the JSP page to be presented subsequently.

Model 2

Model 2 for web applications outsources the decision about which subsequent pages are called up in a separate component and thus allows more flexibility.

Model 2 for web applications

With model 2 for web applications, the dialog sequence is controlled by a separate component, the so-called controller. The controller takes on tasks that have been adapted compared to the original variant in MVC. The distribution of tasks when using Model 2 is therefore as follows:

  • The View: A JSP page that presents data and accepts data input from the user. This page can contain logic, but it does not determine which JSP is displayed as the next page.
  • The controller: A servlet that is always called from JSP and, based on the entries made, decides which action is to be carried out and which subsequent page is called.
  • The model: An object that holds the data to be represented, usually a Java Bean.

The widespread Jakarta Struts framework offers an implementation of the Model 2 variant of MVC. Figure 8.5 shows how an interaction takes place on the basis of this model.

Figure 8.5Model 2 for web applications

Here you can see that the controller has been given additional tasks compared to Smalltalk: It controls part of the application logic, so it is no longer just responsible for communicating the user interaction between the model and the view. You are dealing here with an extension of the MVC pattern.

Online banking in Struts

As an example, we present an excerpt from a small banking application that requires a PIN to be entered in order to log in. First of all, Struts has a central controller (a servlet) that evaluates the reaction to user input (usually the click of a button). The servlet decides on the basis of a configuration in XML what should happen next in response to the input. This decision is made on the basis of a description such as the example shown in Listing 8.1.

... ...

Listing 8.1Process description for Struts application

Listing 8.1 defines which JSP pages are called as subsequent pages. In line, it is first determined which input masks and which classes are used for their data management. The so-called action mappings, which define which JSP pages are to be displayed after an action, begin in line. The action that is triggered in response to entering the PIN is defined in line. The action that is specified via the PinEntryAction class is carried out.This in turn indirectly decides on its status (success, wrongpin or lastwrongpin) which JSP page is displayed next. In line, for example, it is specified that the JSP page Kontoservice.jsp is displayed if the PIN is entered successfully.

Listing 8.2 shows the implementation of the action that is called after entering a PIN.

package banking.logon; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import banking.base.BankingSession; import banking.base.SecurityInfo; import org.apache.struts.action. *; public class PinEntryAction extends Action {public ActionForward perform (ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {LogonForm theForm = (LogonForm) form; // The pin is contained in the transferred form String encodedpin = theForm.getEncodedPin (); // Save the encrypted version of the PIN HttpSession session = request.getSession (); BankingSession bankingsession = (BankingSession) session.getAttribute ("bankingsession"); SecurityInfo securityInfo = bankingsession.getSecurityInfo (); securityInfo.setEncodedPin (encodedpin); return mapping.findForward ("success"); }}

Listing 8.2Action when entering a PIN

The PinEntryAction class from Listing 8.2 notes the encrypted version of the PIN (line) and then signals the success of the PIN entry (line). Possible error situations and other return values ​​are not shown in the code for the sake of simplicity.

Model: simple Java Bean

Our model looks very simple in this case, it is a simple Java Bean that can accept the data that is collected in the view (the corresponding JSP page). Listing 8.3 shows the model that holds the PIN entry data.

package banking.logon; import org.apache.struts.action.ActionForm; public class LogonForm extends ActionForm {protected String track2; protected string track3; protected string encodedpin; public String getTrack2 () {return track2; } public String getTrack3 () {return track3; } public string getEncodedPin () {return encodedpin; } public void setTrack2 (String track2) {this.track2 = track2;} public void setTrack3 (String track3) {this.track3 = track3;} public void setEncodedPin (String encodedpin) {this.encodedpin = encodedpin; }}

Listing 8.3Model for input

The model is used here to record the entries, which in this case include the data of the PIN and the bank card used. The information about the PIN is transferred to the session by the assigned action and can be used again for later checks.

8.2.5 MVC with a focus on testability: Model-View-Presenter

One aspect that is usually only insufficiently considered when modeling the presentation layer is the testability of the resulting application.

Surface testing is difficult.

Experience has shown that tests involving graphical user interfaces are much more difficult to automate than tests of software components that manage without a graphical representation.

There are a number of products that try to solve this problem through automated tests using graphical interfaces. However, it is better to ensure that the majority of the software can be tested without the involvement of graphical user interfaces when designing our software. A pattern in the presentation layer that addresses the problem was categorized by Martin Fowler and is called Model-View-Presenter.

The basic idea is to keep the actual representation (the view) completely free of technical and functional logic.

The more directly an application is linked to the display components, the more difficult it is to test it completely.

Figure 8.6Model-View-Presenter relationship

With the Model-View-Presenter approach, events are processed directly by the view. But the view delegates this directly to the presenter class. This in turn may give feedback to the view. But why does it make sense to include an abstraction layer in the communication between view and presenter via an interface class?

Abstraction via an interface class

Well, one possibility is to reuse presenter classes if a presenter is to work with several different views that only implement the same interface. In practice, however, this case is rather rare.

Much more important is the resulting possibility of replacing the view with a replacement object (a so-called mock object) for test purposes. This gives you the opportunity to test all the logic of your program in a largely automated manner. Only the specific representation is left out, but this is usually less prone to errors than other parts. With a test of the presenter class you can, for example, determine whether cross-dependencies between surface elements are correctly evaluated.

Discussion: Is MVP Too Much Effort?

Gregor: Testability all well and good. But isn't that a bit exaggerated? Think about it: For every dialog, every window in our application, we have to define an interface again and also an additional presenter class, which we could actually give ourselves.

Bernhard: O.k., I admit that it looks like unnecessary complexity. I also don't think it makes sense for all software systems. But my experience is simply that a lot of effort is often sunk into GUI-specific application parts because they cannot be tested properly.

Gregor: But isn't the use of GUI-specific test tools intended precisely for such cases? We throw in Rational Robot or our test director, who tests the entire system with the GUI components together.

Bernhard: That is not the same. In my experience, regression tests are much easier to create and maintain if they only deal with source code. As soon as I write macros for it, rely on labels in dialogues and start an external tool (instead of a simple test program written by me), the whole process itself becomes very complicated and error-prone.

Gregor: Well, admittedly, testing will be easier. But I am not yet completely convinced that this will make up for the additional effort in the implementation. And why an additional class at all, the view class itself would be completely sufficient, why don't I test this directly?

Bernhard: Yeah, that's a good point. In practice, however, the view classes are often closely linked to the very concrete representation and cannot be used independently of it. It is precisely this separation that we are trying to achieve with our newly introduced interface.

your opinion

How did you like the Openbook? We always look forward to your feedback. Please send us your feedback as an e-mail to [email protected]