GarrettW.wiki

My personal knowledge base

User Tools

Site Tools


php_framework_paradigms_compared

Table of Contents

True MVC

  • Original design motivation: separating presentation from domain concerns. The division between the input and output of the application (which resulted in the concept of the Controller component), was really a byproduct of addressing complexities inherent to the host platform (Smalltalk). Today’s development environments have come a long way in shielding developers from such complexities making divisions between device input and output at the application level unnecessary.
  • View can and should access the model directly. In some implementations, the view is automatically notified by the model of changes in state (Observer) which require a screen update.
  • View must be informed of each change so that it can update its display. Yet the model need not take responsibility for communicating the changes to the view because these changes occur only by requests from the user. The controller can assume responsibility for notifying the view of any changes because it interprets the user's requests. It could simply notify the view that something has changed – the view could then request the current state from its model. (Paraphrase of Burbeck, 1992)
  • “… user takes some input action and the active controller notifies the model to change itself accordingly. The model carries out the prescribed operations, possibly changing its state, and broadcasts to its dependents (views and controllers) that it has changed, possibly telling them the nature of the change. Views can then inquire of the model about its new state, and update their display if necessary.” (Krasner & Pope, 1988)
  • Views are not templates but rather use templates for rendering.
  • Models store state.
  • Views always have contracts with Models.
  • The less the Controller does, the better.
  • Views and Controllers have a one-to-one relationship.
  • Views deal with output while Controllers handle input. Both interact with the Model.

MVVM

  • Problems are created by the view accessing the model directly:
    • Reduced reusability of the view because the model now needs to have a very specific interface. Should the model know how it is going to be used? No.
    • The cause of confusion is the term “Model”. When people refer to Models they generally mean “Domain models”. In MVC, while the Model does contain these things, the domain model is not the Model referred to in MVC. The MVC Model does encapsulate domain models, but although you can write a MVC Model which does the job of a domain model, it's impossible to use a domain model as an MVC Model.
  • Ideal solution to allow model and view to be reused without modification; enter MVVM, where the “Model” is actually the domain model, and the ViewModel (helper) is basically MVC's Model.
  • ViewModel contains all interaction between View and Model. The basic premise is that the view only communicates with the helper (not the domain model directly) and that the view helper communicates with the model (not the view). This creates a simple one way data flow. Model←View Helper<View.
  • In this paradigm, the Template contains the HTML and has a contract with domain models. It's just another variable that the view uses. The template has a dependency on the ViewModel. Each template will be used with a single ViewModel (Though can potentially be reused by other ViewModels which share the same interface).
  • The View contains all the display logic for interacting with the template and is the only place the template is interacted with directly. Most of the time it will simply assign the helper to the template. When a View is defined it should also define an interface for the helper which it is going to use. It does not interact with models directly. It uses a ViewModel to get any data it needs from the model.
  • The ViewModel implements the specific interface defined alongside the view. E.g. FormView will require a ViewModel which implements the interface FormViewModel. The ViewModel's job is to link the model layer to the view layer and store the state of the application. This ViewModel will always be incredibly minimalist. It will never contain complex logic, database access, it's a simple wrapper to enable view to access it's data.
  • The ViewModel fully replaces the controller.

MVVMC

  • Is a controller needed? It handles settings states on the ViewModel based on user input, updating the model, and is linked to one ViewModel and one View.
  • Yes, because it helps separation of concerns. ViewModel has read-only access to the Model, and controller has write access.
  • Advantages over MVVM:
    • Better separation of concerns leading to easier isolation of features therefore improved testability
    • Higher application flexibility
    • Reusability of ViewModels with multiple controllers
  • Advantages over MVC:
    • Makes the view easily reusable by abstracting common logic
    • Removes dependency on the model from the view
    • Removes logic used only for display purposes from the model
    • Allows the model to represent the state of the domain by abstracting the state of the view into ViewModels
    • Gives the view a state resulting in domain models having a single instance throughout the application
    • Introduces testability into otherwise untestable UI code
  • One question remains: Should the view expect a specifically structured data set from its ViewModel? To allow a completely reusable view, the format of the data should be consistent. This would allow for reusable templates.
    • In MVVM proper, the ViewModel contains a large amount of of binding logic. That is, it would query the model for the required data and return it in a format expected by the view. So it would need to know about the structure of both.
    • It would be better to return objects (such as one representing a product or a user) from the model directly to the view via the ViewModel. This goes against the principles of MVVM where the View has knowledge and a dependency only on the ViewModel. A dependency on the model is a step backwards but a worthwhile one to heavily reduce binding logic.
    • The answer to this is to couple the template to the ViewModel. For example, the UserListViewModel's findAll() method would return an array of “User” objects. The ProductListViewModel's findAll() method would return an array of “Product” objects. By removing any reusability requirement from templates (Which is of very little benefit anyway) the complexity of ViewModels is reduced and any binding logic inside ViewModels is removed almost entirely.
    • The HTML template is really just another variable returned by the ViewModel. The template has a dependency on a specific ViewModel, and though multiple ViewModels could potentially use the same HTML template, it's unlikely in most cases. Because of this, allowing the template to have knowledge of domain models is beneficial, even if it doesn't quite conform to the original pattern.
  • Finally, an overview:
    • Model - Stores the state of the domain. Accessed by Controllers for writing and by ViewModels for reading
    • View - Contains the display logic related to a specific view (e.g. forms, tables, paginated data). Has a dependency on the ViewModel only
    • ViewModel - Stores the state of the view (including the HTML template) and has the job of fetching data from the model for use in the view
    • HTML Template - Really part of the ViewModel but a component in its own right. Stores the HTML which is used by the View. The template can be manipulated by the View or request data from the ViewModel
    • Controller - Takes a user action and updates the Model and/or ViewModel where required

