Events are an anti-pattern in my opinion. They allow the ultimate flexibility, but in essence are worse than global variables. With events, it is very hard to reason about behavior. Objects respond to messages from "god" at arbitrary times in an untestable way.
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.
Model change listeners are the anti-pattern, not events. Mouse and key events are essential complexity.
--
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.
You seem to know what you are talking about, but I just don't understand what you are saying. Can you explain the React thing a bit better?
> 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.
I think the idea is that instead of having a bunch of DOM elements waiting around for individual events that tell them to change state ("your text should now be this"), you get a whole rendered view ("here's what the DOM looks like now"), which is then merged with the current one. That cuts out of a lot of the weird interconnected events that fly around everywhere in MVVM, because the DOM is mostly just an output.
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.
React probably closer to being just the View than MVC or any other paradigm. It doesn't even have any model layer.
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.
For anyone wondering how Chinese/Japanese/Korean input works interms of DOM events check out the W3C's working draft of the IME API [http://www.w3.org/TR/2013/WD-ime-api-20130815/]. Specifically the sequence diagram near the end of the page.
I don't think events themselves are the issue so much as mutability. When you combine them you end up with changes that ripple through the entire program, making everything incredibly difficult to reason about.
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.
Can't comment about FRP, but can tell you that events can ripple through an entire system, but don't have to.
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.
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.
That's similar to how I'm tending towards. Controllers shouldn't contain the actual business logic, that's for the application layer.
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...
Most patterns can be abused and transformed into abomination. No amount of data-binding or delegation 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.
Even if you're right, this isn't really useful because what you're saying is not actionable. I don't have a "use discipline" switch I can just turn on. Learning discipline comes from doing things the wrong way and being reflective about it.
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.
> "Objects respond to messages from "god" at arbitrary times in an untestable way."
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.
> 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.
Perhaps "pure" events are a recipe for spaghetti code, the same way a low-level anything is a recipe for that. But if you have a framework built on top of events, then it's very maintainable.
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.
This is the fault of your implementation, not the pattern. Event types (names) should be enums, not arbitrary strings. This makes it very easy to change the way the code reads if the meaning of the event slightly changes, and equally easy to obfuscate the event key in a production build.
You would need a static js compiler to type check the enum. So that's an extra step. This doesn't happen in Java or C, but browser based event models (the topic of the post) are almost always strings. Most front end shops choose this implementation. You could add that step to your build, sure, but in. Lot of cases the app is already interpreted so there is no "build" per se. Who else has seen this?
You can make them properties on a global object, so that using an invalid event name is at least a runtime error (when you try to bind to an undefined event) rather than being mystified about why the event never triggers.
So code an eventing system that throws exceptions when an event name that isn't registered is used... It's not difficult; it's what I use in all my JavaScript.
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.
Exactly. Obj-C/Smalltalk have events built in because objects can actually receive 'messages'... can't respond to it? Send it somewhere else, rewrite it, etc.
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.
> Most of the GoF book is a giant anti-pattern for using a broken language.
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.
Reading the code of frameworks / projects you like working with. It's especially interesting to look at older versions and see how it has progressed.
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).
Kent Beck’s Smalltalk Best Practice Patterns is a great book. In Smalltalk, but it works rather well for good OO languages, in general. Very easy to read. http://amzn.com/B00BBDLIME?tag=hboon-20
I haven't used it with Objective-C, but you should check out Smalltalk Best Practice Patterns. The two languages are close enough that it should work, Rubyists refer to it all the time.
I'm glad this was the top post. I don't think events are an anti-pattern, but they are way the hell overused. Part of the overuse is using (name something)MQ for everything, not just for centralized persistent async and pubsub in large systems. Part of it is because of functional languages making a comeback in the past several years, which then settled down again after a spike; They don't require being event driven of course, but stateless systems are the gateway drug to overly event-driven. And part of it is JavaScript's fault- if you were in JS in the bad old days of early Ajax, you knows what I mean, and JQuery just made it easier- but promises hide the fact now that so much is async, though I think promises are just as bad if not worse because they hide a lot of nonsense.
nope you still need to register custom events one way or another, especially when using third party plugins or scripts in directives. You cant magically hookup a 3rd party widget in angular , you need to write event callbacks. Angulars has it's own (scripted) event loop on the top of the DOM event loop. this comes with a huge performance cost no ones wants to acknowledge.
> Objects respond to messages from "god" at arbitrary times in an untestable way
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).
"Objects respond to messages from "god" at arbitrary times in an untestable way."
"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
I'm certainly not the first person to notice this, but the problem with MVC as given is that you end up stuffing too much code into your controllers, because you don't know where else to put it.
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.
Rails didn't bastardize MVC, users of Rails bastardized MVC. Over the years we've seen the progressions of fat controllers to skinny controllers and fat models. Now, we're seeing the progression of using models only for responsibilities related to persisting the object. This leads to extracting additional domain logic into Presenters, Value, Service objects, etc.
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.
All programming language terminology gets blurrier the wider the usage of the term becomes. Right now, if you keep your eye out, you can see this is happening to the term "coroutine"; it's currently mutating from it's programming language research meaning [1] to something indistinguishable from "lightweight thread", or indeed possibly even indistinguishable from "thread".
"MVC" as a meaningful term has been dead for at least 5 years.
I imagine the words as analogies to people and their ease of movement. Fat (“bloated”) components are hard to work with and develop, in the same way a fat person has trouble running from point to point. On the other hand, skinny components are easy to work with because there is little to comprehend, the same way that skinny (“lean”) people will run more quickly and easily.
The decomposition of ActiveRecord Object is not bad. I don't like class like UserAuthentication and AbandonedTrialQuery. I would rather have something like.
Everyone has their own preference for implementing object oriented design which will help push things forward. The important part is that people are thinking about object oriented design more than ever before.
Rails started out as a "the database is stupid, it is just storage" and "models are just object wrappers over your stupid database" as defining characteristics. And it has always had this weird notion that everything has to go through controllers. So it certainly did bastardize MVC, and the guy who came up with MVC has even pointed this out (not specifically about rails I don't think, but about the plethora of faux-MVC frameworks that exist now).
Most criticism of MVC and frameworks can be summarized as:
"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.
"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"
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.
I've lost count of how many times I've had to argue that the View binds (loosely put, for View <-> Model interaction) directly to the Model. The Controller only enters the chain if the operation is more complex, i.e. it is a composite operation.
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.
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.
A nice way of putting it. Somewhere along the line of web/http systems views became templates -- while an MVC "view" really is (some) logic+rendering -- not "just" rendering.
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).
php is not a framework. How many people use bare ruby , bare python or bare java to code webpages ? ( and by the way JSP can be a mess too , so it's not about the language,it's about the brain behind the desk ). Rails , Django and others give devs MVC for free , not PHP, not Ruby , not Python.
Actually, a good code smell / architecture smell in a Rails app is if any given controller method is over 10-15 lines (And even that is on the large side IMHO). For example, I believe Code Climate specifically penalizes your score for long methods in controllers.
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.
Interesting link. Do you know the original context? I’d be the first to agree that a lot of back-end web frameworks have wildly distorted the original idea of MVC, and in many cases completely missed the point of why it was useful. However this is the first time I’ve seen anything from the original Smalltalk days that presented the relationships like this, with views affecting models and a controller implicitly being related to multiple views.
The original context was for building interactive GUIs. I think you're right that web frameworks' concept of MVC is different than the original context because of the request/response cycle of HTTP. However, understanding the original ideas of MVC has helped me a ton even when writing backend code for the web.
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.
Sorry, I wasn’t clear. I’m familiar with the original GUI-based work, or at least I thought I was.
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.
In the original (ST and desktop GUI centric) MVC, controller and view were essentially interfaces. View is something that can draw window on screen and controller is something that processes/redistributes events from input devices. On the other hand model is simply something that can be hooked up to that, ie. stores state accessible by views and controllers and notifies views of state changes.
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).
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).
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.
In addition to the original stuff on MVC, the newer stuff on DCI[1](Data, Context and Interaction) is also illuminating wrt one way to progress with software architecture for interactive/event driven applications.
The original MVC was invented in the context of a fat client which were desktop-esque applications back in the day. In the context of the Web and HTTP (which is a stateless protocol) MVC had to be adapted to fit this context which is what Rails and many other frameworks have done. Now with browsers and JavaScript performance being better than ever, preserving state seems possible so a more "original" MVC implementation can (possibly, everyone is still debating this these days) work on the client side.
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.
Now with browsers and JavaScript performance being better than ever, preserving state seems possible so a more "original" MVC implementation can (possibly, everyone is still debating this these days) work on the client side.
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?
The original flaw, if you ask me, is the naming. WTF is a model? WTF is a controller? WTF is a view? You can (and I have) explained this to a newbie for an hour and they still won't get it.
They may as well have named it 123. At least that wouldn't make you guess at what the naming signifies.
Well obviously the nuance is going to be lost on someone who hasn't actually programmed the type of system the pattern refers to. There's no way for someone to grok it without a mental model of what the system needs to accomplish. However with that experience it's really not that hard to understand.
I disagree. That's not obvious. It's relatively easy to explain parallelism, concurrency, recursion, currying, idempotency, the visitor pattern, etc. etc. This is different. MVC names are really annoying and poorly chosen. Every time I think of the pattern, I have to make an association between each word of the pattern and its meaning.
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.
> A better name, and this is literally off the top of my head, would be "Business Layer, View and Event Translator".
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 ;-)
I think it can be explained pretty easily, even if necessarily generalizing.
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 am amazed at how one web framework managed to completely redefine a long standing pattern in such a short time. MVC is quite old, and well established, and was even used in web development well before rails came along. But now suddenly 99% of people think MVC means a rails style mess.
The author's idea of moving events into the name suggests a poor understanding of OOP in general (with messages/events being the basis of object oriented approach). Ok, maybe he is talking about some special implementation of events but there are a lot of GUI oriented MVC interpretations which use some special events/signals implementation without trying to put it in the name of the pattern/framework because events are a common part of GUI domain then it suggest a lack of experience.
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.
I think you make a good point, but there seems to be more to the OP's events and operations than you suggest. The 'events' are implied to be broadcast versus 'messages' which are sent to a particular object (i.e. point-to-point) in languages that I know.
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.
As for operations communicating this is generally known as a return value. Parent operations and sub operations is just cleverly disguised procedural programming.
It sounds like half procedural programming, half partial application.
This is actually remarkably similar to Backbone.MarionetteJS, only, swap the O with C for Controller (but don't be fooled, even their docs say it's not the most fitting name).
I once presented Rails as an example of "MVC" in my software architecture class the the Prof. kind of ripped me apart saying either Rails it not MVC or I am misinformed.
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.
The original MVC was invented in the context of a fat client which were desktop-esque applications back in the day. In the context of the Web and HTTP (which is a stateless protocol) MVC had to be adapted to fit this context.
While your professor was right he's also a moron for being overly pedantic and ripping you apart.
In the context of the Web and HTTP (which is a stateless protocol) MVC had to be adapted to fit this context.
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.
Not quite. The apps still have state. That is what we today call web apps, have state. Web pages and REST documents probably shouldn't have state, or have very carefully managed state -- different from say a spreadsheet with a (continuously updated (ok, call it "reactive" if you must)) graph.
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.
> In MVC the views are updated when models change without the controller in between.
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.
Yes, ironically the web frameworks that explicitly say "we're not MVC" tend to be much closer to actual MVC than the ones that call themselves MVC frameworks.
This is quite amusing, as it was one of the biggest complaints I had when coming to an RoR shop from a Java shop (please don't immediately take this to mean that I advocate Java over anything else).
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.
"You have models, which are nice self-contained bits of state, views which are nice self-contained bits of UI, and controllers which are nice self-contained bits of...What?"
Not necessarily, putting business logic in the models as opposed to service classes is a recipe for disaster in any decent sized application. People are realizing this, even in the rails community, and are moving away from it. Putting business logic in the model is not a scalable solution and generally leads to god objects.
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'd say the model is a black box for business data and logic yes. So I'd consider the M and O from the article to be the model - encapsulated data + behaviour. IMO the E part of the article maps to the controller layer (in the web version of MVC).
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.)
I'm not saying put it in models I'm saying it's part of the Model of MVC. If you've got a class called FooBarService that takes a model and executes business logic on it, that FooBarService can still be part of the Model of MVC.
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.
Oh my god no! Business logic is in the model. For example "a new user cannot be created if its email is already used by another user". Would you put that is the controller?
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.
I think the problem is that "business logic" is too vague a term, spanning what can be called both "rules" and "behavior." What you've cited -- "emails must be unique" -- is a business rule and belongs in the model, since only the model can enforce a data invariant like that. But take something like "new users are sent a welcome email." Would you put that in the model? Personally, I wouldn't (my User model is supposed to know about the mail service? really?). That fits into the class of behavior and belongs in a controller.
Put another way, when business rules change, you change your models. When business behavior changes, you change your controllers.
Really, it's a natural extension of the concepts of a database. Constraints and fetching information happen in the data layer, same as always... we've just moved some of the data layer into the model and out of the RDBMS.
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.
Well, you are right, the model should not send the mail to new users. There should a way for the mail service to poll the model for emails to be sent. So the business rule here is still coded in the model. Say you want to also send the same email to old inactive users, you should just need to change the model, add a new business rule.
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.
>But take something like "new users are sent a welcome email." Would you put that in the model?
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.
"Controller" is one of those terms that has meant a lot of different things at different times and in different systems. I agree that the same code asset (whether it's called a controller or whatnot) that handles user input should not be responsible for implementing a rule like "new users get emailed." At the same time, I also don't think such a rule belongs in your model layer. It should go in its own class (sometimes called a service, sometimes also called a controller). So the controller-managing-ui calls the controller-defining-behavior to make changes to the model.
One of the big ideas for me was that the controller is the least reusable, most application specific piece. With that in mind, keeping the bulk of the business logic and view logic in highly testable and reconfigurable models and views makes a lot of sense. I think of a controller as a mapping between model and view -- it takes internal state and pipes it to some views then takes external stimuli and pipes it to some models.
exactly, and the application specific-ness is what makes them hard or poorly understood. General DOM management libraries can't provide a controller. For one thing, it needs to interface with your backend.
I think there is a certain amount of "those who do, do, those who can't, teach" going around in the framework space. To-Do List apps and Photo Galleries don't have business logic.
Todo lists do have business logic, but the logic is so simple that one might not notice when it gets coupled to the views. so you can get away with coupling things like "MV-whatever" or MVVM for apps up to a certain threshold. Facebook is an example of an app well past that threshold, so we should probably listen to them when they talk about their new DOM management library, Facebook React.
The reason is that the code in controllers tend to be view specific in practice, to the extent of projecting view specific models. If you wanted to expose your business logic as APIs, you are better off either writing controllers view agnostic, or pushing down the business logic to something else.
I'm very pleased to see the GUI topic mentioned here. For all of those who seek a UI advise, I have a tip.
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.
A problem is that a lot of developers equate MVC with magical framework that does a lot for me and just happens to have folders named "models", "views", and "controllers" where they put stuff. This can be Rails, but is common in other frameworks as well (even if the names change)
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
If you want a nice alternative to MVC (or event-based systems in general), take a look at functional reactive programming (FRP). Instead of modelling time implicitly using mutable state and callbacks, FRP provides time-varying values as first-class citizens. I've found FRP to create much neater code for most of the UI tasks I've worked with.
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?
whenever i read a headline like "X is dead" (whereby X is a technological concept or even a piece of technology) my first reaction is, that the author has probably a very limited understanding of the technology at hand (or about the underlying concepts of that technology)
* 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
Talking about an architectural pattern without specifying its applicability or limitations or context is just completely wrong.
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)
I've been doing something similar to this with Backbone. Backbone has Models, Views, and Events. I put the "Operations" in the Model and Collection extended classes, so the login operation is performed by the User model. So I would call something like currentUser.login(credentials).
I think there's an easy answer to the question of what the controller is - it's the business logic. My main problem with the MVC pattern is actually related to the model and view communicating directly. I started using the MVP pattern and then switched to passive view (http://martinfowler.com/eaaDev/PassiveScreen.html) to eliminate as much code (and therefore testing) as possible from the view.
No that's what the model is for. The controller is just for handling framework specific input. It takes the framework specific part, puts it in a form that the business logic can understand (eg: business logic shouldn't even know what a mouseEvent is), and hands it off to the model's business logic to handle.
You know what its time for ? To go back bit, beyond the patterns, read "A Pattern language" by Christopher Alexander. Understand why those patterns become the way they are, and build software that makes as much sense as real world buildings. Things that are much more costly than software to tinker with. Given how much complex shit is becoming today, imposing any fixed label on how we devs build things would become very restraining very quickly.
Why is this new in 2012? The "event" component is generally implemented using the Observer/Listener pattern in Java and has been done like so for yonks. The most "modern" concept he alludes to in that section is the idea of everything being modelled as operations (and sub-operations) which is pretty much Command-Query-Responsibility-Segregation.
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.
Maybe you mean "devolved". MVC is alive and kicking where I sit. Instead I constantly see the passing corpses of MVVM and CQRS projects... Honestly, not trolling - this is what I have seen for many years.
Well it depends on how people are using it I guess? ;) just because there are plenty of MVVM/cqrs projects that have failed doesn't mean that mvc is more successful... One could propose that devs are more familiar with the steward of traditional architecture?
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 =)
Well, the problem is that if you find Controllers badly defined in MVC, good luck in understanding how to use View Models properly. MVVM seems to me on many levels a re-hash of the old Document/View concept, which is... not so good, because of coupling. And in fact, Many MVVM codebases end up being tightly coupled - bear in mind, also many MVC projects, especially of the ActiveRecord sort.
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)
I'd argue that MVVM is a subset of MVC. So technically they're accurate.
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.
Actually that's what MVC is supposed to be. Whether you use events, callbacks, delegates, or dirty checking really doesn't matter. Views inform the controller, controller updates the model. Events and Operations are the Controller, but lets not shove MVC into some specific implementation based on events, it's an abstract pattern for software architecture, not a framework.
>Views inform the controller, controller updates the model
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.
Have definitely had an excellent experience using an experimental MVC setup in Kivy. Can't chip into any MVC death exclamations. First I should mention that Kivy uses data-binding liberally. It's not events, it's publisher-subscriber where bound functions receive the changes as their arguments. This fixes many things, but Kivy uses a widget tree. Trees are great for reasoning about context, scope, relationship etc between graphics elements in layouts.
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.
I was never a fan of "strict" web MVC. It felt like you were jamming far too much into your models.
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.
>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.
I like to think that its not model view controller, but instead model-view-behavior (or the strategy pattern)
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.
"A common operation for applications is logging a user in. It's actually two sub-operations composed together: first get the email address and password from the user, second load the "user" model from the database and check whether the password matches."
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...
looking at the comments, few programmers even understand MVC yet. Maybe it's just a lack of understanding that causes people to think it's time to MOVE on...
>O: Operations encapsulate everything that your application does.
>E: Events are used to join all these components together safely.
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.
Sounds like my reaction on Apple's version MVC: "Do I have to stuff ALL of this stuff into a Controller???". But if I use something like LESS with a ORM or Microsoft MVC with EF and nice IOC and builder patterns all of a sudden the controller does nothing else but evaluating the request and giving the right kind of response.
Indeed. Even if you are not using an ORM, controller functions should be short. Functions are just not supposed to be 30+ lines.
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.
Basically, you have your program in three parts. Model, view, and controller. The model is the meat of everything. It knows the system, it interacts with other programs, it determines everything. The view is what gets shown to the user. The controller is what the user interacts with. Both the view and the controller should be as minimal as possible, only serving to relay information between the model and the user.
And one place that is easy to trip up, is that you'll probably want to model your data, eg do normalization. That is your applications data model. But that is not the same as the model in MVC.
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.
Blindly picking a design pattern before you develop your application will always be bad. Don't do it. If you do be prepared for tired legs because the chase to find a better one will be never-ending.
We built a prototype app using AngularJS. For our specific usage of AngularJS, while we achieved our goal with the least LOC, its performance is so poor [on mobile] compared to Ember.js, CanJS and MarionetteJS that it was certain that AngularJS is indeed designed for the future, but not the present.
If you did any kind of systematic comparison of those, write a blog post and post it here. I bet it would get a lot of discussion. Angular's mobile performance is very interesting, but not something that seems to have gotten much attention yet.
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.