📜 ⬆️ ⬇️

Why I no longer use MVC frameworks



Dear habravchane.

Since the discussion around the article is very active, Jean-Jacques Dubre (he reads comments) decided to organize chats in gitter.
')
You can chat with him in person in the following chat rooms:
https://gitter.im/jdubray/sam
https://gitter.im/jdubray/sam-examples
https://gitter.im/jdubray/sam-architecture

Also, the author of the article posted code examples here: https://bitbucket.org/snippets/jdubray/

Regarding the code, he left the following comment:
It is the exact same thing as the React + Redux + Relay. for all these bloated library (

Published with the great approval of the author and the consent of the portal infoq.com . I hope my language skills will justify the confidence put by the author.

The worst thing in my work today is designing an API for front-end developers. The dialogue with them inevitably unfolds as follows:
Dev - so on this screen you need x, y and z data. Could you make an API that returns data in the format {x :, y :, z:}

I'm ok

I don't even argue with them anymore. Projects end with a bunch of different APIs tied to screens that change very often, which is “by design” requiring changes to the API. You do not have time to blink an eye, but you already have a bunch of APIs and for each you need to support many formats and platforms. Sam Newman even began to formalize this approach as a BFF Pattern , suggesting that it is normal to develop a separate API for each type of device, platform, and, of course, each version of your application. Daniel Jacobson said that Netflix was forced to start using a new feature for its “Experience API”: ephemerality. Oh…

A couple of months ago, I began my journey in search of an answer to the question of why it all happened and what to do about it. This path led me to doubt in the strongest of the dogmas of creating application architecture - MVC. And when I was faced with the true power of reactive and functional programming, I focused on simplicity and avoiding bloat, in the creation of which our industry has succeeded so much. I think you may be interested in the conclusions made by me.

The pattern that we use in the design of each screen, MVC - Model-View-Controller. MVC was invented in those days when the Web did not exist yet and the application architecture was, at best, a fat client that accessed the only database on a primitive network. And yet, after decades, MVC is still consistently used to create Omni-Channel applications .

In connection with the upcoming release of Angular2, perhaps now is the time to revise the use of the MVC pattern and, therefore, the value that MVC frameworks introduce into the application architecture.

I first encountered MVC in 1990, when NeXT released Interface Builder (it's great to know that this software is still relevant today). At that time, Interface Builder and MVC were presented as a big step forward. In the late 90s, the MVC pattern was adapted to work via HTTP (remember Struts ?) And now MVC is the cornerstone in the architecture of any application, for all occasions.

Even React.js, seemingly far from the MVC dogma, used this euphemism when they presented their framework: “ React is only a View in MVC ”.

Last year, when I started using React, I felt that it was something completely different - you change part of the data somewhere and, at the same time, without the explicit interaction of View and Model, the entire UI changes (not only the values ​​in the fields and tables). Because of this, I quickly became disillusioned with the React development model, and obviously I was not alone. I will share the opinion of Andre Medeiros :
React disappointed me for several reasons. Mainly due to a poorly designed API, which forces the user [..] to confuse several concerns in one component.

As a server API designer, I came to the conclusion that there is no good way to add API calls to the front-end implemented on React, precisely because React focuses only on View, and in its development model there is no concept of Controller.

Facebook has so far resisted correcting this gap at the framework level. The React team developed the Flux pattern , which is also disappointing, and now Dan Abramov is promoting another pattern, Redux , which is generally moving in the right direction, but — I will demonstrate this further — does not provide a proper way to work with the front-end API .

You might think that by developing the GWT, Android SDK and Angular, Google engineers have a clear idea (in English sounds like a pun - strong view) about what is the best architecture for a front-end. But, if you read some thoughts about the architecture of Angular2 , you will not necessarily experience the warm feeling that, at least in Google, people understand what they are doing:
Angular 1 was not built on the idea of ​​components. Instead, we attach the controllers to the various [elements] pages at our discretion. Scopes joined or flowed depending on how our directives encapsulate ourselves (isolated scope, anyone?)

Does Angular2 built on components look much simpler? Not really. The core package Angular2 itself contains 180 definitions, and the entire framework comes to a staggering almost 500 definitions, and this is all on top of HTML5 and CSS3. Who has time to study and improve in this kind of framework for building web applications? What happens when Angular3 comes out?

After working with React and seeing what Angular2 is, I became disheartened - these frameworks methodically force me to use the BFF Screen Scraping pattern, in which each server API is tailored to fit the data needed on the screen, to the last detail.

It was my moment “Fuck it all.” I'll just create applications, without React, without Angular, without any MVC frameworks, and see if I can find a better way to combine the View and the underlying API.

What I really liked about React was the interaction between Model and View. The fact that React is not based on templates and that the View itself cannot ask for data felt like a reasonable direction to study (you can only transfer data to the View).

Having worked with React enough, you understand that its only purpose is to decompose View into a set of pure functions and JSX markup:

<V params={M}/>

:

V = f(M)

, web- , , Gliiph, :


.1 , HTML .

:


. 2. , .

, JavaScript- , : “ React?”.

Virtual dom? , ( , ), , , .

GraphQL? - . , Facebook , . GraphQL View Model. Model View , . React ( , reactive) , , Client Specified Queries:
GraphQL View front-end , [...] , GraphQL- ,

GraphQL, , — , JSX- — Model View. “, front-end ” , Model View.

View ( ) Model , , View Model.

, View v , , , , Model — v, Model.

, , view. view-Model , , , GraphQL ViewModel:

V = f( vm(M) )

MDE (Model-driven engineering — . ), , , , GraphQL.

. -, React, View . , , web- web- View (, ). , responsive-, .

, , HTML5 JavaScript-. , web-. JavaScript-. Wordpress — HTML5 CSS3 ( ).

, . JavaScript-, . “binding” , , JSX, Angular, JavaScript-.

, reactive data flow, , — .

, , View Model Model- , View. caching, lazy loading, orchestration, consistency Model. GraphQL, , View.

, Model View, , ? “Controller”? , MVC.

Apple MVC, “” Xerox SPARC 80- :


. 3. MVC.

, , MVC “” ( ). MVC Action (Controller) Model ( ) , View. ( — . ) , Controller . , , reactive, , , Action Model, , , , Model.

: “ Action- reactive flow?” , Action-, TLA+. TLA “Temporal Logic of Actions”, , . TLA+ Action- :

 data’ = A (data)

TLA+, , .

, MVC :

V = f( M.present( A(data) ) ) 

Action, , ( ), Model, , , , . , View Model. . , Model , reactive flow, , , “ front-end ”. .

, Action , side effect- ( Model, logging, ).

MVC , , Model (), . , Redux , React Model Action- reducer. Action- Model .

, Reactive MVC, , . . , .

, , : , , , Model , .



:


. 4. .

(decrement), (launch), “” . , ( ) , , , decrement. — launch. (abort) , .

MVC Controller, , , View.

, . , TLA+ Action side effects- Model Action . , Action . , . TLA+, Action-, , , , state representation ( View) Action-, . , , (S1, A, S2) . , , (Sk, Ak1, Ak2,...) Actions Sk , Action Model .

TLA+ , “”, Action View ( ).

Model :

model = {
counter:,
started:,
aborted:,
launched:
}

() Model:

ready = {counter: 10, started: false, aborted: false, launched: false }
counting = {counter: [0..10], started: true, aborted: false, launched: false }
launched = {counter: 0, started: true, aborted: false, launched: true}
aborted = {counter: [0..10], started: true, aborted: true, launched: false}


Model , c Action-, . - - . , , , . , . , - , , , , MVC.

. TLA+, next-action . , next-action , Action, . , Model, state representation .


. 5. .

, - WebSocket ( polling, WebSocket ) , Action .

open source Java JavaScript, , TLA+, , WebSocket, Polling Queueing - . , . , .

, , , MVC — SAM pattern (State-Action-Model), , , React.js TLA+.

SAM :

 V = S( vm( M.present( A(data) ) ), nap(M))

, View V Model, Action- A.

SAM, A (Actions), vm (ViewModel), nap (next-action predicate) S (state representation) . SAM, , “” ( ) Model , , Model.

, next-action, nap() callback, state representation .


. 6. State-Action-Model (SAM).

- ( HTTP) - / .

SAM , View. Action View, next-action null-. , — , View () .

, Action-, Action-, Model next-action : Action- stateful, Model Action-, . , , - “”, , View next-action , Model.

, CRUD Action-. Model persistence, CRUD , View. , View “” . , View state representation reactive flow .

Action- Model. , , side effect- ( Model). , Action- API ( , side effect Model). , Model , .

“ ”, API , :


. 7. “ ”

, Action- Model-, (composed) :

:

data’ = A(B(data))

( ):

M1.present(data’)
M2.present(data’)

“-” ( Model , ):

M1.present(data’,M2)
function present(data, child) {
        	// perform updates
        	…
        	// synch models
        	child.present(c(data))
}

Publish/Subscribe:

M1.on(“topic”, present )
M2.on(“topic”, present )



M1.on(“data”, present )
M2.on(“data”, present )


, ( — . ) (. 8) Model, .


. 8. SAM.

composable SAM wizard- ( , ToDo application), SAM :


. 9. SAM.

, , SAM state representation, SAM.
Action-a (. 10). SAM , View Action, callback, Action , , Model.


. 10. SAM.

CQRS, - , . Action Model. ( , ) , Model.

{ _name : ‘/^[a]$/i’ } // Names that start with A or a
{ _customerId: ‘123’ } // customer with id = 123


Model , View. , Model. Action- Model (data sets, events, actions). , , . data sets.

(exceptions), React, , Model ( Action CRUD-). state representation .

, SAM state representation. , state representation hit rate, / Action/Response.

unit-.

SAM front-end , , TLA+, - :

, API, API , View Model.

Action-, , Model Action. , Action-, (state representation) , , Model- , .

SAM Model. Hivepod.io , - , as-is.

, , React, - data binding .

, SAM , virtual-dom state representation API.

: Object Orientation , . . , SAM , , . . API , “screen scrapping”.

, : Prof. Jean Bezivin, Prof. Joëlle Coutaz, Braulio Diez, Adron Hall, Edwin Khodabackchian, Guillaume Laforge, Pedro Molina, Arnon Rotem-Gal-Oz.

:
- xgen.io gliiph. Service Oriented Architectures API 15 . HRL University of Provence (Luminy campus) ( Aix-Marseille University — . ), Prolog. BOLT.

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


All Articles