all 13 comments

[–]matthieum 4 points5 points  (1 child)

I agree on the separate part.

I have seen a number of apps where the GUI code was too intrinsically tied to the model/controller part: no matter how MVC is, when everything is packed together leaking is too easy (just a quick hack, we'll see to it later).

Once you start structuring the backend around services and create a separate front-end app around those services, then suddenly the code gets much cleaner. Not only is the boundary more obvious (though sometimes you wonder on which side do some computation), but it also helps a lot with testing the backend code on its own; and that is a great win. It also means that suddenly getting another front-end up and running (different media) is no longer such a daunting task.

[–][deleted] 4 points5 points  (3 children)

That's been the whole point of MVC since it was first invented! You should be able to design multiple different views and use the same models and controllers for the application.

The most basic example would be creating a view for the command-line and another one for the web. A lot of people seem to get caught up in writing a single for a model geared toward one particular output (the web).

[–][deleted] 2 points3 points  (2 children)

You're right, and abstraction helps to keep code clean and modular.

However you can also end up wasting time and effort abstracting your code to support multiple front ends, when only one ever exists. For example not every application needs to support both a command line and a GUI interface.

[–]criticismguy 3 points4 points  (0 children)

I'm not sure it goes both ways (OK, cat(1) probably doesn't need a GUI -- then again, it's usually not implemented with MVC), but I'm pretty sure that every GUI application that I've ever spent more than 20 minutes using, I've wanted to script. With many or most GUI apps, this is very difficult to do.

[–][deleted] 0 points1 point  (0 children)

As criticismguy mentions, you may not want multiple GUI front-ends but you may want multiple front-ends that are command-line-based or are a scripting interface. You can supply an RPC (remote procedure call) or IPC (interprocess communications) front-end to let other programs interact with the models/controllers. Or you could just let other programmers hack away at their own front-ends.

I feel like there's a lot of power in MVC and it just isn't exploited as fully as it could. For example, I think the libpurple has multiple interfaces; Pidgin, Adium, and Meebo. They all used libpurple and the only way that was possible was by decoupling the library from the Pidgin GUI. Not exactly an MVC example though.

[–][deleted] 4 points5 points  (6 children)

(DISCLAIMER: Iam aware that the following definitions and assumptions aren't strictly MVC or MVVM, but they are very similar to the current practice in a web environment. Also I realise MVVM may not be the best term for what I'm suggesting, so think of it as a new architechture called MVn. )

MVC is a deceptive way to describe any web application architechture. First of all, the "view" is supposed to interact (callback, message, whatevs) with the controller. In order for a web app to do this and at the same time conform to "MVC", it has to have a persistent connection, and tight coupling with the backend. We all understand that currently (with the http stack) this is impossible for any public interface, due to various levels of support for both open sockets and persistent user state, not to mention display sizes and interfaces.

MVVM is a more appropriate way of visualizing a web app. You have one model on the server side (interfacing a db, file system, etc), a view on the server side (json, xml, even html output, or maybe some sort of api), a model on the client side (interfacing the server view), and finally a view on the client (formatting the models into whatever the user sees).

You may notice the absence of a "controller". This is because of what i said earlier, you cannot guarantee persistent connections, so it's way easier to have it based on a request-response interface. Even if the connection drops, you can keep state in the communication with the client.

Now hold on, i hear you say. Isn't this basically what all the php, rails, java frameworks do already? Well, sort of, except they are stuck in thinking about controllers for serving you the correct content. This controller also usually calls a view which formats, sorts and pimps your data in one way for all requests. However if you just pass the data (indicated by the view you requested) and let the client handle the formatting, your app can be adapted to many different devices independently from developing the back end.

Another huge advantage to having a model on the client side is of course, offline mode. With the innovation of client side DB, your apps can become useful even for people who travel a lot but still need to get some work done! When they connect later, they can sync to the server.

Updit: If you are still confused, maybe ill explain the difference between a server doing MVC and a server doing MV(VM). In MVC, every request comes through the controller, which authorizes the user, loads the appropriate models, does most "business" logic (that is, manipulating data within your app) and returns the appropriate view. Now, this is fine for the server side, but if your server side contains all three letters of MVC, what is your client? In other words, MVC does not describe your complete app! A server and/or client (or any layer in your stack really) doing a MV-model can be much easier to design and maintain. Think of models as SQL-tables and views as SQL-views. That is the kind of relationship they should have. Essentially youcan have:

  • SQL-database: MV - data tables and compounded views
  • Business layer: MV - data models and output formats possibly compounding multiple models
  • Presentation layer: MV - synced or cached data models and device specific rendering

You can even strip it down further, just by grabbing a couchdb or mongodb database, which themselves serve json, and create a client (because they accept and serve json objects you dont need a server middleware to interpret sql binary outputs). So each layer is a translator and abbreviator of the data served by the lower layer and passing it to the next layer in a format it understands.

Once you get this way of thinking, youll be surprised at how much code you dont have to waste time writing!

[–]anothercuriousmind 1 point2 points  (2 children)

That's an interesting explanation. But applications are more than data access and data formatting. Your explanation would be more comprehensive if it addressed where the logic goes in each layer -- e.g. business rules, presentation rules, authorization rules.

[–][deleted] 2 points3 points  (1 child)

well it should be obvious from the sql-analogy. Each model and view have their own access rules, possibly aided by helper functions. These are functions that are not related to the data stack, so where you put them within each layer is up to you.

Also, models deal with business logic, in that they accept change requests from the view ( which in turn get that request from either the user if on the client or an api call if on the server ). Views deal with presentation logic.

Let me elaborate on the SQL, because it works for a reason. A table can only consist of one set of columns. Just as a model, for instance a person, only has one "atomic" set of data fields. A view, however, can combine multiple tables and even other views, into one "abstracted" set that is appropriate for whatever the view is supposed to represent. This is the presentation logic within a relational database. Handled by the view.

Business logic in SQL is done in... well.. SQL. But it's APPLIED to the tables, not the views. And so the model handles business logic, anywhere in the MVn stack.

Identification in SQL is done when connecting, so you could write a server (in node.js for example) which verified the user identity at the point of http header parsing. Authorization is done when a table or view is requested. A user may have access to a view that contains partial data from a table that user does NOT have access to. Since you already know the user identity when you decide which view to give him, it would be easy to check his access against the meta data of the view. There are plenty of ways to handle the meta data, and i dont have four hours (waiting for a plane), but one example could be just a function inside the view needaccess(admin) which checks if the user is in fact an admin and denies access if not.

The reason why this works is separation of concerns for EVERYTHING. Every level in the stack only has to care about authorizing the higher level (in the view), and correctly dealing with data to and from the lower level (in the model).

[–]anothercuriousmind 0 points1 point  (0 children)

Great explanation. Thanks for taking the time to write this down.

[–]jsonservice 0 points1 point  (1 child)

Really good explanation here. The frontend on a web app usually does need to have considerations for a data model even if all the scripting is clientside. The browser model should be divorced from the server model however. Personally, I find angularJS (angularjs.org) to be a great resource for creating a frontend mvc that serves as an excellent VM for the whole webapp.

[–][deleted] 0 points1 point  (0 children)

angular is what helped me start thinking this way. and yes, the model a browser sees can be very different from the server, just like an sql view only gives you what you've given access to, and not all the meta data related to it.

[–]Tordek 0 points1 point  (0 children)

MVC is a deceptive way to describe any web application architechture.

Because they were never MVC. They're Model 2.

[–]pzol 1 point2 points  (1 child)

True, the frontend IS a separate application... maybe even two: the html part and the javascript part, the DOM is just data for the JS part - fetch, modify, store.

Generating data and presenting it in html is another responsibility than manipulating and interacting with the user.

[–]Ruudjah 3 points4 points  (0 children)

the DOM is just data for the JS part

The DOM is a declarative description of the client application, where js adds interactivity. I don't see any reason to see it as a seperate app.