📜 ⬆️ ⬇️

Martin Fowler - GUI Architectures. Part 2

Hello everyone again. Its me again. Inside the Habrakat translation is another paragraph of Martin Fowler's article.

This time touched on the topic of MVC. Fowler wrote about it very popular. I tried to translate popularly :) Now you can understand why everyone rushes with MVC, as with a written sack. And by the way, Fowler is right - there are a lot of places and many people perceive MVC in their own way. Fowler himself writes about the original MVC, which worked on the Smalltalk platform. Very informative.

The previous part is here . Original article here . It is very desirable to read the first part, because Fowler defined a common example problem there, which he solves using the described architectures. If you do not read about this problem, it will be a little unclear about what we are talking about.
')
I will write the next part of the translation when I get angry and get myself together.

Model-View-Controller


Model-View-Controller. Perhaps the most common pattern in UI development is Model-View-Controller (MVC). In addition, most often the most misunderstood. I have already lost count of how many times I have seen something described as MVC, which it did not turn out to be. Frankly, this is because nowadays classic MVC is no longer suitable for fat clients. Let's see where MVC came from.

Before we dive into MVC, it is important to remember that he was one of the first attempts to seriously address UI tasks, regardless of the scale of the solution. In the 70s, the concept of "Graphical user interface" was not very popular. The "Forms and Elements" template that I described above appeared later than MVC. I described it first of all because it is simpler, and not always in the good sense of the word. I will look at Smalltalk 80 MVC on the already well-known example of ice cream concentration. At the same time, I will allow myself some liberties and will give some description of the Smalltalk 80 platform. To begin with, I will say that the system was monochrome.

The core of the MVC idea, as well as the main idea for all subsequent frameworks, is what I call the “ Separated Presentation ”. The meaning of the separated view is to draw a clear boundary between the domain objects that reflect our real world and the view objects, which are the GUI elements on the screen. Domain objects must be completely independent and work without references to the representation; they must be able to support multiple representations, perhaps even simultaneously. This approach, by the way, was also one of the important aspects of Unix-culture, allowing even today to work in a variety of applications both through the command line and through a graphical interface (simultaneously).

In MVC, a model is a domain object. Domain objects do not belong to UI at all. In order to put our example with concentration and measurements in MVC, we take the object “measuring” (reading) as a model, which has all the fields of interest to us. (As you can see, the presence of a list box should make the model a bit more complicated, but we will ignore this nuance for a while).

In MVC, I deal with ordinary objects of a domain model ( Domain Model ), as opposed to “forms and elements”, where I worked with a Record Set . This is one of the differences between these two patterns, due to their design. It is assumed that in “forms and elements” most people want to easily manipulate data from a relational database, while MVC also requires working with ordinary Smalltalk objects.

The MVC presentation part is created from two elements: the view and the controller. The controller's job is to collect user input and figure out what to do with it.

Here I should emphasize that in our example, the representation and the controller do not exist in the singular. We must have a pair of view-controller for each element on the screen, for each control on the screen and for the screen as a whole. Therefore, in our example, the first reaction to user input is the joint work of the controllers, which determines which element now receives this data. This element will be the actual concentration text box. Process the entered data will be the controller of this text field.



Figure 4. Basic connections between model, view and controller. (I call them basic, because in fact the view and the controller can be directly related to each other. However, the developers basically do not use this connection.)

Like subsequent development environments, the Smalltalk platform provided the ability to create generic UI components that can be reused. In our case, this component will be a pair of view-controller. Both are generalized (generic) classes ( depend on the so-called configuration - approx. Transl. ). Generalization is needed so that they can be used in different applications. The first is the assessment view, which will play the role of the entire screen and determine the location of simpler elements. This order is similar to the one that was in the "forms and elements." However, unlike the form object in “forms and elements”, MVC does not have event handlers for text fields in the screen controller (assessment controller).



Figure 5. MVC version classes for an example with ice cream concentration.

Consider the case for entering the actual value. The configuration of the element of the actual value text field consists of its connection with the model (measurement object), i.e. the method to call the model when the element changes text. After screen initialization, the selected method will be equal to "#actual" (the '#' character at the beginning of the line indicates the interned string). As soon as the text is entered, the controller makes a reflexive call to the specified method on the measurement object (changes the value of the actual field). In fact, the exact same mechanism occurred in data binding ( Data Binding ). The control is associated with the underlying object (record) and knows which method (ie, column) it controls.



Figure 6. Changing the actual value field

So, in the resulting solution there are no common viewing objects (recall the form object with event handlers). Instead, controls review a model whose behavior is defined in it (and not in the form object). That is, when it is required to determine the value of the difference of indicators (variance), the model copes with this itself.

Browsers are found in MVC. In truth, this is one of the ideas generated by MVC. In our case, all views and controllers review the model. When the model changes, the views react. The actual value text field representation gets the information that the measurement object has changed, after which it calls the model method defined as an aspect for this text field - in our case #actual - and sets its value in the field. (Almost the same thing happens for the color of the text field, but there are some “ghosts” I’m going to get to soon.)

