MVC is dead, it's time to MOVE on (2012)
cirw.in
cirw.in
Whenever I am tempted to use an event, I ask myself if there a way to solve this problem with delegation or data-binding or some other solution.
I fall into the event trap all the time, but when I come across an event-free solution like Angular/Ember or using delegates in Obj-C, I am immediately sold.
Any pattern that promotes events as first class ways to communicate are a recipe for hell. Every Backbone application I have seen is nothing but a messy event hub that mangles arbitrary DOM events with arbitrary Model events, and there is a metric shit ton of code that just re-invents data-binding and delegation.
Add to that its all JS, and you're hosed. Good luck maintaining your selinium tests.
The jQuery route is also interesting, as it registers events as actual methods. So trying to call an event that doesn't exist will, again, throw an exception.
If C++/Java called events messages then it would reveal exactly how broken this vtable crap is as a replacement for actual 'messaging'.
Most of the GoF book is a giant anti-pattern for using a broken languages.
Software design patterns (at least, on the level where you would bother to write books describing them in terms of source code templates, rather than library code) are language-specific (or language-family-specific) workarounds for things that the language doesn't abstract well.
OTOH, recognizing them in existing languages is both how you write better code with the language you have and start to develop/recognize better languages.
Design Patterns books tend to miss the practice with contrived examples. Real code focuses on problems people actually have.
Also, use other languages.
For instance abusing categories is something I learned from rails, when I learned of objc_setAssociatedObject I started adding properties via categories (which you aren't supposed to be able to do via a category).
[1] http://www.amazon.com/A-Mentoring-Course-on-Smalltalk/dp/B00...
Edit: better link
Are you aware that the book also has quite a few Smalltalk examples?
Lots of times people learn these lessons the hard way so I can learn them the easy way. For example, some people(s) noticed all the ways you can shoot yourself in the foot with pointer arithmetic and noticed that all these bugs aren't even directly related to the problems you're trying to solve. I, for one, am glad I develop in a high level language that abstracts pointers away from me. I learned assembly language, C and C++, but I don't miss it.
This isn't a dichotomy. Sure, good judgement and discipline are great, but abstractions that prevent bugs are great, too.
> Most high-level languages can be abused and transformed into abomination. No amount of syntactic sugar and type checking will serve you better than a handful of good judgement and a pinch of discipline, especially while you are architecting the core of your application in assembly.
--
MVVM: model change listeners on each state mutation: response to state mutation is immediate, never batch multiple listeners, requires dependency tracking (if the collection changed, then the count also changed). change listeners fire immediately and can trigger more change listeners. Lots of callbacks to keep track of and easy for things to get out of whack. (Backbone, Knockout, Knockback)
Angular ("MV-whatever"): state changes detected by dirty checking, but changes are immediate (digest loop), never needs dependency tracking. Digest loop runs until the state settles (no more change listeners fire) to ensure consistent views. Magic data binding.
Facebook React: state w/ dirty checking: state changes are always batched, views are a pure function, reconciliation step to merge desired view with existing view, no events or change listeners. Render process is a lot like a 3D game - draw the buffer, whack the buffer, loop. No magic. Facebook doesn't call it MVC but in my eyes it is.
--
The more complex your view and state, the more events/mutations/callbacks, the more you need React.
> Mouse and key events are essential complexity.
I disagree, but probably not with what you mean here. Mouse and Key events are the first thing I want to abstract away, and are an example of the pitfalls of events. The majority of internet connected devices have neither a mouse nor keyboard. I don't want to care about key events or mouse movements, but rather user intent. "submit" and "change" describe user intent; I don't give a shit about clicks and keydowns, or blitting glyphs into an input box or moving the cursor on command-a. What does keydown mean when a Chinese person is swiping chinese characters?
I think of events as chemotherapy. It is one hell of a powerful tool, but should be avoided for most problems. If every problem looks like cancer, then your worldview is missing simpler and less powerful but better tools.
Components in React take a set of properties and implement a render function that transforms those properties into a view (usually by rendering other high-level React components rather outputting plain old HTML). Instead of manually maintaining view state you just render from scratch each time; hence the description of pure functions in parent comment.
Usually this would be a terrible idea because it would kill browser performance and lead to extra complexity in registering/unregistering event handlers, etc. but React implements a framework that ensures the minimum number of DOM interactions happen.
That's the DOM mutation side of it, anyway. I'm don't think I understand how the dirty check/batched event thing works for information going the other direction (user changed the value of a dropdown), and I'll abstain from guessing.
Personally, I don't mind events so much, so react's probably not the framework for me.
A better approach I think would to use FRP (functional reactive programming) on streams of events which eventually sends messages to an agent (one for each category of concern). This enforces a clean separation and allows for simple inspection and testing.
It also has the added benefit of allowing you to scale easily by putting the different agents on different machines, or even sending messages to one of several identical agents randomly.
The back story to that is that you need to put some effort into design. I've been using an event-based design as the basis for all native apps I've built since 2004, and it's evolved into something that's predictable and obvious - primarily because of separation of concerns.
For a simple example, here's a short description of the client I use for my blog: https://www.wittenburg.co.uk/Diagram.aspx?id=5919c0a5-dcb5-4...
The blog post describing the diagram is here: https://www.wittenburg.co.uk/Entry.aspx?id=5919c0a5-dcb5-4e5...
In this approach the model (I call them application entities) is the only part of the system that can raise application-wide events. These are limited to things that happen to the model, eg. Login; per collection, things like Selected, Added, Removed; and per entity, things like Saved, and Deleted.
The UI raises events (keyboard/mouse/etc), but their scope is limited to the UI. There's a service agent that abstracts asynchronous calls to a service, and it raises an event once an async call completes, but that is only visible to application components (Operations, in the linked post).
My specific implementation of this design is based on the architecture of Microsoft Office apps (the idea started formulating after working with Word's document object model).
It's clean and like I mentioned above, predictable.
Controller -> Application Objects -> Model -> View -> Controller
That way, the 'web page' controller can be replaced by a 'web service' controller or a 'command line' controller and the application logic remains untouched.
Spaghetti controllers are a result of not separating concerns.
I also agree with your event compromise. There are always going to be events that need to be broadcast systemwide (logout), but they should be limited.
I've been toying with using a message queue instead of events, it may work, it may not...
But isn't Angular full of magic?
MacOS apps, for instance, are built largely around Objective C, which borrows concepts from SmallTalk. They have delegates and other "we'll call you" concepts. Compare that with Windows apps in the past, where you had to write your own event loop and explicitly listen for events.
On the web, a library like Angular.js encourages you to put your code in one place and it "takes care of the rest". The "inversion of control" is once again very central to the whole thing. And in both cases, it makes for great declarative UI building (UI builder on the Mac, HTML on the web).
In short, if you have a framework, chances are it exposes BOTH kinds of things -- you call it to create / manipulate some objects, but it also calls YOUR code on important events.
If you don't care about mousedown/up events vs touchstart/end events - fine. All that can be abstracted into other events. But you need to respond to events -- whether user input or things coming in.
In our framework, Q, we actually strongly encourage the developer to update their views on events instead of "ajax success" callbacks. That's because Q is built to power SOCIAL apps, and when you're collaborating on a document, you can't predict when a new message will be pushed via a socket ... it may come from someone else posting it to the collaborative document!
So you can't just "avoid" events -- they have their place, especially in multi-user real time environments.
Not untestable or arbitrary, or necessarily a problem. First, almost all processes have some structure that is not random and arbitrary. Second, the science and engineering of distributed systems has some results and approaches that help deal with events that are, or appear, arbitrary. For example idempotence, immutability, monotonically increasing functions such as max() that give the same result independent of the timing or order of events. It's not easy necessarily, but in a distributed system, events are what you have under the pile of turtles.
What a timeless reference.
I have to agree though, the AP is over reaching a fair bit with that statement, there are plenty of ways to implement message based systems that don't suffer from a god complex.
"way to solve this problem with delegation or data-binding"
But this is even less testable. Inheritance makes unit testing a total hell. Because you don't care only for your object, but everything that came before it.
And this usually requires heavy mocking and/or some other tricks.
Delegation makes it easier, sure, I'm not so sure about data-binding
That's definitely a downside of an events-driven model, but I sometimes/oftentimes find it difficult and unmaintainable to squeeze in delegate callbacks (in objective-c) in code, where a notification (event) would work great. Sometimes, when I would have to implement a cascading callback of 2 or 3 delegates, I choose notifications for the clearness it gives to the code.
I don't know about Backbone (never tried it, maybe I should), but if the events are clearly contained in each controller, and the observer properly removed when the controller is deallocated, it's not a big problem (here I'm referring to a language like objective-c).
No, that's just with the bastardized version of MVC popularized by Rails et all, which treat the views as little more than templates.
In the original MVC papers from Smalltalk, the views did actually send messages updating the model:
A view is attached to its model (or model part) and gets the data
necessary for the presentation from the model by asking questions.
It may also update the model by sending appropriate messages.
All these questions and messages have to be in the terminology
of the model, the view will therefore have to know the semantics
of the attributes of the model it represents.
http://heim.ifi.uio.no/~trygver/1979/mvc-2/1979-12-MVC.pdfSo I'll step out on a limb and say that it strongly influence(d/s) the design of Rails
Avdi Grimm has a great book about this called Objects on Rails[1] and Bryan Helmkamp from Code Climate has a good introductory blog post on it as well[2].
Rails implementation of MVC is perfectly fine. It's when people lean on MVC for everything without applying "classic" Object-Oriented design. That's when things become a mess.
1 - http://objectsonrails.com/
2 - http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decomp...
#app/models/user/query.rb
class User
module Scopes
#my scopes.
end
endThe only times 'fat' and 'skinny' are mentioned in the title.
"MVC" as a meaningful term has been dead for at least 5 years.
Rails and the other MVC frameworks don't just focus on the client-side, however. They are also deeply involved with the database and everything in between so a pure implementation of MVC is out of their reach. On the Web in the next 5-10 years maybe we will see more frameworks separating the concerns of the Web server/database and the client-side. Once we break those apart you can have a Smalltalk style MVC implementation on the client-side and organize your "back-end" code to your hearts desire or use a back-end specifc framework to guide you there.
There is little need to debate that point. Doing MVC-style architecture on the browser side works just fine. One of my long-term projects is a relatively large web application that uses something very close to the original MVC idea, with a central model that holds all the state and then a few dozen view-controller pairs that handle all the ways of interacting with it. This architecture has served me well for several years now, and the design has proven to be very easy to maintain and adapt to changing requirements. (In practice I add a fourth type of component in the web context, a “store” that is responsible for communicating with the server, and I define a small number of additional relationships to go with it because it doesn’t fit into any of the other three categories. Even then, the store acts somewhat like a view-controller pair for most purposes, and the cases where it doesn’t are mostly things I might do differently with the wisdom of hindsight.)
On the Web in the next 5-10 years maybe we will see more frameworks separating the concerns of the Web server/database and the client-side.
I’m not sure why we need any distinction between them. Ultimately, we’re just writing a distributed application, which happens to run using something like HTTP as a communications protocol in this case. All the usual concepts about maintaining state and actions that have side effects apply, and all the usual arguments about separating such concerns apply. What makes you think we can’t use these ideas already today?
Trygve Reenskaug actually setup a web page to explain how MVC was originally conceived [1]. My main take-away was that models correspond with the user's mental model while using the application: "The essential purpose of MVC is to bridge the gap between the human user's mental model and the digital model that exists in the computer. The ideal MVC solution supports the user illusion of seeing and manipulating the domain information directly." The most important (IMO) implication of this is that your models aren't limited to data that exists in a database, which is a mistake that I see a lot of web developers make.
However, this is the first time I’ve seen any material from those early days that suggested having the view affect the model, as opposed to being a mere observer, passive or otherwise, and having controllers responsible for all changes of state.
It’s also the first time I’ve seen an early source suggest having one controller deal with multiple views, as opposed to possibly having multiple controller-view pairs associated with the same underlying data but with each view having its own associated controller. I’ve seen variations with views and controllers nested and using some form of delegation/bubbling if the presentation is complicated, but that’s not quite the same thing.
The only original papers I’d seen previously, even those that I thought included Reenskaug as an author, already had the characteristic triangle arrangement with one-way traffic from the model to the view and with a 1:1 view:controller relationship, so I was interested to know the origin of the paper that icebraining linked to. Your link answers that question, so thanks for that.
The idea of view directly modifying models comes from fact that in many cases there was class named FooView, that acted both as view and controller (which generally makes sense because the low level GUI logic is same for both). Also models represented not only the actual data but also various parts of GUI state itself (eg. position of scrollbar).
Sure, as an implementation detail that might be how things are done, but that’s different from conceptually having the view responsible for changes of the model’s state, no?
Also models represented not only the actual data but also various parts of GUI state itself (eg. position of scrollbar).
I think everyone who tries MVC probably comes up against the “Where does view metadata go?” question sooner or later. FWIW, I think treating that kind of transient state as part of the model is unwise.
If it’s metadata that applies to one specific view, as with your scrollbar example, it can live on the view. The corresponding controller can then send suitable commands to the view to update it in response to user actions, and the model is completely unaffected.
If it’s metadata that is shared among multiple views, such as which element of a system has a focus/active state or something like a clipboard/kill ring, then I prefer to introduce a completely separate component. Each affected view will observe that metadata component in the same way it observes the model, and therefore each corresponding controller can update that metadata component in response to a user action on its view and all affected views will react. Often, the metadata component may itself also observe the real model, so that for example if an item with focus is deleted from the model it will also cease to be recorded as the current selection in the metadata for any views.
This approach isn’t quite as tidy as pure MVC, but it does maintain clear responsibilities and collaborations between all of the components involved. In particular, it maintains the general design principles of MVC, and it does prevent anything that isn’t really persistent state or related business logic from polluting the model.
[1] https://en.wikipedia.org/wiki/Data,_Context,_and_Interaction
They may as well have named it 123. At least that wouldn't make you guess at what the naming signifies.
For example, the Model of MVC consists of business logic and sometimes what people refer to as... models. The business logic controls how models are modified. The Controller doesn't. The Controller controls very little when the system is correctly architect-ed, especially when you have multiple UIs.
Really, the View is the only one without ambiguity. But even so, I still have to google from time to time to remember who is allowed to know about who and who notifies who of what...
A better name, and this is literally off the top of my head, would be "Business Layer, View and Event Translator".
Edit: Having thought about it more, I decided to change the word Presentation to View in my "better name" suggestion.
That's not far off the original meaning AFAIK. It used to be called MVCU - model-view-controller-user. The "model" is the idea of the data as it exists in the users mind, the view is how the system presents it, and the controller works with what the user "do" with the model through the view.
It gets confused if you don't realize there are two data models: the "data" model - how the data is modelled in the abstract (and confusingly, internally in the program/database) -- that is distinct from the model in MVC. So the original MVC "model" is closer to "domain model" than to "data model".
Now, in the dark 90s, when everyone had forgotten that users existed, something that no-one would realize until "agile" emerged and surprised everyone, these two "models" got mixed up -- and no one was able to understand this MVC thing ;-)
Model is a representation of the data of your domain and behavior imminently related to this data. I.e. what is "user" and what it means to "create a user"? What does it mean to "find most active users"? The name is because it "models" the domain by representing it as an abstract interface.
Controller is a representation of the rules of when and which models are invoked and which actions are performed. I.e. when we would "create a user"? When we would need to "find most active users"? The name is because it "controls" the models, telling them what to do.
View is how the information presented to the end consumer and how the consumer interacts with it. I.e. what it means to actually show "most active users" to the end consumer? The name is because end consumer "views" it.
Of course, this explanation without actual experience of how such systems are designed and behave does not make a newbie magically able to design complex systems flawlessly. No amount of name changing would. But explaining how this approach works doesn't seem that hard to me.
I write plenty of Rails apps that have thin controllers and fat models. Class methods / static methods on models can help encapsulate business logic in any language's MVC frameworks, as well as liberal use of the Tell Don't Ask pattern.
While Rails did use this and make it popular, it's older than that: http://en.wikipedia.org/wiki/Model_2
"I don't understand MVC, this framework I'm using doesn't supply me with a one-size-fits-all architecture for my business logic and I'm incapable of designing my own. So I'll just stuff my spaghetti style code somewhere, and bitch about MVC and/or the framework being insufficient/dead/shit."
It's the ultimate expression of a bad craftsman blaming his tools, and it's endemic in web development.
That said - the Controller is the only place that is left if the code isn't interface or datastorage specific, so naturally it's the first place to get bloated. But that's fine, you just have to take care of that when you can, by abstracting common functionality and/or move it out in a library.
Funny, because too me that seems like the whole point of MVC: To have a one-size-fits-all "architecture" to shoe-horn your business logic into.
But then again I never really understood the point of MVC. It seems like a somewhat nice fit for GUI applications, but that doesn't mean you should use it for everything. The real takeaway is to decouple and abstract to the point that makes sense. Not too much and not too little.
Important word here: 'web'. If you move that word all ror puritanism falls apart. For example imagine multi-protocol MVC. In that sense javascript is really part of view and it can 'pass messages' to model using ajax.
I'm not sure if rails is the first offender here -- php (and asp, jsp etc) makes it so easy to drop a ton of complexity on your lower extremities that it becomes necessary to "ward off" the part that actually does templating from the rest of your code -- which, if it's all old school php -- isn't terribly easy to do -- or at least isn't trivial to make "obvious" in your code.
If you fail to maintain a part of your code as template-php, and mix it up with your logic, your nicely structured application quickly becomes a mess (this is what old php codebases I've looked at looks like -- and has left me a a little resentful against the entire language. Probably more than php deserves).
Without the E in the MOVE we have just MOV.
Let's talk about Operations now. There are several MVC frameworks which use different names for the classes related to controllers (for example Commands). Some implementations let you compose them. They usually live inside controllers _package_. Do the authors of those implementations rename the C into somethings else? No!
There are some cases with different names (think MVP, MVVM) but they have a different form of relationship between the three parts of a pattern. Let's look at the MOVE's diagram. We actually have the original MVC diagram with a strange quirk: the controller (made from Operations) can directly affect the view. Now we have a problem. There are two places in this architecture where the view gets updated: the view can get events from the model and update itself (oh horror! it's active view!) or it can be directly updated by the Operation.
This doesn't solve anything but makes programs built with this architecture harder to reason about and debug.
There are two ways to fix it: 1. remove direct changes on view from controller then we have just MVC 2. stop sending events from model to view and send them to controller then we have MVP
In the end I don't see enough justification for calling it something new and using a special name for this particular pattern. Also this pattern is broken. Talking about the article itself, it's neither academic, nor pragmatic and looks like a blatant attempt at self promotion. It's a bullshit which puts words over meaning and misleads beginning programmers.
Most programming languages already have operations, you don't need to tack them on as objects, objects generally perform one of these operations when passed a message.
'events' are generally known as 'messages' and are again built into the language.
So now we're left with MV, we just need some sort of object that can send/receive messages from views and models. I think I'll call this object a controller.
The OP is also suggesting a hierarchy of 'operations', with sub-operations communicating with the parent operations. I don't think this maps directly onto language features (again, in languages I'm aware of).
I'd be interested to hear which languages you had in mind, and some more detail on how you envisage the mapping to language features.
It sounds like half procedural programming, half partial application.
'Events' sounds alot like [NSArray makeObjectsPerformSelector] / KVO/KVC / Multicast delegate.
Honestly, the more I think about it the more MOVE sounds like functional reactive programming.
For those interested in learning more about Marionette, Amy Palamountain made a fantastic presentation you can check out at her site: http://amy.palamounta.in/2013/04/12/unsuck-your-backbone/
After a lot of research I realized that the true MVC architecture is not something that Rails implement. In MVC the views are updated when models change without the controller in between. Something like YUI App framework is true MVC in that sense, but not Rails.
While your professor was right he's also a moron for being overly pedantic and ripping you apart.
Isn’t this a bit like saying that in the context of mountain rescue (which involves rough and steep terrain) cars have to be adapted to fit? Cars simply aren’t useful in that situation, and while helicopters are great, they aren’t cars any more. Moreover, the innocent belief of a five-year-old that a helicopter is just like a car but with some rotor blades on top does not mean that people with engineering degrees should start calling them cars because the meaning of the word “car” has been diluted.
So, if you want to build stateful apps on top of web and http (which are stateless) -- you'll end up playing with the same concepts as that of MVC -- but you need to adapt.
I agree you probably shouldn't adapt the MVC pattern (it's a pretty high level abstraction) -- but you'll have to paper over http somehow.
So far building fat clients, lately using either javascript, objective-c or java/dalvik -- seems to work better than sticking the state in a cookie and pretending everything is ok.
In other words: MVC is still valid, and the adoptions aren't really to MVC -- they are to the surrounding framework. I'm not quite sure how that fits with the mountain rescue analogy, though.
Wait, does that mean Wicket is a MVC framework after all? I thought frameworks like Rails, Grails and Spring MVC were classic MVC frameworks, while Wicket was View-first (whatever that means), but in Wicket, View and Model update each other directly.
In my Java shop, we used the service pattern. We had our views, our controllers, our models (which were simply meant to hold data), our services, and our data access objects. Services performed the business logic, and data access objects interacted with the database.
This pattern worked extremely well for every application we developed. Entering the RoR world, I quickly found that most developers forget about all the lessons we learned back when we used other languages, and are repeating the quick-and-dirty mistakes we already corrected.
Business logic
Unless your definition of model is the business logic area of your application. Saying that business logic goes in the model, in terms of the general rails sense, is the bad route.
I think there are two areas of confusion on the topic:
1. Web MVC isn't the same as the traditional MVC pattern as seen in apps and described in patterns literature. In the web version all communication between model and view is mediated through the controller layer and there is no direct control between them) - many web developers are only aware of this variant.
2. Rails popularised web MVC and used ActiveRecord which meant that models were essentially table wrappers and this pushed business object logic into the controller.
For me the next step after MVC is PAC - http://en.wikipedia.org/wiki/Presentation%E2%80%93abstractio... (which I think is pretty much the same thing as HMVC). Adding that extra dimension of multiple self-contained triads keeps the controller layer from becoming a single unwieldy mess of spaghetti spread across the whole web layer. (Ironically I suppose it does introduce a concept of events binding them which may bring it full circle to some ideas in the article.)
If, on the other hand, FooBarService has a handler for a MouseEvent - something that should be done in the Controller - and business logic in it too, now you're violating MVC because your Model and Controller aren't separated.
BTW, IMO to name something FooBarService or BazQuxService is a code smell. "Service" carries no significance. Same goes for "Manager" or "Logic" or whatever generic thing you end up using. Any code could be in there. I have to look inside it to see. It also gives you an excuse to make those file huge because anything could be in there. It's a violation of the Single Responsibility Principle.
Hah, yes, I'm a Java programmer.
Yes, that is the definition of the model in MVC.
Controller is just orchestrating the basket dance of the views and the model. Got this user input, fwd to this model, got this result from the model, wake this view.
Put another way, when business rules change, you change your models. When business behavior changes, you change your controllers.
If you add such rules in the controller, you have to split your rules in two places, which is bad.
Ideally, I always thought that business rules should be a kind of "config", or more accurately a set of files written in a mini-domain language, that would be readable by PMs. Then it would be the job of the model to interface this set of rules with the controller.
So no, business rules and logic and whatever do not belong to the controller.
Yes, 100% absolutely, no question.
>That fits into the class of behavior and belongs in a controller.
The controller is just to handle input, it has nothing to do with behavior. This is one of the key misunderstandings that differentiates between MVC and the weird mess rails calls MVC.
It has a very specific meaning: http://en.wikipedia.org/wiki/Model–view–controller
>At the same time, I also don't think such a rule belongs in your model layer.
I'm not talking personal preference, I am talking how MVC works. If your application were MVC, then yes it absolutely would be in the model.
Your actual procedural stuff that's actually deciding what to do to and with the data doesn't go in the database (stored proc fanboys be damned), and likewise doesn't go in the model.
I have done a lot of pondering about GUIs since I began programming. I ended up in mantaining a 12 year old project, with more than 400 individual forms (that's for a single client, we've got 4 more). Damn, I was lucky.
The project really blew my mind! It crushed most of the assumptions which I made while reading articles or developing toy applications.
And here's the thing:
It uses most of the "bad practices", "anti-patterns", or however the internet calls today the "I was bitten once and didn't find the way out" thing, in it's codebase and still is ridiculously maintainable. With very much likelyhood it will survive another 12 years. Partly, because of the contract, but the point still holds. :)
So, my bold advice: just ignore all the naysayers and make up your own mind. Event's are bad? It they solve a problem giving another one or two in exchange, there most probably is another solution fixing those two too. And while the problems never end, at one time you end up with a framework that covers 90% of needs, correctly.
"Yeah, we can't notify the remote client about the update on the model, when it's in a form rollback phase and when it has at least one two-dimensionally time tracked attribute. It isn't possible, because it interferes with the data history stack. We should not have used events at the very beginning at all." Damn, that's a tough problem. Wait, what does your UI do !?
At the project I'm working on it took a lot of work and at least one PhD thesis to get it where it is today. I can't give out all details, but if anyone's interested, there are few open sourced parts. But You will find plenty of good libraries already.
I also made a simple JAVA Swing project on github using some of the gained knowledge. If anyone would find that interesting, just leave a comment.
I hope such good UI articles come up more often in the HN feed. And please, do write as much technical details as possible.
I found working with a barebones MVC framework a bit enlightening. One is Framework One by Sean Corfield. It was originally written in ColdFusion, consisting of a single class (CF calls them "components") with very little magic. (it does do things like implicit views and queue up service/model calls with an event lifecycle, but in general, nothing happens that you don't have direct control over) He's also written a version for Clojure, though it's less mature
https://github.com/framework-one/fw1 https://github.com/framework-one/fw1-clj
http://elm-lang.org/learn/What-is-FRP.elm
It's a nice abstraction when(if) the alternative is to work with the DOM, javascript and browsers -- but the examples would be trivial in a smalltalk-like environment: The various labels would reference the mouse, and on redraw they'd use the current value. So I'm not sure it's so much an alternative to MVC as it is a fix for our broken environment (the browser+dom+i/o as a GUI system).
Mind sharing a bit about Your experiences? Are the initial investments cost high or low? Are there any drawbacks which inhibit any other functionality (what to do to avoid memory leaks)? Is the end-product really mantainable? Does compose easily?
I'm eager to learn :)
* vinyl records are dead, http://www.nytimes.com/2013/06/10/arts/music/vinyl-records-are-making-a-comeback.html?pagewanted=all
* CDs are dead (yes, they are, optical data storage isn't)
* flash is dead (but still, most videos are still streamed via flash and a gaming company i know prototypes all games in flash...)
* SEO is dead
* social media is dead
* java is dead
* progressive enhancement is dead
* print is dead
* native is dead
* desktop is dead
* ...
* ...
* mvc is dead
lets call it "Franz's law of deadliness"In architecture it's not optional to proceed as follows: 1. describe a problem, 2. describe a solution to the problem
They don't do that. This is a classic mistake: describing a solution and looking for a problem to solve. Don't do that!
Furthermore, MVC is used because it's widely applicable to a bunch of problems and contexts - with its pros and cons, clearly. It's actually a very rare thing for a pattern to have such a large sphere of applicability. So, no, you don't throw it away just like that. It doesn't make any sense. Sure, there are other patterns that work better in some very specific context. CQRS is an excellent pattern for building NoSQL databases for example. That doesn't mean it should be applied to any random problem!
Also sometimes I feel engineers spend WAY too much time worrying about architecture of CRUD. I mean, MvC, non-MvC.. who cares? Adopt one and run with it. Then spend the rest of your time about crucial technical problems(ie semantic analysis, machine learning, spam detection, whatever)
This obviously is not convenient in terms of web facing applications. Don't forget that web pages are intrinsically static which means your model has no way of pushing events to your view. Unless we (in 2013) are suddenly advocating that every site now should be using WebSockets (Just as bad as using PostBacks in ASP WebForms... unless you are writing a client-side application)? And lets not forget that each web application endpoint (HTTP_METHOD + URL) is in itself already an intent/operation described here -> GET = Give Me Information. POST = Mutate Information.
In any case, MVC isn't fully dead as it has evolved into MV(C)VM instead. Instead of the View getting the data from the Model, the Controller gives the required information to the View.
Pretty much all iOS projects are MVVM - See UITableView. AngularJS is arguably MVVM: in this case the views are databound to the view model which is held by the controller, which is essentially the "Events" component.
Additional Edit: All MVC Java Swing apps could arguably be classified as MVVM -> all your JComponents are all... MVC! Which really leads me to think that MVVM is really just nested MVCs... perhaps =)
My comment obviously relates to my experience, which is admittedly more webby than application-y.
I thought iOS was inherently MVC though (or at least, that's what they claim)
And also, anything that is "badly done" becomes bad. I'm not really sure why it is hard to understand View Models... your controllers shouldn't define your view models. Your VIEWS determine what information is needed to render itself. Any templating engine that requires you to pass in a model (i.e. Handlebars, Jade etc.) is, in effect, MVVM. This makes your views more concise since it doesn't get access to a whole model when it isn't required. Its dependency is specifically only on the View Model itself.
No, that's not how it is supposed to work. The idea that everything has to pass through a controller for no reason, and that we need a controller per view, is the rails bastardization, not actual MVC.
Trees are also an awful topology when something has a relationship to an element in another branch. The controllers as I'm using them are globally visible and thus don't need to be passed. This would pollute namespaces except that a minimal number of controllers will recreate the topology of the problem space and not in tree-space. The whole application can see "out" of the 2D tree into a graph that connects things with many fewer connections. These few controllers have tons of logic, but it's all program. There's very little related to how widgets display themselves, so this fat code is also very high-calorie, rich or whatever.
Fat controllers make me happy. My program, the part that I think of as the program, exists all in one place and the bits that control how everything looks all belong in the tree. Widgets don't send events to my controllers often. Occasionally it's easier to reason through a problem using the property/data-binding system, but more often the data already exists in the on_press callback of the widget or whatever and there's no need to secondarily send it through more sub/pub plumbing when I can just call a function of my global controller on the data.
I'm busy getting my code cleaned up and contributed. It has really saved me untold time even in it's nascent stages because of the fundamental topology conveniences.
Take Symfony2's architecture, for example. Controllers, Entities, Repositories, Views, Services, Listeners, Events, etc. Each layer has its own distinct purpose that do something very specific by themselves, but when brought together form a very cohesive whole.
But the end result is so very complex and the benefits gained are doubtful at best.
Events are a given. Models can fire/handle events, views can fire/handle events. The behavior/strategy pattern is just a bunch of singleton objects that know how to mediate between the view and the model. Sometimes the behavior pattern handles events (as a strategy), but it doesn't fire events (only the model and view can do that).
The model knows how to generate the behavior. The View contains the behavior and asks the behavior questions with the model.
This separates responsibilities nicely in my opinion.
Why do you need to have Operations when that code could be into the model? The view tells the model: login(username, password); and the model just do that and saves the state in it's model.
So there will be models that contains state and models that contains data...
Why add another layer?
So my controllers are just there to work with the repository/service layers. This is just the next logical step after straight MVC and is already a pretty well established pattern.
My understanding of MVC is the context of web development.
If my controller function isn't less than 20 lines of code I look over it and figure out what code can be placed in a library or a model or a view. The controller function should do very little.
The "MVC-model" of a bank account is an account number with a balance attached: the data model of an account is a series of credit/debit transactions that can be summed up to a current balance.
I wonder how this applies to stateless systems (HTTP) though. It seems like it's really geared toward thick client applications.
You're triggering digest unnecessarily + you most likely have full object comparisons.
One of the thing with AngularJS is your team needs to have stronger CS fundamentals compared to other frameworks.