“I do not understand why people admire this Caruso so much?” Talking, googling, singing - you can not figure it out!
- Have you heard how Caruso sings?
- Yes, I have here something from his repertoire Rabinovich sang on the phone.
I realize that to write another article on Model-View-Controller is stupid and harmful for “karma”. However, with this “pattern” I have a too personal relationship - a failed project, six months of life and hard work “in the basket”.
We rewrote the project, already without MVC, just guided by the principles - the code no longer looked like a tangle of spaghetti and was reduced by half (more on this later in the promised article about how we applied the “principles” in our project). But I wanted to understand what we did wrong, what was the mistake? And for a long time everything that contained the abbreviation MVC was studied. Until the initial work from the creator, Trygve Reenskaug, met ...
And then everything fell into place. It turned out that we actually re-invented the “original MVC” based on the principles. And what is often presented as MVC, has nothing to do with it ... however, as well as to good architecture. And judging by how many people write about the failure of the “classic MVC”, argues about it and invents various modifications of it, we are not alone with this problem.
For more than 30 years, ideas and solutions gathered at MVC remain the most significant for developing user interfaces. But oddly enough, despite the existing confusion and an abundance of conflicting interpretations, developers continue to be content with “second-hand” information, drawing on MVC knowledge from Wikipedia, small articles on the Internet, and web application development frameworks. The most "advanced" read Martin Fowler. And for some reason almost no one turns to primary sources. I would like to fill this gap. And at the same time dispel some myths.
Myths: MVC was created for the SmallTalk language
The MVC concept was formulated by Trygve Reenskaug as a result of his work at Xerox PARC in 1978/79. As a rule, MVC creation is associated with the SmallTalk language, but this is not quite so. In fact, Reenskaug worked in a group for the development of a Dynabook portable computer for children of all ages under the leadership of Alan Kay.
In order to assess the scale and revolutionary nature of that project, one must bear in mind that these were the years when working with a computer required to study multipage manuals and have a degree. The task that Alan Kay was trying to solve was to bring the computer and the average user together, to “break” the wall separating them. He wanted to provide the user with tools that would be extremely simple and convenient, but at the same time would give the opportunity to control a computer and complex applications.
It was then / there that the foundations of the graphical interface were laid, the concept of a "friendly interface" was formed. As well as the SmallTalk language was developed, along with the concepts of object-oriented programming, so that an unprepared user “could understand and write programs.” Here’s how Steve Jobs describes what he saw in Xerox PARC in 1979 - How Steve Jobs got it from XEROX (from 6.30)
The project was about 10 years, a group of very strong developers. The solutions, approaches, principles found both in the field of user interfaces and in the field of object-oriented programming and in general in the development of large and complex computer systems were to some extent reviewed by Reenskag and formed the basis of MVC. So MVC is really first of all a set of guiding architectural ideas. In SmallTalk-80, these ideas just got their first significant implementation. Moreover, this was done after Reenskaug left Xerox PARC and without his participation.
Unfortunately, for a long time there was practically no information available about “real MVC”. The first serious publication from the creators appeared only 10 years later - " A Cookbook for Using the Paradigm in Smalltalk-80 ". Even Fowler mentions that he studied MVC from a working version of SmallTalk - “I had access to a working version of Smalltalk-80 so I could study MVC. I can’t say that this study was thorough, but it allowed me to understand some aspects of the solution which other descriptions could not explain . "
So it is not surprising the emergence of "myths" and various interpretations. The problem is that many “secondary” sources describe MVC not only in a distorted, but also in a deceptively simplified form, usually in the form of a certain formal scheme.
As a result, many really consider MVC as a scheme or pattern (because of which the question constantly arises - which of the many existing schemes is “correct” and why are there so many of them?). In a more advanced version, MVC is called a composite pattern, that is, a combination of several patterns that work together to implement complex applications (Observer, Strategy and Composite are commonly referred to here). And only a few understand that MVC is primarily a set of architectural ideas / principles / approaches that can be implemented in various ways using various templates ...
The latter include in particular Martin Fowler. Here is what he writes: “MVC is often called a pattern, but I don’t see much use in seeing it as a pattern, because it includes many different ideas. Different people read about MVC in various sources and extract different ideas from there, but call them the same - “MVC”. This leads to a lot of confusion and also serves as a source of misunderstandings and misunderstanding of MVC, as if people learned about it through a “damaged phone” ... I’ve already lost count of how many times I’ve seen something described as MVC that it didn’t turn out to be. ” [GUI Architectures]
I would venture to suggest that one of the reasons for the “damaged phone” is that the majority of secondary sources “behind the scenes” leave the most important thing - the actual architectural ideas themselves, embedded in MVC by its creators, and the tasks that they tried to solve. Just everything that allows you to understand the essence of MVC and avoid a huge number of pitfalls and mistakes. Therefore, in this article I want to talk about what usually remains “behind the scenes” - MVC from the point of view of its architectural principles and ideas. Although the scheme will also be. Rather, let's start with them.
But first the links. The original Reenskaug report is " The original MVC reports ". Later Reenskaug all this was more clearly formulated and designed in his subsequent work “ The Model-View-Controller (MVC). Its Past and Present . ” Perhaps someone will be interested in the page where Ranskaug records relating to that period are collected, with his comments - MVC XEROX PARC 1978-79 .
The already mentioned first MVC publication in the SmallTalk-80 language from the developers is only in the improved quality of the A Paradigm in the Smalltalk-80 System ( Model Description of the Model-View-Controller User Interface ) (Glenn Krasner and Stephen Pope). A good addition is the article “ Applications Programming in Smalltalk-80. How to use Model-View-Controller ”(by SteveBurbeck participated in the development of the SmallTalk compiler for IBM based on Smalltalk-80, as well as in the development of MacApp). Well, if someone wants a complete immersion - “ Smalltalk-80. The Interactive Programming Environment ”from the famous Adel Goldberg in discussions with which Reenskaug created the terms Model, View, Controller.
In order to make it clear what is at stake and what the problem is, let's first analyze the most typical MVC “schemes”. This is important, since often no explanations are given to the schemes, and by the same token, it happens that definitions are borrowed from one place, and schemes from another. As a result, you can find the same MVC descriptions with completely different diagrams, which is very confusing.
So, despite the fact that MVC is interpreted and portrayed in very different ways, in all this diversity one can still single out a common “core”. What is common is that everywhere it is said about some three parts - the Model, the View and the Controller, which are interconnected in a certain way, namely:
The model knows nothing about either the View or the Controller, which makes it possible to develop and test it as an independent component. And this is the main point of MVC.
View displays the Model. And that means that it must somehow get from it the necessary data for display. The following two options are most common: 1) Active View , which knows about the Model and itself takes the necessary data from it. 2) Passive View to which the data is supplied by the Controller. In this case, the View is not related to the Model.
There can be several types - they can display the same data in different ways, for example, in the form of a table or graph, or they can be responsible for displaying different parts of data from the Model.
And he can also manage the View / Species (especially if there are several) and, accordingly, be aware of the Species, but this is not necessary.
From here we get the basic (most simplified) schemes of the two most common MVC varieties. The crossed out line indicates the optional connection of the Controller with the View.
This is how the basic scheme looks like in Fowler: “The main links between the Model, the View and the Controller. (I call them the main ones, because in fact the View and the Controller may be directly related to each other. However, the developers mostly do not use this connection. ) ":
Further. The model, like the View, can also be Passive or Active. The Passive Model does not affect the View or the Controller. In this case, all changes to the Model are tracked by the Controller and it is also responsible for redrawing the View when necessary.
But usually, by MVC, all the same implies a variant with an Active Model .
"Active Model" announces that changes have occurred in it. And she does this through the Observer pattern, sending change notifications to all of her “subscribers.” “Active View” subscribes to these messages by itself and thus knows when it is necessary to re-read the data from the model and update it. In the case of Passive View, the Subscriber is the Controller, which then updates the View.
The Observer pattern allows the Model to, on the one hand, inform the View or the Controller that there have been changes in it, and on the other, it is practically “not to know” about them (except that they implement a certain specified “subscriber” interface) and thus remain independent. This is called weak binding and is considered the second key point of MVC.
That is why, when it is said that MVC is a composite pattern, the Observer pattern is mentioned first of all as one of its components. It is customary to draw weak linking in diagrams with a dotted arrow, but many ignore this rule.
Thus, the more advanced "MVC schemes" will look like this:
Note: there are authors who put a completely different meaning in the terms Passive and Active Model. Namely, what is usually called the Thin Model (a model containing only data) and the Thick Model (a full-fledged model containing the entire business logic of the application).
Well, the last. Generally speaking, MVC, in any of its variations, is primarily a template for developing applications with a user interface and its main purpose is to ensure the interaction of the application with the user. Therefore, a user must be present in the full MVC scheme (explicitly or implicitly). And here basically there are two interpretations:
The user controls the application through the Controller, and the View serves only to display information about the Model, and the user only sees it
Often indicate / draw only the fact that the user acts on the controller, and what he sees the view is lowered .
The user interacts with View only. That is, the View not only reflects the Model, but also accepts user commands and transmits them to the Controller. In this case, one more connection is formed between the View and the Controller: a direct (View knows about the Controller and directly transmits information) or, more often, a weakened (View simply sends information about user actions to all interested subscribers and the Controller subscribes to this distribution)
Note: it must be kept in mind that the Passive View version, when the View is not related to the Model and the Controller supplies the data for display, is sometimes called MVC, and sometimes it is isolated into a separate type - MVP and then the Controller is renamed to Presenter .
To illustrate the above, a few diagrams "from the Internet" (I hope it became clearer why they are so different):
And now the most important thing - how are they used, what do they designate and what does the Model View and Controller correspond to when writing applications?
Here we can distinguish two radically different approaches, in each of which the Model, View and Controller are interpreted in a very different way.
The first approach comes from web programming, where MVC is the most widely used, and therefore the features typical of web programming are reflected in it as much as possible. Namely, the binding to the three-tier client-server-database architecture and the predominance of scripting languages. As a result, MVC components are formally attached to the three layers of the architecture and it turns out that:
Model = Database
A model is simply the data with which the application operates.
Controller = Server
The controller is the business logic of the application. Sometimes they also say that the controller is the center for processing all requests and making decisions, as well as an intermediate layer providing the connection between the model and the presentation.
About the inadequacy of this approach has already been written so much that it even entered into Wikipedia ( MVC. The most common mistakes ). The problems arising from this are well discussed in the article, which has become a kind of classic " M in MVC: why models are misunderstood and underestimated ." Therefore, I will just try to summarize briefly:
Model Independence is central to MVC. If the model is thin, that is, it contains only data, then the possibility of its independent development makes little sense. Accordingly, with this approach, MVC itself also loses its meaning.
The entire business logic of the application, that is, most of the code, is concentrated in the Controller, and this is despite the fact that the Controller is the most dependent part in MVC - in general, it depends on both the Model and the View. Generally speaking, well-designed applications are tried to do exactly the opposite — the most dependent parts should be minimal, not maximal.
In practice, the Controller in a web application usually corresponds to one script, and putting all business logic to the Controller actually means that most of the application is in the same script. Hence the term TTUK - a fat stupid ugly controller.
The program, of course, is divided into many MVC, corresponding to the pages of the web application, and this saves the situation but, alas, does not change the essence. This problem is known, here is a good article - " RIA Architecture ".
Typical errors: confusion in the Business Controller and GUI logic
The good news is that the “MVC web version,” just a few years ago the most common, is now actively losing ground. The bad thing is that it is still common, only now not in an explicit, but in a disguised form. As for the phrases (I quote): “ The model is the exchange of data from the database , etc. The controller is processing the data and preparing for the View ” is now actively “minus”, they began to write:
The fact is that in an object-oriented application there is no data, but there are many objects and each of them contains some data and methods for working with them. Including database access objects (if any). Therefore, when the definition of a Model begins with the word “data”, then it essentially makes little sense and often in a veiled form implies all the same access to the database. The lion’s share of business logic is often placed in the processing of user actions, and as a result, all or almost all application logic often ends up in the Controller.
The second approach is much closer to the original sources. Therefore, we analyze it in more detail.
Martin Fowler is absolutely right when he says that MVC is not a pattern, but a set of architectural principles and ideas used in building user information systems (usually complex).
We tried to collect and describe the architectural principles in the article " Creating the architecture of a program or how to design a stool ." If to speak extremely briefly, the essence is as follows: a complex system must be divided into modules. Moreover, it is desirable to do the decomposition hierarchically , and the modules into which the system is divided should be, if possible, independent or weakly connected ( Low coupling ). The weaker the connectivity, the easier it is to write / understand / expand / repair the program. Therefore, one of the main tasks in decomposition is minimization and weakening of connections between components.
Let's see how these principles are applied in MVC to create a primary architecture (decomposition) of user applications. In fact, at the heart of MVC are three fairly simple ideas:
"1" Separate the domain model (business logic) of the application from the user interface
The first and main idea of MVC is that any user application can be divided into two modules in the first approximation - one of which provides the main functionality of the application, its business logic, and the second is responsible for user interaction:
Thus, we get the opportunity to develop a domain model containing the business logic of the system and constituting the functional core of the application, without thinking about how it will interact with the user.
The task of user interaction is placed in a separate module - the user interface and can also be solved relatively independently.
It is the domain model ( Domain Model from the English domain model ) that is considered to be the Model in “architectural MVC” (hence the term). Therefore, it is so important that it be independent and can be independently developed and tested.
“The core idea of MVC, like the main idea for all subsequent frameworks, is what I call the“ Separated Presentation ”. The meaning of the separate presentation is to draw a clear boundary between the domain objects that reflect our real world, and View objects, which are GUI elements on the screen. Domain objects must be completely independent and work without references to the view, they must be able to support multiple views, perhaps even at the same time. 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). " - Fowler
“2” Independence of the Model and synchronization of user interfaces due to the Observer pattern
The second key idea is that in order to be able to develop a Model independently , it is necessary to weaken its dependence on the user interface. And this is done, as mentioned above, at the expense of the Observer pattern.
The model sends notifications of changes . The interface subscribes to these alerts and thus knows when to re-read the data from the model and update. Due to this, we get a practically independent Model , which knows nothing about the user interfaces associated with it, except that they implement the “observer” interface.
“3” Separate User Interface into View and Controller.
The third idea is simply the second step of the hierarchical decomposition. After the initial separation of the application into a business model and interface, the decomposition continues at the next hierarchical level, and the user interface, in turn, is divided into View and Controller.
I got the impression that very few people understand the essence of this division and therefore can explain. Usually they give only a standard streamlined formulation that the Controller somehow reacts to user actions, and the View displays the Model (therefore, in most implementations, the View itself subscribes to the Model change notifications. Although, as already mentioned, the Controller can be a subscriber or Controller together).
Since the division of the user interface into the View and the Controller is related to the second level of the hierarchy , it is much less significant than the primary separation of an application into a domain model and interface. ( ) « MVC », UI-, . .
« MVC» . , , , . , . , -, " ", .
, MVC , « » . , , ?
? «MVC-» , - ?
, , . , ( ) . , , , . , . , , , GUI, .
— , . : " A model could be a single object (rather uninteresting), or it could be some structure of objects. " – , , ?
: " , … « », - , ." « ». «» , « ».
: , ( ), «» ( ) «». , , .
, « » «». , , , , . – « ». . (Dependency Inversion Principle). — .
, , .
:
: MVC , , , « », , «Editor» ().
, MVC , – ( ), ( ). «MVC » ( ), .
, ( ), , . - , , , . , , … , -, , . .
MVC, :
. . / . , , . .
- , -. , ( ), . ( Provided Interface ) ( RequiredInterface ).
,
( Interface Segregation Principle ) ProvidedInterface RequiredInterface .
, . , — “ An API Gateway is a server that is the single entry point into the system. It is similar to the Facade pattern from object-oriented design. The API Gateway encapsulates the internal system architecture and provides an API that is tailored to each client . ” Building Microservices: Using an API Gateway .
" API, API (Rather than provide a one-size-fits-all style API, the API gateway can expose a different API for each client. For example, the Netflix API gateway runs client-specific adapter code that provides each client with an API that's best suited to it's requirements) " API Gateway .
- SmallTalk-80. - MVC :
… (glue), , , , … / .
, . - ( "Interface-Based Programming Techniques").
- JavaGuru — Advanced MVC Patterns . , , /-/ (Models as Proxies, Models as Filters), , – , : “ , , . !.. - ”.
- , original MVC, «», . « », .
— " ?". MVC — «-» .
? , . . - . – « » «GUI » ( ).
, Smalltalk. Smalltalk-80 . ( « » ) , , .
( SmallTalk) /, . - ( ) SmallTalk-80.
, Smalltalk GUI : Inspector, Browser, Workspace,…
Glenn Krasner:
"Inspector . ListView (), TextView ()… « Inspector »… « Inspector » . View " actual " models ...
Inspector, . « Browser » - ... "
: -, -, . Inspector « Inspector », Browser – « Browser ».
Workspace, " StringHolder, , ".
Krasner SmallTalk ( Model): StringHolder , Browser , Inspector , FileModel , Icon … " the models were almost always some sort of filter class ".
VisualWorks Smalltalk Holder- . , , – ValueModel ValueHolder. , , ValueModel , GUI « » .
:
, " MVC" - GUI - . Front-Controller ApplicationModel, ViewModel ( . Model-ModelView-Controller ) Proxy-model .
- , «», , . - -.
For example, ValueHolder is, as a rule, just a wrapper around an already existing domain variable, it should not contain data, it contains a link to the data. That's what they write: " ValueModel doesn’t need to be saved by another model " ( Understanding and Using ValueModels ).
But a quote from the Advanced MVC Patterns article: “ One of the most common mistakes that people make when using Swing components is to copy data into models of these Swing components. The correct way is to use existing data, adapting it with filter ... Remember: never copy data that you can simply interpret! ".
Consider the following simple example. If you follow the Internet tips and use a code like this for "adding items to the list" (taken from StackOverflow and Adding and Removing an Item in a JList ), then that copy of the data into the list model will occur:
Object[] items; //
DefaultListModel model = new DefaultListModel();
JList list = new JList(model);
for (int i = 0; i < items.length; i++){
// !
model.addElement(items[i]);
}
, , ListModel ( AbstractListModel):
// - ,
//
ListModel model = new AbstractListModel() {
public int getSize() {return items.length;}
public Object getElementAt(int index) {return items[index];}
};
//
JList list = new JList(model);
, - , . -
Object[] items1; Object[] items2; //
// -
ListModel model = new AbstractListModel() {
public int getSize() { return items1.length + items2.length;}
public Object getElementAt(int index) {
return index<items1.length ? items1[index] : items2[index-items1.length];
}
};
JList list = new JList(model);
. , ( ).
, :
JList list = new JList(items);
- .
: GUI-
, .
: «MVC »
- «» . - , , .
- (, , ) , . : "model object with a façade that reflects the user’s mental model".
MVC «», « » . (" ?", “ ?”), .
MVC , : . //..., ( ) . – .
- Model-View-Whatever MVC … : , ,
Source: https://habr.com/ru/post/321050/
All Articles