Note that the text field controller itself does not set the value in the text field representation. It updates the model and allows the browser mechanisms to take care of updating other objects. This approach is different from what was in the “forms and elements”, where updating the form object updated the control, which in turn updated the underlying record set via data binding. I distinguish these two approaches in templates and call them accordingly: Flow Synchronization ( Flow Synchronization ) and synchronization through a browser ( Observer Synchronization ). They describe different ways to synchronize between the screen state ( screen state ) and the session state ( session state ). "Forms and elements" synchronize data through the flow of applications to the application of various controls that need to be updated directly through direct access to them. MVC synchronizes through model updates and then relies on updating the views of the controls through their communication with the browser.

Stream synchronization becomes more pronounced when there is no data binding in the application. In this case, the application must explicitly synchronize at one of its important stages (application flow) - for example, when you open the screen or upon an event of pressing the “save” button.

One of the consequences of synchronization through the browser ( Observer Synchronization ) is that the controller does not know about changes of any other element, if suddenly the user somehow changed it (that is, another element). While the form object in “Forms and Elements” needs to closely monitor the integrity of the screen state when something changes (which can be very laborious with a complex form layout), the controller does not need to do the same.

This useful advantage is especially useful when several screens are opened that view the same model objects. A classic example of MVC is a table, for example, a screen with data, plus a pair of windows of various graphs of this data. The window with the table does not need to know that other windows are open. It just updates the model, and synchronization ( Observer Synchronization ) does the rest. With flow synchronization ( Flow Synchronization ), you would need to somehow know what other windows are open to update them.

With all the advantages of synchronization through the browser ( Observer Synchronization ), it has one drawback. The Observer Synchronization synchronization problem is the browser itself - by looking at the code, you cannot tell what is happening. When I understood the examples implemented on Smalltalk 80, I very clearly remembered this inconvenience. I can know what is happening in a section of some code, but as soon as a browser comes into action, I need a tracker and a debugger to understand what is being done next. The behavior of the browser is difficult to understand and debug, because it is implicit.

Various approaches to state synchronization can be observed in the diagrams provided. However, the most important and influential difference in MVC is its use of the Separated Presentation . The calculation of the deviation between the actual and target values ​​should be the behavior of the domain model and should not depend on the UI. Therefore, we implement this behavior in the domain layer of the system - the layer that is the object of measurement (reading). The deviation calculation method is absolutely logical for the measurement object and has no clue about the user interface.

Now, however, we can consider a couple of complications of the current state of affairs. There are two uncomfortable areas through which I slipped, talking about the theory of MVC. The first problem area is the assignment of color to the difference text box. This logic does not entirely belong to the domain object, since the color with which we highlight the deviation value is not part of it. However, some part of this logic is still part of it. For example, the deviation quality assessment: good (more than five percent), bad (less than ten percent) and normal (all other values). The evaluation calculation is the domain logic. Coloring a text field is the presentation logic. The problem is where to put the presentation logic, since it is not part of the logic of our plain text field.

The first developers on Smalltalk faced this problem, they also offered solutions to this problem. The solution shown above is dirty because it violates the “purity” of the domain logic. I confess to the random act of "pollution" and try to prevent it from becoming a habit ( this is Fowler so funny - approx. Transl. ).

We can also solve this problem in the same way as “Forms and Elements” - let the evaluation screen review the presentation of the deviation text field. When its value changes, the screen will respond and assign a color to the text field. But such a decision involves the use of browser mechanisms - and the more they dig, the more (exponentially) the work with them becomes more complex, and the number of unnecessary links between different views increases.

I would prefer to develop a new type of UI element. A characteristic feature of the behavior of this element is that it requests an estimate from the domain object, compares it with the internal table of values ​​and colors, and highlights it with the color obtained from the table. Both the table and the query value of the domain object will be assigned by the evaluation view at the assembly stage itself. In the same way, an aspect of a value is assigned to a text field so that it tracks it. This approach will work very well if I have an easy way to inherit from a text field (in it I will add a new behavior). Whether there is such a method depends on how well-designed components support inheritance — in Smalltalk this is very easy, and in other environments it can be more complicated.



Figure 7: Using an inheritor of a text field class that supports color detection.

The final touch will be the creation of a special domain object, something that will monitor the elements on the screen, but it will not depend on it. In other words, create a model for the screen. Methods that were previously called for the measurement object will be delegated by the model to the measurement object. Also in it will be defined methods "only UI", for example, the definition of color.



Figure 8: Using the Presentation Model in the processing of presentation logic.

The proposed solution works in many cases, and as we will see later, it has become a common technique that Smalltalk developers follow. I call it the presentation model (), because it is designed for (and is part of) the presentation layer.

The view model solves another view logic problem - the view state problem. The basic concept of MVC assumes that the view state is inherited from the model state. How in this case to determine which station is selected in the list? Presentation Model solves this problem by providing a place where you can place this kind of state. A similar problem arises if we have “save” buttons, which can be clicked only when the data has changed - this state is determined by the interaction with the model, and not the model itself.

Now, I think it's time to identify the characteristic features of MVC.



To be continued.

Source: https://habr.com/ru/post/53536/


All Articles