MVC, MVP, MVVM
class: center, middle .title[ Front-end training # MVC, MVP, MVVM ] --- class: center, middle .title[ #Spagetti Code ]  --- class: center, middle  --- class: center, middle .title[ # Separated Presentation ] # The idea behind [Separated Presentation](http://martinfowler.com/eaaDev/SeparatedPresentation.html) is to make a clear division between domain objects that model our perception of the real world, and presentation objects that are the GUI elements we see on the screen. --- class: center, middle .title[ # MVC ] --- # MVC .img-wrap-70[] - Model–View–Controller (MVC) is a software architectural pattern for implementing user interfaces. - Since 1979 (Trygve Reenskaug). Smalltalk-80 (Jim Althoff) - It divides a given software application into three interconnected parts, so as to separate internal representations of information from the ways that information is presented to or accepted from the user. --- # Observer ``` javascript function Subject(){ this.observers = []; } Subject.prototype.addObserver = function( observer ){ this.observers.push( observer ); }; Subject.prototype.removeObserver = function( observer ){ var observerIdx = this.observers.indexOf(observer, 0); this.observers.splice( observerIdx, 1); }; Subject.prototype.notify = function( payload ){ var observerCount = this.observers.length; for(var i=0; i < observerCount; i++){ this.observers[i].update( payload ); } }; ```
See in action on jsbin.com
--- # MVC + JS .img-wrap-70[] - Model–View–Controller (MVC) is a software architectural pattern for implementing user interfaces. - Since 1979 (Trygve Reenskaug). Smalltalk-80 (Jim Althoff) - It divides a given software application into three interconnected parts, so as to separate internal representations of information from the ways that information is presented to or accepted from the user. --- # MV* illustration .img-wrap-70[] --- # Model ```javascript var PhotoModel = function (data){ this.name = data.name; this.date = data.date; this.url = data.url; this.validation = function(){ //validation here } this.formatName = function(){ this.name.toUpperCase() } return this; }; var photoModelInstance = new PhotoModel({ name: 'myPhoto', date: 'today', url: 'http://example.com/mPhoto.jpg' }) ``` Model is where the application’s data objects are stored. - Doesn’t know anything about views and controllers. - Notifies its associated views and controllers when there has been a change in its state. - May have additional features: conversions, validations, computed properties, access control. --- # View ```javascript var photoView = function ( photoModelInstance, photoController ) { var render = function () { // rendering logic $('#photo').html("
" +photoModelInstance.name + "
"); }; //subscribe to model changes photoModelInstance.addSubscriber( render ); photoEl.addEventListener( "click", function () { //controller do some work photoController.handleEvent( "click", photoModel ); }); }; ``` View requests information from the model that it needs for generating an output representation to the user. - Doesn’t care how to get the data or where the data comes from. - May use the existing HTML or may build new HTML --- # Controller ```javascript var PhotoController = function () { this.handleEvent = function(){ //do something important //e.g. update model } this.init = function () { var photoModelInstance = new PhotoModel({ name: 'myPhoto', date: 'today', url: 'http://example.com/mPhoto.jpg' }); var photoViewInstance = new photoView(photoModelInstance, this); } return this; }; ``` Decision maker and the glue between the model and view. - Updates the model when the user manipulates the view --- # Controller like behaviour in BackboneJs ```javascript var PhotoRouter = Backbone.Router.extend({ routes: { "photos/:id": "route" }, route: function( id ) { var item = photoCollection.get( id ); var view = new PhotoView( { model: item } ); $('.content').html( view.render().el ); } }); ``` 'C' part of MVC may have different functionality in different frameworks --- # What does MVC give us? This separation of concerns in MVC facilitates simpler modularization of an application's functionality and enables: - Easier overall maintenance. When updates need to be made to the application it is very clear whether the changes are data-centric, meaning changes to models and possibly controllers, or merely visual, meaning changes to views. - Decoupling models and views means that it is significantly more straight-forward to write unit tests for business logic - Duplication of low-level model and controller code (i.e what we may have been using instead) is eliminated across the application - Depending on the size of the application and separation of roles, this modularity allows developers responsible for core logic and developers working on the user-interfaces to work simultaneously --- class: center, middle .title[ # MVP ] --- # MVP .img-wrap-70[] - Model-view-presenter (MVP) is a derivative of the MVC design pattern which focuses on improving presentation logic. - Since 1990 (Taligent) - Presenter is a component which contains the user-interface business logic for the view - Passive View --- # Presenter - 2 way communication with the view - View Communication: The view communicates with the presenter by directly calling functions on an instance of the presenter. The presenter communicates with the view by talking to an interface implemented by the view (IView). - There is a single presenter for each view --- # Benefits: - it increases the testability of our application - it provides a more clean separation between the view and the model --- # MVC or MVP?
--- class: center, middle # MVC or MVP?
Your browser does not support the video tag.
--- # MVC or MVP? - underlying concerns we may have with MVC will likely hold true for MVP - differences between them are mainly semantic - MVP is generally used applications where it's necessary to reuse as much presentation logic as possible - Applications with very complex views should use MVP because of one presenter is better than five controllers --- class: center, middle .title[ # MVVM ] --- # MVVM .img-wrap-70[] - MVVM (Model View ViewModel) is an architectural pattern based on MVC and MVP, which attempts to more clearly separate the development of user-interfaces (UI) from that of the business logic and behaviour in an application. - Since 2005 (Silverlight) - KnockoutJS, Kendo MVVM --- # Model ```javascript var PhotoModel = function (data){ this.fileName = data.fileName; this.fileUrl = data.fileUrl; this.date = data.date; // no more methods in model this.formatName = function(){ this.name.toUpperCase() } //only validation can be here this.validation = function(){} return this; }; var photoModelInstance = new PhotoModel({ fileName: 'myPhoto', fileUrl: 'http://example.com/mPhoto.jpg', date: new Date() }) ``` --- # View. Two way data binding ```html
{{ControlPanelVM.fileName}}
{{ ControlPanelVM.date | date : format : timezone}}
Save
``` View is simply a HTML document with declarative bindings to link it to the ViewModel - Displays information from the ViewModel, pass commands to it - Specific syntax. --- # ViewModel ```javascript function ControlPanelVM(model, config, service) { var vm = this; vm.uploadCompleted = true; vm.fileName = model.fileName; vm.fileUrl = model.fileUrl; vm.save = save; vm.getFileUrl = getFileUrl; function getFileUrl(){ return (config.hostUrl + vm.fileUrl + ''); } function save (){ service.save() } } ``` The ViewModel can be considered a specialized Controller that acts as a data converter. - Changes Model information into View information passing commands from the View to the Model. --- # ViewModel ViewModel (Example: WPF, Knockoutjs) - 2 way communication with the view - The ViewModel represents the view. This means that fields in a view model usually match up more closely with the view than with the model. - View Communication: There is no IView reference in the ViewModel. Instead, the view binds directly to the ViewModel. Because of the binding, changes in the view are automatically reflected in the ViewModel and changes in the ViewModel are automatically reflected in the view. - There is a single ViewModel for each view --- # MVC vs MVP vs MVVM ## MVC In MVC, the View sits on top of our architecture with the controller beside it. Models sit below the controller and so our Views know about our controllers and controllers know about Models. Here, our Views have direct access to Models. Exposing the complete Model to the View however may have security and performance costs, depending on the complexity of our application. MVVM attempts to avoid these issues. ## MVP In MVP, the role of the controller is replaced with a Presenter. Presenters sit at the same level as views, listening to events from both the View and model and mediating the actions between them. Unlike MVVM, there isn’t a mechanism for binding Views to ViewModels, so we instead rely on each View implementing an interface allowing the Presenter to interact with the View. ## MVVM MVVM consequently allows us to create View-specific subsets of a Model which can contain state and logic information, avoiding the need to expose the entire Model to a View. Unlike MVP’s Presenter, a ViewModel is not required to reference a View. The View can bind to properties on the ViewModel which in turn expose data contained in Models to the View. As we’ve mentioned, the abstraction of the View means there is less logic required in the code behind it. --- #What should I use? - Data binding (MVVM) - Connection between the view and the rest of the program is not always available (MVC) - Any other case (MVP) --- # Related resources - [Udacity course: JavaScript Design Patterns](https://www.udacity.com/course/javascript-design-patterns--ud989) - [TodoMVC - Helping you select an MV* framework](http://todomvc.com/) - [MVC app example: todo app](https://github.com/udacity/ud989-retain) - [MVC app example: pizza app](https://github.com/udacity/ud989-pizzamvo)