name: title class: left, top .left-column[ # .fancy[[SE1] Patrones UI] ### · MVC y variantes Carlos Granell· Universitat Jaume I EI1039 - Diseño de Software · Sep 2023 ] .right-column[ <div class="figure"> <img src="images/MVC3.png" alt="MVC architecture from freecodecamp.org" width="100%" /> <p class="caption">MVC architecture from freecodecamp.org</p> </div> ] ??? Image credits: [freecodecamp.org](https://www.freecodecamp.org/news/the-model-view-controller-pattern-mvc-architecture-and-frameworks-explained/) --- class: inverse, center, middle .acid[Model-View-Controller (MVC)] -- .heat[Model-View-Presenter (MVP)] -- .cold[Model-View-ViewModel (MVVM)] -- .fat[View, Interactor, Presenter, Entity, and Router Model (VIPER)] --- # .acidinline[MVC] inicios .left-column[ <div class="figure"> <img src="https://upload.wikimedia.org/wikipedia/commons/7/77/Trygve_Reenskaug_%282010%29.jpg" alt="Trygve Reenskaug from Wikipedia" width="100%" /> <p class="caption">Trygve Reenskaug from Wikipedia</p> </div> ] .right-column[ .large[
[Formulada](http://heim.ifi.uio.no/~trygver/themes/mvc/mvc-index.html) en 1978/79] .large[
Como un lenguaje compartido para describir problemas y sus soluciones ("Pattern Language")] .large[
Uso predominante en la era pre-Web para GUI (Smalltalk, Mac OS, Windows...) ] ] --- # .acidinline[MVC] componentes ## .acidinline[M]odel
datos y su lógica ## .acidinline[V]iew
presentación de datos e interacción del usuario ## .acidinline[C]ontroller
El interfaz entre `Model` y `View`; Controla y decide --- # .acidinline[MVC] componentes <div class="figure"> <img src="images/HeadFirstDesingPatterns14.png" alt="MVC from Head First Design Patterns" width="90%" /> <p class="caption">MVC from Head First Design Patterns</p> </div> --- # .acidinline[MVC] ¿patrón de diseño o de arquitectura? -- .pull-left[ ## .center[MVC como patrón de diseño .acidinline[si soluciona problemas específicos]] ] -- .pull-right[ ## .center[MVC como patrón de arquitectura .acidinline[si afecta a toda (la arquitectura de) la aplicación]] ] ??? ¿Qué gorra nos ponemos? ¿La de arquitecto, como al principio del curso? ¿o la de diseñador/programador, como en la parte de patrones de diseño? MVC admite una, la otra, o ambas a la vez. --- # .acidinline[MVC] como patrón (.acidinline[compuesto]) de diseño <div class="figure"> <img src="images/HeadFirstDesingPatterns14.png" alt="MVC from Head First Design Patterns" width="90%" /> <p class="caption">MVC from Head First Design Patterns</p> </div> ??? MVC se puede considerar un patrón de diseño **compuesto**, es decir, la combinación de varios patrones de diseño de software. --- # .acidinline[MVC] como patrón (compuesto) de diseño ### .acidinline[V]iew-.acidinline[C]ontroller
[`Strategy`](https://cgranell.github.io/ei1039/slides/TE7_2_strategy.html#title) - .large[`View` es un objeto configurado con una estrategia; el `Controller` proporciona la **estrategia**] - .large[`View` se encarga solo del aspecto visual y delega el resto al `Controller`, que se encarga de interactuar con el `Model`] - .large[`View` está desacoplado, no conoce nada de la interacción entre el `Controller` y `Model`] --- # .acidinline[MVC] como patrón (compuesto) de diseño <div class="figure"> <img src="images/HeadFirstDesingPatterns15.png" alt="MVC-Strategy from Head First Design Patterns" width="90%" /> <p class="caption">MVC-Strategy from Head First Design Patterns</p> </div> --- # .acidinline[MVC] como patrón (compuesto) de diseño ### .acidinline[V]iew
[`Composite`](https://cgranell.github.io/ei1039/slides/TE5_1_composite.html#title) - .large[`View` consiste en un conjunto de ventanas, paneles, botones, etiquetas, etc.] - .large[Cada elemento visual es bien un _Composite_, o nodo intermedio (un frame), o bien un _Leaf_, o nodo hoja (un botón)] --- # .acidinline[MVC] como patrón (compuesto) de diseño <div class="figure"> <img src="images/HeadFirstDesingPatterns16.png" alt="MVC-Composite from Head First Design Patterns" width="90%" /> <p class="caption">MVC-Composite from Head First Design Patterns</p> </div> --- # .acidinline[MVC] como patrón (compuesto) de diseño ### .acidinline[V]iew-.acidinline[M]odel
[`Observer`](https://cgranell.github.io/ei1039/slides/TE6_1_observer.html#title) - .large[`Model` implementa el patrón `Observer`] - .large[`View` (y `Controller`) es un observador del `Model`] - .large[`Model` está completamente desacoplado: no depende de la `View` ni del `Controller`] - .large[Permite cambiar la `View` sin afectar al `Model`] --- # .acidinline[MVC] como patrón (compuesto) de diseño <div class="figure"> <img src="images/HeadFirstDesingPatterns17.png" alt="MVC-Observer from Head First Design Patterns" width="90%" /> <p class="caption">MVC-Observer from Head First Design Patterns</p> </div> --- # .acidinline[MVC] proporciona .large[
_separation of concerns_] .large[
componentes _reutizables_] .large[
componentes pueden _desplegarse_ independientemente] .large[
componentes pueden _testearse_ independientemente
EI1048] -- .large[
desarrollo en paralello] .large[
`Model` puede tener multiples `View`s] .large[
alta cohesión: un `Controller` agrupa acciones relacionadas] ??? *Separation of concerns* (separación de responsabilidades) permite una fácil modificación ya que todas las responsabilidades están separadas, lo que simplifica el desarrollo o modificación futura de la aplicación o sistema. --- # .acidinline[MVC] como patrón de arquitectura <br/><br/><br/><br/> .center[.large[Además de afectar a toda la aplicación, MVC entra en un escenario más complejo con la introducción de la Web (__Web MVC__) y los frameworks modernos (__Web & mobile frameworks__)]] -- <br/><br/> .center[.large[
¿Platform _vs._ Framework?]] ??? ¿Cambiamos de gorra o nos ponemos las dos a la vez? **(Web) Framework** = conjunto de componentes personalizables e intercambiables para el desarrollo de una aplicación (web). Permitir a los desarrolladores implementar su propia aplicación utilizando funcionalidades común y reutilizables. **Platform** = ofrece herramientas y/o funcionalidades **out-of-the-box** configurables hasta cierto punto. --- background-image: url(https://hackernoon.com/hn-images/0*1VVNmPlwpfeytDMh) background-size: contain # Web MVC ??? Image credits: [hackernoon.com](https://hackernoon.com/from-mvc-to-modern-web-frameworks-8067ec9dee65) --- # Web MVC .pull-left[ <div class="figure"> <img src="https://hackernoon.com/hn-images/0*1VVNmPlwpfeytDMh" alt="Web MVC from hackernoon.com" width="100%" /> <p class="caption">Web MVC from hackernoon.com</p> </div> ] .pull-right[ .large[
`Controller` gestiona la petición inicial, no la `View`] .large[
La `View` "amasa" HTML, JS y CSS (_templating_) para el _browser_ en vez de presentar datos y manejar entradas de datos] .large[
HTML/JS tiene lógica (_button click handlers_) que lanza acciones al `Controller` via peticiones HTTP] ] ??? https://hackernoon.com/from-mvc-to-modern-web-frameworks-8067ec9dee65 --- background-image: url(https://hackernoon.com/hn-images/0*dTPUy_vSyQPHe-kX) background-size: contain # Web Frameworks ??? Image credits: [hackernoon.com](https://hackernoon.com/from-mvc-to-modern-web-frameworks-8067ec9dee65) --- # Web Frameworks .pull-left[ <div class="figure"> <img src="https://hackernoon.com/hn-images/0*dTPUy_vSyQPHe-kX" alt="Modern Web Frameworks from hackernoon.com" width="100%" /> <p class="caption">Modern Web Frameworks from hackernoon.com</p> </div> ] .pull-right[ .large[
[Single-Page Applications (SPA)](https://en.wikipedia.org/wiki/Single-page_application) precarga recursos una sola vez para UX más fluida] .large[
Nuevas SPA (_static bundles_) se sirven con baja latencia] .large[
SPA realiza peticiones HTTP para obtener recursos via `API Controller`] ] ??? https://hackernoon.com/from-mvc-to-modern-web-frameworks-8067ec9dee65 --- class: inverse, center, middle .heat[Model-View-Presenter (MVP)] .large[o Android MVP Architecture] --- # .heatinline[MVP] Model-View-.heatinline[Presenter] <div class="figure"> <img src="https://miro.medium.com/max/1400/0*CNMHroWFQUOEC-PI.png" alt="MVC-MVP from medium.com" width="100%" /> <p class="caption">MVC-MVP from medium.com</p> </div> ??? https://medium.com/@tinmegali/model-view-presenter-mvp-in-android-part-1-441bfd7998fe --- # .heatinline[MVP] Model-View-.heatinline[Presenter] .pull-left[ <div class="figure"> <img src="https://miro.medium.com/max/1400/0*nryKBiuwZthT--SA.png" alt="MVP-Android from medium.com" width="100%" /> <p class="caption">MVP-Android from medium.com</p> </div> ] .pull-right[ .large[
`Model` y `View` igual; `Presenter` es el nuevo `Controller`] .large[
`Presenter` actúa de mediador entre `View` y `Model`] .large[
1:1 mapping entre `Presenter` y `View`. Un `Presenter` gestiona una `View`] .large[
Mayor separación entre `View` y `Model` facilita Unit tests] ] ??? https://medium.com/@tinmegali/model-view-presenter-mvp-in-android-part-1-441bfd7998fe --- # .heatinline[MVP] ¿Cuando utilizarlo? .large[
en desarrollos de aplicaciones moviles en Android] .large[
si tenemos flujo bi-direccional de acciones en la pantalla] .large[
si decisión/interacción del usuario afecta UI] ??? ¿MVP más apto para desarrollo móvil? --- class: inverse, center, middle .cold[Model-View-ViewModel (MVVM)] --- # .coldinline[MVVM] Model-View-.coldinline[ViewModel] <div class="figure"> <img src="https://upload.wikimedia.org/wikipedia/commons/8/87/MVVMPattern.png" alt="MVVM from Wikipedia" width="100%" /> <p class="caption">MVVM from Wikipedia</p> </div> --- # .coldinline[MVVM] Model-View-.coldinline[ViewModel] .pull-left[ <div class="figure"> <img src="https://docs.microsoft.com/en-us/previous-versions/msp-n-p/images/hh830877.1afe20bab0052f5ab0fc400bf3b6f3f7(en-us,pandp.10).png" alt="MVVM from MSDN" width="100%" /> <p class="caption">MVVM from MSDN</p> </div> ] .pull-right[ .large[
`ViewModel` es el nuevo `Presenter`] .large[
`ViewModel` ofrece el modelo exacto que le gusta al `View`] .large[
`ViewModel` tiene un _binder_ para sincronizacion automática entre propiedades enlazadas (_bounded_) del `View` con `ViewModel`] .large[
`ViewModel` se mantiene sincronizado con `Model`] ] ??? https://docs.microsoft.com/en-us/previous-versions/msp-n-p/hh848246(v=pandp.10)?redirectedfrom=MSDN --- # Modern Web (& mobile) frameworks ### .acidinline[(Push-based) MVC]
[Spring MVC](https://vuejs.org/), [Ruby on Rails](http://rubyonrails.org/), [Django](https://www.djangoproject.com/)... ### .heatinline[MVP]
[Lavarel](https://laravel.com/), ... ### .coldinline[MVVM]
[VueJS](https://vuejs.org/), KnockoutJS, [EmberJS](https://emberjs.com/), [Angular](https://angular.io/)... --- class:center, middle # Ten en cuenta que -- .large[Los frameworks modernos ya no se ajustan fielmente a las tres capas clásicas (M,V,C), ni resulta fácil clasificarlos dentro de las variantes MVC] -- .large[Surgen más capas ([Middleware](https://laravel.com/docs/8.x/middleware), [Requests](https://laravel.com/docs/8.x/requests),...) por complejidad y necesidades crecientes] -- ### Organiza y estructura tus apps de forma que soluciones tus problemas ??? MVC frameworks observe a push-based architecture, also known as ‘action-based.’ They adopt actions that do the necessary processing and then accordingly ‘push’ the data to a view layer to furnish the outcome. Some examples of frameworks are https://hackernoon.com/from-mvc-to-modern-web-frameworks-8067ec9dee65 https://www.monocubed.com/10-most-popular-web-frameworks/ --- class: inverse, center, middle .fat[View, Interactor, Presenter, Entity, and Router Model (VIPER)] --- # .fatinline[VIPER] Apple-style MVC for iOs apps <div class="figure"> <img src="https://koenig-media.raywenderlich.com/uploads/2020/02/viper.png" alt="VIPER from raywenderlich.com" width="100%" /> <p class="caption">VIPER from raywenderlich.com</p> </div> --- # .fatinline[VIPER] Single Responsability Principle .pull-left[ <div class="figure"> <img src="https://koenig-media.raywenderlich.com/uploads/2020/02/viper.png" alt="VIPER from raywenderlich.com" width="100%" /> <p class="caption">VIPER from raywenderlich.com</p> </div> ] .pull-right[ .large[
`View` o UI] .large[
`Interactor` o lógica de negocio, media entre `presenter` y datos] .large[
`Presenter` gestiona tráfico de datos/acciones] .large[
`Entity` o modelo de datos] .large[
`Router` gestiona navegación entre pantallas] ] ??? https://www.raywenderlich.com/8440907-getting-started-with-the-viper-architecture-pattern --- # Recursos - .large[Wikipedia: [Model–view–viewmodel](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel), [Model–view–presenter](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93presenter)] - .large[[From MVC to Modern Web Frameworks](https://hackernoon.com/from-mvc-to-modern-web-frameworks-8067ec9dee65)] - .large[[The MVC, MVP, and MVVM Smackdown](https://academy.realm.io/posts/eric-maxwell-mvc-mvp-and-mvvm-on-android/)] - .large[Model View Presenter (MVP) in Android, [Part 1](https://medium.com/@tinmegali/model-view-presenter-mvp-in-android-part-1-441bfd7998fe), [Part 2](https://medium.com/@tinmegali?p=a15e35891095), [Part 3](https://medium.com/@tinmegali/model-view-presenter-mvp-no-android-parte-3-f0b0a6966579)] - .large[[MVP for Android: how to organize the presentation layer](http://antonioleiva.com/mvp-android/)] - .large[[10 Popular Web Frameworks for Web App Development in 2021](https://www.monocubed.com/10-most-popular-web-frameworks/)] - .large[[MVC vs MVVM vs MVP vs VIPER: Which design architecture is suitable for iOS?](https://www.techaheadcorp.com/blog/mvc-vs-mvvm-vs-mvp-vs-viper/)] - .large[[Getting Started with the VIPER Architecture Pattern](https://www.raywenderlich.com/8440907-getting-started-with-the-viper-architecture-pattern)]