You know it's nice reading a criticism of something that has an alternative solution offered rather than just going "hey MVC is terrible and you're an idiot for using it".
I do however think there's still great benefits to MVC, if you're shovelling code into controllers and can't make it work like it should then MVC is not the right design pattern for the project. Like every other pattern it'll only work when it works, but MOVE sounds like an interesting addition that I might have a play with.
MVC is terrible for web apps (in the original local GUI domain it's fine for some things), you aren't an idiot for using it because you're probably not actually using it but rather only something loosely inspired by it, and the solution is simply DRY. MVC at its best is simply one manifestation of DRY, but there's no real reason to get too stuck on it when with practice DRY is something you should just always be doing. If MVC falls out of that, great, but if not, so what?
(The original MVC is actually useless for web apps because there is no client-server connection in it, and that profoundly changes everything. There's no point in trying to bash a GUI top-level design into a new client-server world, especially when DRY is just sitting there, waiting for you to use it.)
MVC, MOVE, all the variants just obscure your vision from the underlying and far more important principle.
I suspect this is because most people do not actually understand what MVC is and how it applies to server-client relationships; in fact, the wikipedia article on MVC is slightly off on the subject, assuming one accepts the original Xerox description as a source. Try not to wrap the entire complicated application into one big MVC umbrella because that will just confuse. There are actually multiple processes involved, and each has its own MVC.
The big epiphany for me was when I realized that the server has its own MVC, and the browser has its own MVC. The server's output is the View for the server and the Model for the browser. For a complex set of objects in a given Model, the final output of those objects is their View, and the consumer of that output uses it as a Model. In theory, any View can be a Model for the thing accepting the View, so in a complex system, you have a chain of MVCs.
And one can further imagine that applets written in JavaScript have their own MVC unit.
I work on complicated, large-data web apps sometimes daily. MVC has been a fine model for them and has kept my group's organization clean and modular.
> in fact, the wikipedia article on MVC is slightly off on the subject, assuming one accepts the original Xerox description as a source.
People complaining about factual inaccuracies on Wikipedia annoy me. It's Wikipedia. The entire point and purpose of it is to fix what you know is wrong.
For once, I'd like to see, "I just touched up the Wikipedia article on this subject to explain it a bit more accurately."
This can be a really frustrating experience with articles where most people hold misconceptions about the concepts. I spent a few months off and on on the REST article and managed to clean it up a fair bit, but I was constantly working against militantly ignorant people. Last I checked it's somewhere between accurate and bullshit, one of the poorer resources for understanding either actual REST or more popular RPC style APIs.
>"I just touched up the Wikipedia article on this subject to explain it a bit more accurately."
"But then all my changes were reverted by an overprotective editor; I brought the issues up on the talk page, but my comments were brusquely dismissed."
Your changes would still be in the edit log, and someone more savvy in Wikipedia politics would have the opportunity to get your changes cemented. Said person might be another HN reader who is less knowledgeable about the subject matter.
If you don't make any changes, he has nothing to work with except some random whining.
(And yes, that's how it works in the real world, too.)
>People complaining about factual inaccuracies on Wikipedia annoy me. It's Wikipedia. The entire point and purpose of it is to fix what you know is wrong.
This presupposes
1) I care about fixing it.
2) I have the knowledge to fix it (spotting and removing an inaccuracy is easy, knowing the correct and full set of facts to substitute it with not so much)
3) I can write well enough
4) The Wikipedia process is not convoluted and broken for casual contributors.
The article about MVC on Wikipedia wasn't just slightly off. For a long time, it was completely overrun by people who seemed to think MVC is an architecture for web apps. Real MVC, as the term had been used for decades before the web apps abused it and still is in interactive GUIs today, was all but relegated to a footnote.
"Touching up the Wikipedia article" has little value in cases like this. Usually the only remedy at that point is to delete the entire thing and start again, which somebody finally did not long ago.
"The big epiphany for me was when I realized that the server has its own MVC, and the browser has its own MVC."
While I'd still advocate DRY over this POV (unless of course DRY leads you here naturally), I will agree this is a generally valid viewpoint, because you've got the server-client model built in there instead of glossed over. And you are now the first person who has gotten me to be generally agreeable about MVC used in the web world.
Which raises the interesting question of building a framework that builds this idea into the core, with server-side MVC, client-side MVC, and some sort of defined crossover instead of the usual hacky stuff that emerges from single-MVC.
I am doing a simialr thing. Except ASP.NET MVC 4 Web API on the server and Angular.js on the client. It feels very natural and simple to me. What I find odd is Angular.js works very similar to Silverlight, and my whole setup has similarities to Silverlight with RIA services. Yet SL+RIA never felt natural at all and was very difficult. I've not narrowed down where the difference lies.
Angular is very impressive. There are lots of small things that make it nice to use. Among them:
The lexical/nested scoping in the templates is just perfect. I've reviewed the documentation of all competing frameworks, and I couldn't figure how to do it in any of them. Since it was a primary requirement for my app, I went for Angular.
The service-based architecture, and the automatic service injection in controllers, based on parameter names are pretty nice too, as is the fact that you can pass arbitrary parameters to filters.
In a calendar widget that displays a month, I pad the `month` array with days of the surrounding months in order to get complete weeks. I wanted to have these days styled differently. `dayName` and `idem` are custom filters.
<ul id="calendar">
<li ng-repeat="day in month.days"
class="day {{day.day|dayName}} this-month-{{day.month|idem:month.month}}">
<div class="date-number">{{day.date}}</div>
Events go here.
</li>
</ul>
I found a blog post that gives a rundown on the evolution of MVC (https://billkrat.wordpress.com/2010/12/23/hello-world/) and links something similar to the document I had originally read (http://heim.ifi.uio.no/~trygver/1979/mvc-2/1979-12-MVC.pdf). I think I had originally found something that was more of a prototype of this document, but the wording appears to be the same and more succinct. The blog post also links to an earlier version of the MVC model that included a fourth part, a "Thing".
One thing I found interesting in the blog article was the notion of "smart controls", but I can rationalize that away as another MVC module; after all, the Windows OS itself is handling all the interesting behavior, and the GUI app is borrowing the behavior. Depending on the toolkit that interfaces with the "smart controls", we get access to events (mousedown, keypress, etc) that can serve as input to one of our application's controllers.
Thank you for this comment. I was slowly losing my faith in HN developers knowledge.
Server MVC (Model2) is not the same as client MVC (the classic one). They are totally different architectures. Patterns that apply to one, don't apply to the other.
You can't get MVC with Rails/Django/Struts. You can get a nice MVC with a Single Page Application or with a desktop app.
This times 9000. I've noticed a trend amongst developers to jump at patterns and spend all their time trying to shoehorn their project into it because someone vaguely respected mentioned it on Twitter.
Patterns are great, but slavishly following them, and not understanding that there's often multiple patterns for different circumstances can lead to coding dragons.
I think this article goes even beyond the "is terrible and you're an idiot for using it", it actually "states" MVC is dead.
Honestly I'm sick of reading all those "x is dead"-alike articles. Hey, if you believe the web PHP is dead, Java is dead, C is dead.. etc... Technologies, patterns, languages or structures don't die, in fact, if you really fancy you could write your application using C code and compiling it into asm, why not? If it works, perfect! There are enough examples out there where old technologie works. And I think people tend to be spending too much time thinking why something is imperfect, or how to do it better, instead of actually making stuff that rocks.
If you really do have the need to improve something, prove it! Make a useable example, write a framework, library or new language if you really need to.
> And I think people tend to be spending too much time thinking why something is imperfect, or how to do it better, instead of actually making stuff that rocks.
I was with you until this. I think it's actually important to think about where flaws are and how improvements could be made.
The literary critic Howard Bloom actually argues that many of the best creative works are agonistic: they take a previous masterpiece and say, "I could do better," and from that claim do. The produced work ends up being a response, saying, "That was good, but here's your mistake, here's how it can be done better, and look how well it turns out."
MVC doesn't fit cleanly into the world of webapps, but it's still a lot better than business logic in view code, or monolithic classes than handle all HTTP interaction, etc. I've seen some really terrible Model 1 code in my lifetime.
Are there any MOVE frameworks yet? I very much like the idea, but one of my favorite tests for "correctness" in a program is to use it to build something. Although it could be (and probably is) a reflection on my lack of knowledge, I find myself "fighting" with MVC frameworks like backbone whenever I try to use them. I would love to see if MOVE would be any better.
I feel like you could still accomplish this with existing frameworks, though it'll be a bit of a hack. Perhaps split the controller in half, for instance LoginOperations and LoginEvents
I think the problem with most MVC frameworks is not the framework themselves, but that that the MVC design pattern should only be considered while refactoring existing working code. Starting right off the bat with a giant MVC boilerplate isn't necessary and may even be counter-productive.
I write my code initially as one monolithic controller, and then refactor my code into an MVC pattern. It doesn't take that long to move functions from one object an other, and now you're working with an already-functioning piece of code rather than guessing how things might work later on.
So this could be the part where I'm not that great a programmer, but the I've had trouble creating apps from scratch with MVC, not just refactoring existing code.
I don't think so, but I feel that Grails may be the closest thing currently. It has a concept of a Service construct that feels like an Operation. Then again I could be completely wrong.
MVC may not be a solid pattern for a client side framework. It makes sense to contain some semblance of state with in the presentation layer on the client side, rather than working with a stateless MVC pattern.
IMO MVC on the client side is just a carry over from people who were experienced in writing web apps who wanted something that felt familiar on the client side. It's a leaky abstraction at best.
I agree with this. I'm not particularly interested in client-side MVC frameworks because it wrongly trivializes the server component, and technically speaking any javascript running on the client is part of the view.
I'm not sure what the right answer is, but I certainly feel like the race for rich client-side apps had too many frameworks settle on MVC without thinking about the bigger picture.
This looks like a really good way to stop putting all your messy code into Controllers and start putting it into Operations.
The problem with messy code or where it lives will not go away because you think about it differently, you just have to either hire better people or spend more time and money refactoring.
The advantage of operations over controllers is the composability.
Whereas controllers have a pretty undefined lifetime, operations are finished when they're done. This means that operations can use each other to get work done, a pattern you don't see with controllers.
So basically he's just putting the controller methods in their own namespace. Which is all well and good, but I don't think anybody argues that all of your business logic has to be in the controller class for it to be considered MVC.
Out of the three terminologies (state, representation, flow), the third one is arguably the most tangled. I find it healthy to refactor it into reusable chunks (operations) and event-driven flow management.
The problem was, in my opinion, that operations should have not been put into controller units. It attracted more copy-paste solutions in my experience.
Operations are similar to controllers for sure. But where's routing or state? We don't have a full picture here.
After trying out that new meta-pattern, things get overly coupled, too many bi-directional relationships between state, views, models, and controllers/operations.
... I'm pretty sure typical MVC uses some form of event as well, i.e. an event is created to inform the view that the model has changed. (Even the wikipedia page differentiates passive MVC implementations where the language/platform cannot implement events.)
Somehow, I'm just seeing the Observer pattern and the MVC pattern in the OPs post.
Seems like a reasonable way to structure an application. It would be great to see a concrete example or two. The login example that is sketched out gets you partway there.
Services is where the logic of your application should live, and services should be HTTP (or any protocol) agnostic. They should only speak in models and native types, and should abstract all of your logic away from your controllers and models.
This leaves the controllers as a thin http handling layer that parses inputs and then lets the service handle the work.
The response from the service is then transformed appropriately (JSON, HTML, etc) and sent back to the caller.
This is certainly interesting. I like the event based model. Here are my thoughts:
If your controllers are getting fat and spaghetti like, I wouldn't blame MVC. There are many patterns one can use that are compatible with MVC without going to a completely different architecture. For instance, if you need to encapsulate multi-model interaction you can create a presenter abstraction that the controller simply calls into. Just because there is a bunch of code that ends up in the controller because "you don't know where to put it" doesn't mean there isn't a better place to put it without re-designing the entire application.
Another thing is while I love the data-binding event deal, this really only works for client-side frameworks like Backbone. Server-side kinda goes at the window, but I suppose you could add a framework that piped event signals in the response from changes that occurred in the ORM layer (although this further couples components).
I'm not convinced that separating the data from the methods that operate is a great idea unless you want to go purely functional. Doing this clearly breaks encapsulation, throws any notion of OOP out the window, and still binds the "operations" too closely to the data. Generally speaking, the data is useless without the operations and vice versa.
So the real difference between MOVE and MVC, at least according to this article, is that models are no longer useful on their own, the controllers aka "operations" know everything about how to manipulate models (it shouldn't), and models generate events which are only consumed by views, which makes no sense if you wanted to use the model on its own (but you can't without your operations).
Generally speaking, the model should MODEL something. That includes data and behavior. Without both, you have a database, and a set of operations kinda like a C library but only because OOP hadn't been invented yet.
In my mind this further couples all of the components because it actually increases the reliance on each other for them to be useful.
Sorry, but data-bound events are not useless in server context. It might be exactly what we need when fat controllers go out of control. Perhaps you meant they are too much of a complication if taken too far to work across all concurrent requests?
Binding data and behavior together breaks the rule of single responsibility, which I believe is far worse than designing separate roles in sepearate components that work together. Models should model the data structure only, if you need a presentation abstraction anyway for multi-model operations. Why not go the extra mile and use this abstraction level for all operations?
It is a false dichotomy that you go either full-OOP or purely functionaly. Models wrap knowledge as the article suggests, That means that, in addition to getters and setters, they might contain functions that let you check "is this the user's password?". I envision these methods to work on a single attribute, whereas multi-attribute and multi-model business logic belongs to operations.
MVC isn't dead, but it was a local maximum OOP gave us. Event-driven development seems to raise and work well with objects and datasets.
If "fat controllers go out of control" then you've already made multiple mistakes. I don't think re-inventing the wheel is the right approach to fixing a problem when the developer can understand their own mistakes instead of blaming a framework or architecture.
Are you suggesting that OOP breaks the rule of single responsibility? Any 'operation' that modifies the internal data should belong on the model. Would turnLeft() belong on a Car model? Or do you pass a Car into a turnLeft operation? In my mind a turnLeft operation shouldn't know the details of how to turn a car left, or a bike left, or a boat left. These operations belong in the Car, Bike, and Boat.
Somewhat pedantic, but just throwing this out there: cars, bikes, and boats are all forms of transportation which can turn. They should probably inherit the concept of turning left, and then specify the exact meaning in their context.
Obviously, I don't say "turn your handlebars such that the left side is closer to your chest," or "rotate your steering wheel counter-clockwise," when I mean to tell someone to turn left at the next intersection. I might, however, tell a sailor to steer to port at the next buoy. =)
EDIT: forgot to say, fwiw, that I agree that such actions do not belong in the model. The things go in the model, and the only actions the model should support are those relative managing the data in the model, not interacting with the data... That is, after all, what the controller is for.
... it was a roundabout way of explaining how right you were, or at least in my initial reading of it.
I see thing which is called a Car, an instance of which is stored in the Model, which may contain other things, including other types of Transports. The user interacts with the View, instructing a left turn - the controller grabs the Car (why it grabs the Car, and not the Bike is undefined =), and tells it to turn left. None of the M, V, or C understand what a left turn is - but the controller knows that the Car can perform such a thing if instructed. The Controller knows it can tell the Car to turn, because the Car is descended from a Transport, and all Transports have a virtual method for turning.
That last sentence was in my head and unfortunately took over my comment.
I think any logic inherently tied to the data should be in the model. The controller shouldn't have to worry about internals of the model any more than necessary.
Here's an example. Suppose I create an i18n framework for handling numbers. I certainly am going to include in it a function for converting the number into the current user's localized format, and another one for converting the number from the current user's localized format. I will probably also have functions to convert to/from db formats and to/from arbitrary formats. Not all of these will be called by the controller (in most cases, just the ones to/from the user's localized format and maybe an arbitrary format on rare occasions).
This way the controller script can just call something like $number->to_output; and get the localized string back. Other model objects can call $number->to_db and get a string suitable for entry into the db.
Interestingly in LedgerSMB 1.4 where we have done this, the number of cases where the model calls number i18n functions are remarkably small. These are usually called in the model or in the view simply because the controller probably shouldn't have to worry about this, and the view gets to worry about display logic.
Converting the display format of data when requested by a view is exactly what a model is supposed to do.
However, instructing a contained object to take some action at the user's request that is unrelated to display or management of contained objects is neither the responsibility of the view or the model, but specifically the task of the controller.
I want an email to be sent to me when the quantity on hand of a part gets below the re-order point.
So now, I build a program that listens for notifications, and when it gets one, loads the data, erases the queue, and sends me an email.
I build this so the app itself doesn't know this is required or is going on. Database triggers, queue tables listening scripts, and templates all are triggered when the db write takes place.
Now, what we have here are arguably two MVC environments where the model behavior of one triggers a model change in another, which triggers a controller to run, calls some other model stuff, creates an email (via a view) and sends it.
But this is the sort of action you are talking about, right? You think this violates separation of concerns?
This is very unclear - the database is not the model in the app, it's the storage for the model. (In its own application though, it may be a model...) You've abstracted some application functionality into the data storage, ok.
I'm speaking to the point that if you are separating Model, View, and Controller, and you have complex objects in your model that can do many things, it would not make sense to put all of the logic about what those things can do, how to do them, and when to do them in the model. Otherwise, you're simply blending the model and the controller (which may not be a wrong thing to do) - so you just have MV.
Let me give a more concrete example: I have a model which represents a network of connected complex "devices," there are five types of devices, each that can do 50 distinct things. The model can add a new device, delete a device, or retrieve an existing device. It can also ask the devices what their names, and addresses are, and what features they support, on behalf of any view which needs that information.
It cannot, however, tell device 1, which is of type X to take action "foo". That, instead, is implemented by a controller attached to a view that shows a big button that says "Do Foo", and a drop-down with the list of available devices that can do Foo. The view passes the press of the button onto the controller, which asks the model for the selected device, and then executes a "do Foo" command on it, and then, perhaps, contacts the device again to check that "Foo" was completed.
If all such logic were built into the model, I'd have several hundred methods in it, and I'd be very quickly looking for somewhere to move all of this logic, like, you know, controllers.
The database is not the model but the db operations are usually in the model, right?
My point though is in essentially shimming functionality. In my example, for example, here is how it would work.
1) User requests "save this invoice", which activates a controller script which automates the model elements for "invoice" instantiates an invoice (since this is a stateless web app) and saves it.
2) The model saves the invoice by writing it to the db.
3) Saving to the db fires a trigger which checks ROP vs on-hand and where ROP is greater saves a record in a queue table and issues an asynchronous notification, which doesn't have any immediate effect.
4) Controller commits the db transaction. The DB sends out the notification and makes the rows in the queue table visible.
5) Controller for application b wakes up (let's say every 15 min) and polls for notifications. Ok, we got one. Look up the queue table, prepare the email (model stuff) runt he template (view stuff) and sent it out (model stuff again).
So what I am getting at here is a way to have model events have side effects which are outside the scope of Application A, but are at least triggered by model operations. This is not an anti-pattern really because application A is not relying on those side-effects for operation. However if you look at application A as the primary one and application B as contained within it, then application B can only be described as contained within the model of application A, from application A's perspective, because all of its functionality is abstracted behind the model. From application B's perspective, there is a model, a view, and a controller, and it doesn't care as to where notifications and queue table data is coming from. From it's perspective it is a loosely coupled app in its own right.
But as always what I am suggesting is that common sense usually determines the best place for a given piece of logic. LedgerSMB is very model-centric but there are cases where we have a fair bit of logic in the controller.* I think that anything which is inherent in the model belongs in the model. So back to the vehicle analogy, a bike object should support a $bike->turn('l') and a $bike->turn('r'). However telling the bike when to turn left is the controller's job.
* for example in contact and employee management, the controller has to coordinate a lot of different model operations, leading to unusually long/complex model code in the system.
Couldn't agree more. As long as you find a consistent way of splitting and placing your "Controller" code, MVC works perfectly fine. The problem is that a "Controller" is only vaguely defined and always application dependent. However, finding a good split and place for code is not easily accomplished and, in my experience, needs a couple of iterations to be perfected.
The MOVE split seems useful for event based systems (webapps?), however it doesn't seem to encapsulate as wide a range of apps as the more vague MVC does..
Seems like the Operation layer is a combination of controllers and business logic, which feels like a bad idea to me. If the models only wrap knowledge, but don't do any work, then it's the part of the Operation to both decide what to show and also get it in the correct format to show. This seems like it's doing too much and is analogous to the MVC problem of really fat controllers.
On a flip side you can get models that do too much. At one point I had a method on a model that, in order to get data into correct format, just went and rendered a [Django] template. It came to that naturally, the line is thin, and I now prefer to err on the side of models doing too little.
> it's the part of the Operation to both decide what to show and also get it in the correct format to show
Did you mean Views, not Operations, here? Or maybe I'm missing something.
I think it's unfortunate that the author chose to use the word "model" in MOVE. It appears that the "model" in MOVE is not the same thing as it is in MVC. That risks confusing a lot of people.
This sure looks like MVC, but they call the Controller "operations".
The MVC abstraction has an issue with web applications, since the request-response cycle doesn't provide feedback as directly as the hardware-monitor-software cycle that the pattern was originally designed around.
However, if the problem is that you are putting too much "logic" into your controllers, you should probably find a better place for it.
In Java/Spring-MVC, there is a typical class hierarchy of Controller -> Manager/Service -> DAO. The extra level of indirection is a very handy place to put business logic, then each class in the tier has a dedicated function:
Controller -- Parses input, delegates the action and returns the response (rendered by the view).
Manager -- Handles sanitized data, encapsulates business logic and makes calls into the Model / Data layer.
DAO -- Interfaces with the data store, makes sure only good data goes in, and appropriate responses are returned.
This approach doesn't seem to offer anything more than that, except for putting a label on the messaging between subsystems, but those operations are not well defined (at least in this piece), and seem like another nebulous way to bury logic.
It seems like this problem has arisen from a rather narrow reading of what an MVC system should be, as in, not having utility libraries because they aren't strictly an M a V or a C.
Speaking of Java/Spring-MVC approach, I tend to have a mix approach of Service and Repository (since DAO seems to be getting a lot of bad-rep, time to pick a new name :D).
Controller -> Service (SOAP) or Resource (REST) [although Resource could simply forward to Service as well)
or
Controller -> Repository (for specific entity that requires no interaction with other entities)
Unfortunately the Service layer is necessary in the situation where there are 2 or more domain models need to interact with each other.
This seems to help writing test-automations by splitting the tests into 2 categories:
1) End-to-End w/ mock repository
2) Integration only at Repository level using in-memory DB (Derby, H2)
By doing this, we were able to speed up the test significantly.
I believe in Rails, you're tied with ActiveRecord and would require real database (be it SQLite3). There may be open source libraries that can intercept AR calls and re-route it to either fake DB or just simply fake 'em all, but not sure how popular/complete they are.
Well I think it depends, sqlite can behave as an entirely in-memory database I think - so what would be the difference between that and a pure ruby in-memory database, really?
If you want to just fake 'em all, which does not sound particularly ideal, people just generally mock em
Yes, my bad for not clarify it: mock the repository part, but not to mock as an entire ActiveRecord.
for example:
FriendsRepository.java is an interface that can be mocked during unit-test while the integration-test would use the actual implementation.
I know that the Java solution tend to be brittle because it somewhat forces people to have 1 interface, 1 class implementation (the mock implementation would be provided by mocking library).
It's very similar you're correct, particularly when you add in the Manager/Service layer (something that I hadn't spent enough time investigating).
The main advantage of Operations over controllers is that they're fully composable. You can take the operation that logs a user in (which displays the login screen, and awaits the user typing a username and password) and use it as a sub-part of any other operation.
In a purer MVC world you get something similar to this by making a function that instantiates the login controller with its associated view; that's pretty good, but there's no obvious place to put that function.
I'll certainly be following up with more details, and some actual code.
Right, but in an MVC web-app, the Controller defines the "end-point". Meaning it should end there. The composition of different pieces of functionality should be happening in the area of the business logic.
I understand the motivation, and have come across several situations where I wanted "controllers calling controllers", but ultimately, you're repurposing a piece of the architecture to do something it shouldn't be doing. A controller handles the input into the system, it shouldn't be defining a workflow.
> In a purer MVC world you get something similar to this by making a function that instantiates the login controller with its associated view; that's pretty good, but there's no obvious place to put that function.
That just sounds backwards to me. Are talking about creating dynamic endpoints? That sounds like a much bigger headache than composing stuff in a service layer.
MVC can be a little ambiguous, and with web-frameworks it can be hard to see that each piece is actually a subsystem. The Model isn't just your model class, its the model class, the DB and the ORM library you are running. Similarly, the View is the entire response / template rendering subsystem. The part that is addressed in the framework is mostly the "controller" subsystem, which is a way of organizing code so that the actual "controllers" can do the primary work of sanitizing input, delegating function calls and returning the output to the View system.
Again, MVC is just a pattern that doesn't fit perfectly in the web request/response cycle, which then necessitates a pattern to handle the leakage (in my case I'm talking about the service/manager pattern). However, I just don't see your suggestions that MVC is "dead", or how this system is radically different.
This thing you're calling MOVE, how is it different from Qt's MVC + signals and slots [1]? You've discovered a new (for you) way of applying MVC and you've gone ahead and given it a new name. Nothing in your blog post is new, except the name of course.
If I sound snarky, it's because I'm sick and tired of similar opinionated proclamations in too many self-important blog posts.
Edit: Re the down votes. If you're going to write posts with titles like "MVC is dead" with no justification whatsoever, then proceed to self-post on HackerNews, then I feel justified calling you out on it. Again, I would appreciate someone informing on how MOVE is fundamentally different from MVC.
Suppose I have an MVC web app. Suppose I add some database triggers so that when some data is entered other things happen. Maybe I flag an invoice to be printed and the trigger notifies a waiting program which processes the invoice data and sends it to the printer.
Now, from the perspective of any single request, the application is MVC-centric. However, from the perspective of the application structure as a whole it's not, because model operations trigger other operations which can have other effects beyond the immediate knowledge of the model.
Is that kind of what you are talking about? MVC with a sort of events backplane?
The controller in MVC does have a bit of a dual nature, firstly it acts as glue code between models and views, allowing the two to be effectively de-coupled. The second task is a little more complex - views take user input eg mouse-clicks and key presses, and translates it into semantic events "OK button clicked", "Open File selected", which are then acted on by the controller.
Your post explicitly identifies these two roles and formally seperates them. This is perhaps not a bad thing, but I don't know that it justifies the title. Something like "The two faces of an MVC controller" might have been a better description...
This looks like MVC to me as well, except what MOVE is calling operations I would call commands. There are quite a few MVC frameworks that work like this, including PureMVC which has been implemented in almost every OOP language http://puremvc.org/.
Does anyone else not really get "MVC"? It seems like every person has their own idea of what it is and no two frameworks can agree on what the necessary parts are. I get the feeling MVC is mostly a bunch of handwaving about separation of concerns, motherhood, and apple pie.
I wouldn't like it to be a religion! I'd just like some precision. Design patterns point to a large region of possible configurations, so to say something is "MVC" isn't saying very much.
The original MVC architecture was for GUI interfaces in Smalltalk. It was so helpful a design pattern it was borrowed for use in request/response web application, where naturally the use of each part was very different.
If you really want to "get" the original MVC, see the classic book "Smalltalk, Objects, and Design" [1] which explains MVC and other OO architectures as well as the principles behind them, which might guide you to picking an appropriate structure for applications that don't fit the GUI/MVC paradigm.
My original implementation of Mvc was writing a game of connect 4 in java. There was a board model. There were two views. One graphical, and one command line. You could update both views by clicking your next move on the graphical board, or putting input on the command line. Once the model was updated, the controller would update any view that was listening on it.
The controller shouldn't be updating the views. The views should be observers of the models. The controller updates the model, which triggers messages from the models to their observers, the views. They would then would then reflect the change in the model.
Me. I really struggled with it early on when I was moving from single file php to frameworks, so I read head first design patterns. There MVC made sense; you had state to maintain, and changes to make; MVC still holds up well in desktop GUI applications. But on the web you throw away the world on every request, so essentially you're just running a big API where every request gets interpreted by the controller, acted on by the model and rerendered by the view; basic separation of concerns. All of these "model pushes changes to the view, controller accepts actions" stuff from the original MVC seems like it's really poorly mapped to the web. I still don't know if it just hasn't clicked yet or I'm doing it all wrong or something, but I really wish I could have a bit more certainty when I'm architecting new projects that I'm doing MVC "right".
I sort of evolved my own PHP framework pattern after I did my first few webdev jobs and identified the problem areas. This was before I had ever used a MVC framework.
Looking back at it now, it had everything your typical web MVC framework has, just slightly diffrent:
* Models, with cleanly encapsulated functionality, but without an ORM. I only built small websites, so all related database tables were managed by the same model.
* Controllers that handled all input and delegate it to models.
* Views in the form of HTML code following the controller code in the same file, but strictly separated.
* "Forms" that abstracted away the controller/view and input validation of forms in a neat, reusable package.
My point is that whatever you come up with that actually works well and lets you be productive will more-or-less resemble MVC.
MVC is not dead. It has its warts, but there still is a strong developer community who build applications using MVC - through MVC based frameworks, and also by handrolling implementations that are an approximation of MVC. As long as there are enough people using it, MVC can't be pronounced 'dead'.
As to MOVE, the issue that the author points as the problem with Controllers in MVC is that'controllers are nice self-contained bits of.. what?'. At some point people will start asking these questions about 'Operations' and 'Events'. What would you classify as an 'event' vs an 'operation'. Some mature Rails projects that I've seen already uses this paradigm - there is an internal synchronous pub/sub event listener to which messages can be pushed by both the controller and the model. Even then, there is always a question of where to put what. Some answers are very clear - like an audit log which is only a side effect. But it is not the case always.
The author is trying to solve this 'classification' problem by giving us a more granular model. This can help to a certain degree - but there will be some point where even this wont help us. At that point we can choose go to a finer granularity, or ask the question whether all this extra organization is worth the hassle?
Abstractions are not without a cost. Some abstractions are too essential for any project. Some abstractions are nice to have. But all of them have a cost. In the case of MVC, the cost of the extra organization is paid many times over by the increased maintainability of the application. But given the number of components the MOVE paradigm advocates, I'm doubtful whether the added organization will be worth the cost.
I agree with what DHH said on a recent podcast - it is easy to talk about concepts in abstract and they can look really good. But what changes the game is a real implementation and being able to contrast the code 'before' the change and 'after' the change. This is not feasible all the time - some things have to go through the ideation and a slow testing phase. But at the least, I'm looking forward to see a non-trivial application that uses this paradigm. I'm ready to try imagining how it would have looked in MVC and decide whether the extra organization is worth it.
I don't know. This is essentially saying that the way to solve problems is to add additional layers of abstraction. If you want to see a bunch of examples of why that's a bad idea, take a look at any J2EE application.
If we were really understood the problem we'd have come up with a way to make things simpler, not more complicated.
I think the real problem is that MVC is understood by different people to mean different things but they think they're talking about the SAME thing. Back end developers tend to think of the view layer as a trivial thing ("It's just HTML and Javascript! How hard can that be?") and front end developers tend to think of the model layer as trivial. ("Look, my backbone.js code is handing out and consuming JSON, how hard can it be to persist that?")
When I read suggested code where each class has one "process" or "run" method, I think that someone who lives in an object-oriented world has reinvented functional programming.
Very spot on explanation of what is circulating in my head for months now. This seems to relate to the Data-Context-Interaction movement and what Bob Martin calls Entity-Boundary-Interactor pattern in his latest talks.
I usually get around the cited issues through dependency injection into the model. That is, instead of placing large amounts of logic in the controller, I let the model hold the logic.
In a naive implementation, this may couple the model to things it shouldn't be coupled to. So, to avoid the model coupling to infrastructure resources (say, storage), I let the controller inject those objects into the model, as needed.
But, I realize that that's an architect-y, OO kind of way to do it that requires some background knowledge which can may obfuscate the code. So, I'm all about making things easier for everyone.
As others have mentioned, it'd be useful to have a more sophisticated example.
Addy Osmani has a nice excercition [1] on the history of MVC in Developing Backbone.js Applications, where he states:
"Developers are sometimes surprised when they learn that the Observer pattern (nowadays commonly implemented as a Publish/Subscribe system) was included as a part of MVC's architecture decades ago. In Smalltalk-80's MVC, the View and Controller both observe the Model: anytime the Model changes, the Views react."
232 comments
[ 2.7 ms ] story [ 249 ms ] threadI do however think there's still great benefits to MVC, if you're shovelling code into controllers and can't make it work like it should then MVC is not the right design pattern for the project. Like every other pattern it'll only work when it works, but MOVE sounds like an interesting addition that I might have a play with.
(The original MVC is actually useless for web apps because there is no client-server connection in it, and that profoundly changes everything. There's no point in trying to bash a GUI top-level design into a new client-server world, especially when DRY is just sitting there, waiting for you to use it.)
MVC, MOVE, all the variants just obscure your vision from the underlying and far more important principle.
The big epiphany for me was when I realized that the server has its own MVC, and the browser has its own MVC. The server's output is the View for the server and the Model for the browser. For a complex set of objects in a given Model, the final output of those objects is their View, and the consumer of that output uses it as a Model. In theory, any View can be a Model for the thing accepting the View, so in a complex system, you have a chain of MVCs.
And one can further imagine that applets written in JavaScript have their own MVC unit.
I work on complicated, large-data web apps sometimes daily. MVC has been a fine model for them and has kept my group's organization clean and modular.
People complaining about factual inaccuracies on Wikipedia annoy me. It's Wikipedia. The entire point and purpose of it is to fix what you know is wrong.
For once, I'd like to see, "I just touched up the Wikipedia article on this subject to explain it a bit more accurately."
"But then all my changes were reverted by an overprotective editor; I brought the issues up on the talk page, but my comments were brusquely dismissed."
If you don't make any changes, he has nothing to work with except some random whining.
(And yes, that's how it works in the real world, too.)
(In my experience most Wikipedia edits are gratefully received, assuming you provide references for your claims. Kind of like HN, really)
This presupposes
1) I care about fixing it. 2) I have the knowledge to fix it (spotting and removing an inaccuracy is easy, knowing the correct and full set of facts to substitute it with not so much) 3) I can write well enough 4) The Wikipedia process is not convoluted and broken for casual contributors.
"Touching up the Wikipedia article" has little value in cases like this. Usually the only remedy at that point is to delete the entire thing and start again, which somebody finally did not long ago.
While I'd still advocate DRY over this POV (unless of course DRY leads you here naturally), I will agree this is a generally valid viewpoint, because you've got the server-client model built in there instead of glossed over. And you are now the first person who has gotten me to be generally agreeable about MVC used in the web world.
Which raises the interesting question of building a framework that builds this idea into the core, with server-side MVC, client-side MVC, and some sort of defined crossover instead of the usual hacky stuff that emerges from single-MVC.
I use Angularjs in the browser, now.js for the interface, and, at the moment, custom code on the server that follows the MVC pattern.
The server is lightweight: its role is to
That's it.http://angularjs.org/
http://nowjs.com/
The lexical/nested scoping in the templates is just perfect. I've reviewed the documentation of all competing frameworks, and I couldn't figure how to do it in any of them. Since it was a primary requirement for my app, I went for Angular.
The service-based architecture, and the automatic service injection in controllers, based on parameter names are pretty nice too, as is the fact that you can pass arbitrary parameters to filters.
In a calendar widget that displays a month, I pad the `month` array with days of the surrounding months in order to get complete weeks. I wanted to have these days styled differently. `dayName` and `idem` are custom filters.
In CSS: Bam: calendar!One thing I found interesting in the blog article was the notion of "smart controls", but I can rationalize that away as another MVC module; after all, the Windows OS itself is handling all the interesting behavior, and the GUI app is borrowing the behavior. Depending on the toolkit that interfaces with the "smart controls", we get access to events (mousedown, keypress, etc) that can serve as input to one of our application's controllers.
Can you expand more on this? I've used MVC for webapps quite a bit, and find it to work well.
You haven't used MVC, you have probably used Model2. The post we're discussing is about MVC.
http://andrzejonsoftware.blogspot.com/2011/09/rails-is-not-m...
Server MVC (Model2) is not the same as client MVC (the classic one). They are totally different architectures. Patterns that apply to one, don't apply to the other.
You can't get MVC with Rails/Django/Struts. You can get a nice MVC with a Single Page Application or with a desktop app.
A similar discussion was already here: http://news.ycombinator.com/item?id=3035549
Patterns are great, but slavishly following them, and not understanding that there's often multiple patterns for different circumstances can lead to coding dragons.
Honestly I'm sick of reading all those "x is dead"-alike articles. Hey, if you believe the web PHP is dead, Java is dead, C is dead.. etc... Technologies, patterns, languages or structures don't die, in fact, if you really fancy you could write your application using C code and compiling it into asm, why not? If it works, perfect! There are enough examples out there where old technologie works. And I think people tend to be spending too much time thinking why something is imperfect, or how to do it better, instead of actually making stuff that rocks.
If you really do have the need to improve something, prove it! Make a useable example, write a framework, library or new language if you really need to.
I was with you until this. I think it's actually important to think about where flaws are and how improvements could be made.
The literary critic Howard Bloom actually argues that many of the best creative works are agonistic: they take a previous masterpiece and say, "I could do better," and from that claim do. The produced work ends up being a response, saying, "That was good, but here's your mistake, here's how it can be done better, and look how well it turns out."
I write my code initially as one monolithic controller, and then refactor my code into an MVC pattern. It doesn't take that long to move functions from one object an other, and now you're working with an already-functioning piece of code rather than guessing how things might work later on.
I don't think so, but I feel that Grails may be the closest thing currently. It has a concept of a Service construct that feels like an Operation. Then again I could be completely wrong.
http://www.martinfowler.com/eaaDev/uiArchs.html MVP via M. Fowler seems a little closer to what client side should feel like (imho).
http://en.wikipedia.org/wiki/Model_View_ViewModel MVVM also makes sense for a client side app, which is just an extension of MVP.
IMO MVC on the client side is just a carry over from people who were experienced in writing web apps who wanted something that felt familiar on the client side. It's a leaky abstraction at best.
I'm not sure what the right answer is, but I certainly feel like the race for rich client-side apps had too many frameworks settle on MVC without thinking about the bigger picture.
The problem with messy code or where it lives will not go away because you think about it differently, you just have to either hire better people or spend more time and money refactoring.
Whereas controllers have a pretty undefined lifetime, operations are finished when they're done. This means that operations can use each other to get work done, a pattern you don't see with controllers.
Out of the three terminologies (state, representation, flow), the third one is arguably the most tangled. I find it healthy to refactor it into reusable chunks (operations) and event-driven flow management.
The problem was, in my opinion, that operations should have not been put into controller units. It attracted more copy-paste solutions in my experience.
The original MVC designs and sample code all had views and controllers observing models through an Observer based event pattern.
The operations were the controller units. The events were not.
http://emberjs.com/images/ember_mvc/embermvc.png
Operations are similar to controllers for sure. But where's routing or state? We don't have a full picture here.
After trying out that new meta-pattern, things get overly coupled, too many bi-directional relationships between state, views, models, and controllers/operations.
I'm going to have to agree with the parent here. Without example code to compare, how is this different than MVC? (or "MVCE")
app.trigger 'boom'
Somehow, I'm just seeing the Observer pattern and the MVC pattern in the OPs post.
Do you haz teh codez?
The idea in practice gives a much better idea of what the pros and cons are.
Services is where the logic of your application should live, and services should be HTTP (or any protocol) agnostic. They should only speak in models and native types, and should abstract all of your logic away from your controllers and models.
This leaves the controllers as a thin http handling layer that parses inputs and then lets the service handle the work.
The response from the service is then transformed appropriately (JSON, HTML, etc) and sent back to the caller.
Just my $0.02
If your controllers are getting fat and spaghetti like, I wouldn't blame MVC. There are many patterns one can use that are compatible with MVC without going to a completely different architecture. For instance, if you need to encapsulate multi-model interaction you can create a presenter abstraction that the controller simply calls into. Just because there is a bunch of code that ends up in the controller because "you don't know where to put it" doesn't mean there isn't a better place to put it without re-designing the entire application.
Another thing is while I love the data-binding event deal, this really only works for client-side frameworks like Backbone. Server-side kinda goes at the window, but I suppose you could add a framework that piped event signals in the response from changes that occurred in the ORM layer (although this further couples components).
I'm not convinced that separating the data from the methods that operate is a great idea unless you want to go purely functional. Doing this clearly breaks encapsulation, throws any notion of OOP out the window, and still binds the "operations" too closely to the data. Generally speaking, the data is useless without the operations and vice versa.
So the real difference between MOVE and MVC, at least according to this article, is that models are no longer useful on their own, the controllers aka "operations" know everything about how to manipulate models (it shouldn't), and models generate events which are only consumed by views, which makes no sense if you wanted to use the model on its own (but you can't without your operations).
Generally speaking, the model should MODEL something. That includes data and behavior. Without both, you have a database, and a set of operations kinda like a C library but only because OOP hadn't been invented yet.
In my mind this further couples all of the components because it actually increases the reliance on each other for them to be useful.
MVC isn't dead. There is a good chance you are using it wrong. I highly suggest Rails Antipatterns. While it is specific to Rails, it works for MVC in general. http://www.amazon.com/Rails-AntiPatterns-Refactoring-Addison...
edit: spelling
Binding data and behavior together breaks the rule of single responsibility, which I believe is far worse than designing separate roles in sepearate components that work together. Models should model the data structure only, if you need a presentation abstraction anyway for multi-model operations. Why not go the extra mile and use this abstraction level for all operations?
It is a false dichotomy that you go either full-OOP or purely functionaly. Models wrap knowledge as the article suggests, That means that, in addition to getters and setters, they might contain functions that let you check "is this the user's password?". I envision these methods to work on a single attribute, whereas multi-attribute and multi-model business logic belongs to operations.
MVC isn't dead, but it was a local maximum OOP gave us. Event-driven development seems to raise and work well with objects and datasets.
Are you suggesting that OOP breaks the rule of single responsibility? Any 'operation' that modifies the internal data should belong on the model. Would turnLeft() belong on a Car model? Or do you pass a Car into a turnLeft operation? In my mind a turnLeft operation shouldn't know the details of how to turn a car left, or a bike left, or a boat left. These operations belong in the Car, Bike, and Boat.
Obviously, I don't say "turn your handlebars such that the left side is closer to your chest," or "rotate your steering wheel counter-clockwise," when I mean to tell someone to turn left at the next intersection. I might, however, tell a sailor to steer to port at the next buoy. =)
EDIT: forgot to say, fwiw, that I agree that such actions do not belong in the model. The things go in the model, and the only actions the model should support are those relative managing the data in the model, not interacting with the data... That is, after all, what the controller is for.
I see thing which is called a Car, an instance of which is stored in the Model, which may contain other things, including other types of Transports. The user interacts with the View, instructing a left turn - the controller grabs the Car (why it grabs the Car, and not the Bike is undefined =), and tells it to turn left. None of the M, V, or C understand what a left turn is - but the controller knows that the Car can perform such a thing if instructed. The Controller knows it can tell the Car to turn, because the Car is descended from a Transport, and all Transports have a virtual method for turning.
That last sentence was in my head and unfortunately took over my comment.
I think any logic inherently tied to the data should be in the model. The controller shouldn't have to worry about internals of the model any more than necessary.
Here's an example. Suppose I create an i18n framework for handling numbers. I certainly am going to include in it a function for converting the number into the current user's localized format, and another one for converting the number from the current user's localized format. I will probably also have functions to convert to/from db formats and to/from arbitrary formats. Not all of these will be called by the controller (in most cases, just the ones to/from the user's localized format and maybe an arbitrary format on rare occasions).
This way the controller script can just call something like $number->to_output; and get the localized string back. Other model objects can call $number->to_db and get a string suitable for entry into the db.
Interestingly in LedgerSMB 1.4 where we have done this, the number of cases where the model calls number i18n functions are remarkably small. These are usually called in the model or in the view simply because the controller probably shouldn't have to worry about this, and the view gets to worry about display logic.
However, instructing a contained object to take some action at the user's request that is unrelated to display or management of contained objects is neither the responsibility of the view or the model, but specifically the task of the controller.
I want an email to be sent to me when the quantity on hand of a part gets below the re-order point.
So now, I build a program that listens for notifications, and when it gets one, loads the data, erases the queue, and sends me an email.
I build this so the app itself doesn't know this is required or is going on. Database triggers, queue tables listening scripts, and templates all are triggered when the db write takes place.
Now, what we have here are arguably two MVC environments where the model behavior of one triggers a model change in another, which triggers a controller to run, calls some other model stuff, creates an email (via a view) and sends it.
But this is the sort of action you are talking about, right? You think this violates separation of concerns?
I'm speaking to the point that if you are separating Model, View, and Controller, and you have complex objects in your model that can do many things, it would not make sense to put all of the logic about what those things can do, how to do them, and when to do them in the model. Otherwise, you're simply blending the model and the controller (which may not be a wrong thing to do) - so you just have MV.
Let me give a more concrete example: I have a model which represents a network of connected complex "devices," there are five types of devices, each that can do 50 distinct things. The model can add a new device, delete a device, or retrieve an existing device. It can also ask the devices what their names, and addresses are, and what features they support, on behalf of any view which needs that information.
It cannot, however, tell device 1, which is of type X to take action "foo". That, instead, is implemented by a controller attached to a view that shows a big button that says "Do Foo", and a drop-down with the list of available devices that can do Foo. The view passes the press of the button onto the controller, which asks the model for the selected device, and then executes a "do Foo" command on it, and then, perhaps, contacts the device again to check that "Foo" was completed.
If all such logic were built into the model, I'd have several hundred methods in it, and I'd be very quickly looking for somewhere to move all of this logic, like, you know, controllers.
My point though is in essentially shimming functionality. In my example, for example, here is how it would work.
1) User requests "save this invoice", which activates a controller script which automates the model elements for "invoice" instantiates an invoice (since this is a stateless web app) and saves it.
2) The model saves the invoice by writing it to the db.
3) Saving to the db fires a trigger which checks ROP vs on-hand and where ROP is greater saves a record in a queue table and issues an asynchronous notification, which doesn't have any immediate effect.
4) Controller commits the db transaction. The DB sends out the notification and makes the rows in the queue table visible.
5) Controller for application b wakes up (let's say every 15 min) and polls for notifications. Ok, we got one. Look up the queue table, prepare the email (model stuff) runt he template (view stuff) and sent it out (model stuff again).
So what I am getting at here is a way to have model events have side effects which are outside the scope of Application A, but are at least triggered by model operations. This is not an anti-pattern really because application A is not relying on those side-effects for operation. However if you look at application A as the primary one and application B as contained within it, then application B can only be described as contained within the model of application A, from application A's perspective, because all of its functionality is abstracted behind the model. From application B's perspective, there is a model, a view, and a controller, and it doesn't care as to where notifications and queue table data is coming from. From it's perspective it is a loosely coupled app in its own right.
But as always what I am suggesting is that common sense usually determines the best place for a given piece of logic. LedgerSMB is very model-centric but there are cases where we have a fair bit of logic in the controller.* I think that anything which is inherent in the model belongs in the model. So back to the vehicle analogy, a bike object should support a $bike->turn('l') and a $bike->turn('r'). However telling the bike when to turn left is the controller's job.
* for example in contact and employee management, the controller has to coordinate a lot of different model operations, leading to unusually long/complex model code in the system.
> it's the part of the Operation to both decide what to show and also get it in the correct format to show
Did you mean Views, not Operations, here? Or maybe I'm missing something.
The MVC abstraction has an issue with web applications, since the request-response cycle doesn't provide feedback as directly as the hardware-monitor-software cycle that the pattern was originally designed around.
However, if the problem is that you are putting too much "logic" into your controllers, you should probably find a better place for it.
In Java/Spring-MVC, there is a typical class hierarchy of Controller -> Manager/Service -> DAO. The extra level of indirection is a very handy place to put business logic, then each class in the tier has a dedicated function:
This approach doesn't seem to offer anything more than that, except for putting a label on the messaging between subsystems, but those operations are not well defined (at least in this piece), and seem like another nebulous way to bury logic.It seems like this problem has arisen from a rather narrow reading of what an MVC system should be, as in, not having utility libraries because they aren't strictly an M a V or a C.
*edit: formatting.
http://en.wikipedia.org/wiki/Apache_Struts
MVC with "action" (or event, similar semantics).
Speaking of Java/Spring-MVC approach, I tend to have a mix approach of Service and Repository (since DAO seems to be getting a lot of bad-rep, time to pick a new name :D).
Controller -> Service (SOAP) or Resource (REST) [although Resource could simply forward to Service as well)
or
Controller -> Repository (for specific entity that requires no interaction with other entities)
Unfortunately the Service layer is necessary in the situation where there are 2 or more domain models need to interact with each other.
This seems to help writing test-automations by splitting the tests into 2 categories:
1) End-to-End w/ mock repository
2) Integration only at Repository level using in-memory DB (Derby, H2)
By doing this, we were able to speed up the test significantly.
I believe in Rails, you're tied with ActiveRecord and would require real database (be it SQLite3). There may be open source libraries that can intercept AR calls and re-route it to either fake DB or just simply fake 'em all, but not sure how popular/complete they are.
If you want to just fake 'em all, which does not sound particularly ideal, people just generally mock em
for example:
FriendsRepository.java is an interface that can be mocked during unit-test while the integration-test would use the actual implementation.
I know that the Java solution tend to be brittle because it somewhat forces people to have 1 interface, 1 class implementation (the mock implementation would be provided by mocking library).
The main advantage of Operations over controllers is that they're fully composable. You can take the operation that logs a user in (which displays the login screen, and awaits the user typing a username and password) and use it as a sub-part of any other operation.
In a purer MVC world you get something similar to this by making a function that instantiates the login controller with its associated view; that's pretty good, but there's no obvious place to put that function.
I'll certainly be following up with more details, and some actual code.
I understand the motivation, and have come across several situations where I wanted "controllers calling controllers", but ultimately, you're repurposing a piece of the architecture to do something it shouldn't be doing. A controller handles the input into the system, it shouldn't be defining a workflow.
> In a purer MVC world you get something similar to this by making a function that instantiates the login controller with its associated view; that's pretty good, but there's no obvious place to put that function.
That just sounds backwards to me. Are talking about creating dynamic endpoints? That sounds like a much bigger headache than composing stuff in a service layer.
MVC can be a little ambiguous, and with web-frameworks it can be hard to see that each piece is actually a subsystem. The Model isn't just your model class, its the model class, the DB and the ORM library you are running. Similarly, the View is the entire response / template rendering subsystem. The part that is addressed in the framework is mostly the "controller" subsystem, which is a way of organizing code so that the actual "controllers" can do the primary work of sanitizing input, delegating function calls and returning the output to the View system.
Again, MVC is just a pattern that doesn't fit perfectly in the web request/response cycle, which then necessitates a pattern to handle the leakage (in my case I'm talking about the service/manager pattern). However, I just don't see your suggestions that MVC is "dead", or how this system is radically different.
It seems like it is just semantics.
If I sound snarky, it's because I'm sick and tired of similar opinionated proclamations in too many self-important blog posts.
Edit: Re the down votes. If you're going to write posts with titles like "MVC is dead" with no justification whatsoever, then proceed to self-post on HackerNews, then I feel justified calling you out on it. Again, I would appreciate someone informing on how MOVE is fundamentally different from MVC.
1. http://doc.qt.nokia.com/4.7-snapshot/model-view-programming....
Suppose I have an MVC web app. Suppose I add some database triggers so that when some data is entered other things happen. Maybe I flag an invoice to be printed and the trigger notifies a waiting program which processes the invoice data and sends it to the printer.
Now, from the perspective of any single request, the application is MVC-centric. However, from the perspective of the application structure as a whole it's not, because model operations trigger other operations which can have other effects beyond the immediate knowledge of the model.
Is that kind of what you are talking about? MVC with a sort of events backplane?
Your post explicitly identifies these two roles and formally seperates them. This is perhaps not a bad thing, but I don't know that it justifies the title. Something like "The two faces of an MVC controller" might have been a better description...
And Events are handled with a combination of Key-Value Observing and UI binding. http://developer.apple.com/library/mac/#documentation/Cocoa/...
Controllers still exist but the design of a program is easier to reason about if everything that mutates data is pulled out of the controller.
UI changes must be made on the main queue, but the above design helps pull out model changes, network requests, etc on to background queues.
http://c2.com/cgi/wiki?ModelViewController
If you really want to "get" the original MVC, see the classic book "Smalltalk, Objects, and Design" [1] which explains MVC and other OO architectures as well as the principles behind them, which might guide you to picking an appropriate structure for applications that don't fit the GUI/MVC paradigm.
[1] http://www.amazon.com/Smalltalk-Objects-Design-Chamond-Liu/d...
Looking back at it now, it had everything your typical web MVC framework has, just slightly diffrent:
* Models, with cleanly encapsulated functionality, but without an ORM. I only built small websites, so all related database tables were managed by the same model.
* Controllers that handled all input and delegate it to models.
* Views in the form of HTML code following the controller code in the same file, but strictly separated.
* "Forms" that abstracted away the controller/view and input validation of forms in a neat, reusable package.
My point is that whatever you come up with that actually works well and lets you be productive will more-or-less resemble MVC.
[CQRS]: http://martinfowler.com/bliki/CQRS.html
As to MOVE, the issue that the author points as the problem with Controllers in MVC is that'controllers are nice self-contained bits of.. what?'. At some point people will start asking these questions about 'Operations' and 'Events'. What would you classify as an 'event' vs an 'operation'. Some mature Rails projects that I've seen already uses this paradigm - there is an internal synchronous pub/sub event listener to which messages can be pushed by both the controller and the model. Even then, there is always a question of where to put what. Some answers are very clear - like an audit log which is only a side effect. But it is not the case always.
The author is trying to solve this 'classification' problem by giving us a more granular model. This can help to a certain degree - but there will be some point where even this wont help us. At that point we can choose go to a finer granularity, or ask the question whether all this extra organization is worth the hassle?
Abstractions are not without a cost. Some abstractions are too essential for any project. Some abstractions are nice to have. But all of them have a cost. In the case of MVC, the cost of the extra organization is paid many times over by the increased maintainability of the application. But given the number of components the MOVE paradigm advocates, I'm doubtful whether the added organization will be worth the cost.
I agree with what DHH said on a recent podcast - it is easy to talk about concepts in abstract and they can look really good. But what changes the game is a real implementation and being able to contrast the code 'before' the change and 'after' the change. This is not feasible all the time - some things have to go through the ideation and a slow testing phase. But at the least, I'm looking forward to see a non-trivial application that uses this paradigm. I'm ready to try imagining how it would have looked in MVC and decide whether the extra organization is worth it.
RAPHT (https://github.com/DanielWaterworth/Raphters/blob/master/RAP...) attempts to something similar (adding more layers of abstraction to MVC) but I have the same problem with that.
If we were really understood the problem we'd have come up with a way to make things simpler, not more complicated.
I think the real problem is that MVC is understood by different people to mean different things but they think they're talking about the SAME thing. Back end developers tend to think of the view layer as a trivial thing ("It's just HTML and Javascript! How hard can that be?") and front end developers tend to think of the model layer as trivial. ("Look, my backbone.js code is handing out and consuming JSON, how hard can it be to persist that?")
I usually get around the cited issues through dependency injection into the model. That is, instead of placing large amounts of logic in the controller, I let the model hold the logic.
In a naive implementation, this may couple the model to things it shouldn't be coupled to. So, to avoid the model coupling to infrastructure resources (say, storage), I let the controller inject those objects into the model, as needed.
But, I realize that that's an architect-y, OO kind of way to do it that requires some background knowledge which can may obfuscate the code. So, I'm all about making things easier for everyone.
As others have mentioned, it'd be useful to have a more sophisticated example.
"Developers are sometimes surprised when they learn that the Observer pattern (nowadays commonly implemented as a Publish/Subscribe system) was included as a part of MVC's architecture decades ago. In Smalltalk-80's MVC, the View and Controller both observe the Model: anytime the Model changes, the Views react."
So, not really new actually.
[1]: http://addyosmani.github.com/backbone-fundamentals/#mvc