HMVC

  • “widgetization” of content structures, or the ability to dispatch sub-requests to a Controller to handle these responsibilities
  • allows you to serve both internal and external requests with the same controller

MVP

  • Used for UIs
  • Communication is bidirectional
  • View is passive and confers events to the Presenter or Supervising controller, which then updates the Model.
  • When the Model has a response to an update, a state-change event is fired to the Presenter which then updates the passive View.
  • One version has:
    • Selections are components which specify what portion of the data within the Model is to be operated upon.
    • Commands are components which define the operations which can be performed on the data.
    • Interactors are components which address how user events are mapped onto operations performed on the Model, such as mouse movements, keyboard input, and the selection of checkboxes or menu items.
  • Another later one removes the above 3 parts, and is more like MVC - except that in MVC the Controller intercepts user input, while the Presenter focuses on updating the Model. It only intercepts View events as a byproduct.
  • Presenter contains all presentation logic. It orchestrates the overall interaction of the other components within the application. Its roles include the creation of the appropriate Models, Selections, Commands, Views, and Interactors, and directing the workflow within the application.
  • Examples: .NET, Nette, RhubarbPHP
  • At one extreme, the view is entirely passive, forwarding all interaction operations to the presenter. In this formulation, when a user triggers an event method of the view, it does nothing but invoke a method of the presenter that has no parameters and no return value. The presenter then retrieves data from the view through methods defined by the view interface. Finally, the presenter operates on the model and updates the view with the results of the operation.
  • Other versions of model-view-presenter allow some latitude with respect to which class handles a particular interaction, event, or command. This is often more suitable for web-based architectures, where the view, which executes on a client's browser, may be the best place to handle a particular interaction or command.
  • Difference with MVC:
    • The Presenter acts as an overall manager for a particular subsystem within an application. It maintains the lifecycle and relationships between the Views, Interactors, Commands, Selections, and Model. The responsibility for intercepting user events is governed by Interactors; therefore Presenters are not needed for each widget on a given View as were Controllers. There is generally a single Presenter per View, though in some cases a Presenter may manage multiple logically related Views.
    • Interactors are somewhat analogous to Controllers. They are the components which respond to user events and in turn call the appropriate Commands and Selections of the Model.

PAC

  • Abstraction (Model) - retrieves and processes the data
  • Presentation (View) - formats the data
  • Control - handles flow of communication between the other two
  • Each PAC triad can communicate with other triads through the controller
  • Within each triad, View and Model are completely insulated and thus can be multithreaded

ADR

  • A web-specific refinement of MVC
  • We generally route and dispatch not to a controller class per se, but to a particular action method within a controller class.
  • We commonly think of the template as the View, when in a web context it may be more accurate to say that the HTTP response is the View.
  • Action is the logic that connects the Domain and Responder. It uses the request input to interact with the Domain, and passes the Domain output to the Responder.
  • Domain is the logic to manipulate the domain, session, application, and environment data, modifying state and persistence as needed.
  • Responder is the logic to build an HTTP response or response description. It deals with body content, templates and views, headers and cookies, status codes, and so on.
  • The web handler or front controller receives a client request and dispatches it to an Action.
  • Differences with MVC:
    • View/Responder may use Domain/Model objects but does not interact with the Domain directly
    • Action classes are devoted to a single action, unlike Controllers which contain several action methods
    • Controllers merely use Views to generate output. Actions hand over control completely to the Responder.
    • Responder may incorporate any kind of View/template. Don't need different responder for each View.
php_framework_paradigms_compared.txt · Last modified: 2016/09/20 10:27 by Garrett W.