11 ms·
MVC Isn’t MVC
- EdwardDiego 3y agoAnd REST isn't REST. Words and phrases change, no semantics survive first contact with the enemy. Literally used to literally mean literally, now it doesn't. Grieve, and move on.
- misterbwong 3y agoIf you squint a bit, the "original" MVC looks eerily similar to the one-way data flow pattern popularized by flux/redux. https://en.wikipedia.org/wiki/React_(software)#Unidirectional_data_flow https://en.wikipedia.org/wiki/React_(software)#Unidirectiona... edit: better link
- dfox 3y agoIndeed, what the various “reactive” frameworks do is in the end the idea behind MVC, although as they are web-based the implementation is ridiculously complex and the abstraction is very leaky.
- scrame 3y agothe purest mvc demo is pong.
- laurent123456 3y agoIn many ways it's really just MVC (at least the fat model / skinny controller style) except they renamed the elements: - Dispatcher = Controller - Store = Model - View = View And the actions are the messages sent from the user to the controller.
- MrPatan 3y agoIt may be a matter of explaining it differently. Maybe just the names! But I never "got" MVC, and I got the one way data flow pattern straight away. Maybe I was just old enough to get the point that time around.
- breadwinner 3y agoMVC is one-way. Some people think MVC is two-way data binding. That's MVVC actually.
- PlunderBunny 3y agoI'm glad I'm not the only one that doesn't get MVC. I can sort of understand it if I study a real example for a long time, but to doesn't stick. Sometimes I want to think that learning to code in the days of 8-bit computers is somehow incompatible with a lot of modern programming concepts, but maybe I'm just old and tired.
- tracker1 3y agoI think flux/redux is generally cleaner imo. But have had a tendency to think of it that way. MVC usually feels like spaghetti in contrast. And while Redux/Flux takes some mental overhead, I see so many fewer side effects in UIs that use the approach.
- DaiPlusPlus 3y ago> MVC looks eerily similar to the one-way data flow pattern popularized by flux/redux. I'm not seeing it. From TFA: > Views: A visual representation of a model. Views are updated by querying the model directly, and are notified by the model of updates. A view can update it’s model directly. A view should never know about things like keyboard and mouse events directly. I'd like to emphasise the "a view can update its model directly" part - which is exactly what Redux and React are designed to prevent: when logic in a view can mutate the model (especially when the view _also_ depends on update notifications from the model to update itself) things get impossible to reason-about. Instead, Redux/React is designed to force the view to "update" the model indirectly via actions and reducers. Another tenet of Redux+React is that the model ("state" in Redux/React) is an immutable object-graph which is replaced on every update, whereas "classical" MVC requires a mutable, long-life'd model. I feel the similarities only exist if you squint - and if you're lumping TFA's idea of MVC with React (and MVVM (groan...)) as ideas in opposition to how most people wrote/write RAD/VB6/WinForms by directly subclassing controls and overriding message-pump event-handler methods, which (I hope) everyone will agree is an approach that doesn't scale beyond building throwaway UIs.
- preommr 3y agoIf you squint almost of all software looks like MVC because it's essentially just, input(data)/processing(controller)/output(view).
- taberiand 3y agoIf you squint just a little more you'll notice a monad is just a monoid in the category of endofunctors.
- myaccountonhn 3y agoSoftware is just a giant ORM.
- rtontic 3y agoIt's all just one big state machine.
- gepardi 3y agoIf I squint, Redux is like a controller. Handles requests and response. It calls the DB, gets a response, updates state, then a view (React component) renders it.
- Avlin67 3y agoI did long forgot the MVC stuff...
- fredgrott 3y agoTo get anal If you use any SDK and or framework you do not have MVC you instead have framework-SuperController | MVC
- EdwardDiego 3y ago> To get anal Buy them a very nice dinner, at least.
- Khelavaster 3y agoResponsive UI-driven apps these days use MVC backend => frontend MVC app context loader => frontend MVVM application layer. https://learn.microsoft.com/en-us/dotnet/architecture/maui/mvvm https://learn.microsoft.com/en-us/dotnet/architecture/maui/m...
- breadwinner 3y agoMVVM uses two-way data binding. By now it is widely acknowledged that one-way data binding is better.
- vxNsr 3y agoI wish I was smart enough to understand what this really means, I often feel very much like a code monkey when these discussions come up.
- breadwinner 3y agoIn the old days there was just MVC. Then Microsoft announced successor to Windows Forms... a new technology called WPF. WPF uses MVVM which automated more of the work that a developer has to do: it automatically updates the UI when data objects change, and it automatically updates data objects when the user inputs something through the UI. Sounds cool, right? The problem is that in large projects it becomes hard to understand how data is flowing. Because of excessive automation things are happening behind the scenes. Developers began to understand that this is not as cool as it initially looked. React re-introduced one-way data binding, which updates the screen when data objects change, but not the other direction. People found that they are significantly more productive with this technology even though it does less on behalf of the developer. Now it is widely acknowledged that one-way data binding is better.
- Khelavaster 3y ago... WPF has built-in one-way databinding. You choose whether every control is one-way or two-way...
- bsaul 3y agoNot sure why author got the impression apple’s models had to be « dumb data containers ». Actually, having dumb models is the surest way to completely screw up your controllers design, since you’re now left with no other places to write your business logic in. This leads to either weird trees of controller inheriting each other for the sake of reusing some data processing piece, or singletons everywhere which makes the code super hard to reason upon, not to mention harder to unit test. My take on the model layer is : write everything that’s not strictly specific to your UI there.
- vsareto 3y agoWe really need to call it Model-View-Controller-Service-Repository and be done with it. That is actually what happens 99% of the time. Logic is done within services and where the complex dependency graphs live. Repositories do the data retrieval. The controller is a traffic cop. The model is a data transfer object with maybe some calculated fields. The view makes things pretty.
- gabereiser 3y agoLol, but MVCSR (MVCaeser) sounds like an architectural dictatorship where one must follow all rules or else be outcast from citizenship. Where some executive will stab you in the back and sell it to a private equity firm to be cut and squeezed by all the lands and your intentions and beautiful code structure is murdered by junior bootcamp devs. /s
- LeonB 3y agoThe problem with the MVCaesar pattern is that sooner or later a Basic Routing Universal Transformer User Service stabs it in the back.
- gabereiser 3y agoIronically named Optimus.
- 3y ago
- janetacarr 3y agoMy take on MVC is that it's an architectural pattern to decouple state, state changes, and state usage.
- breadwinner 3y agoFun fact: React was originally designed to be used as the 'V' in MVC [1]. [1] https://github.com/facebook/react/tree/015833e5942ce55cf31aefd0a5c2be8a65ec2daa https://github.com/facebook/react/tree/015833e5942ce55cf31ae...
- dcre 3y agoIt still can be! A client-side app that talks to an API is still the V. Obviously many apps get elaborate with client-side state, but you don’t have to!
- quickthrower2 3y agoThat API itself my use MVC too!
- fellowniusmonk 3y agoIs it weird that the inconsistent citation scheme really jumped out at me? > In December of 1979 _Tyrgve Reenskaug_, an employee of _Xerox PARC_ Later >In 2004, a Danish man
- toyg 3y agoI took that as a slight dig at the (famously self-publicizing) Rails creator, or an in-joke for the Rails crowd - which seems to be the world the author lives in.
- 59nadir 3y agoI found it really funny, it actually made me laugh out loud. It seemed very deliberate to me, though, so that's why. Edit: To clarify, I think DHH would probably laugh at this as well, which is why I feel it's not so much laughing at anyone as it is laughing with them.
- 20x6 3y agoThe author is being cute in the second citation and is referring to David Heinemeier Hansson who is famous in the web dev world for creating Ruby on Rails.
- keyle 3y agoThere is a lot of truth in what the Author wrote, however he completely missed the MVVM pattern and confused it with MVC. The MVVM pattern, originally designed by MSFT for Silverlight, showed a way that basically cleaned up a lot of the issues with MVC. That is what SwiftUI uses today, MVVM, as you can compare with his diagram of what he calls "Apple's MVC" and this diagram from MSFT: [1]. In fact, I'd go out on a limb and say that no one really uses MVC today - in its pure original form. [1] https://learn.microsoft.com/en-us/dotnet/architecture/maui/mvvm https://learn.microsoft.com/en-us/dotnet/architecture/maui/m...
- smackeyacky 3y agoFunnily enough, the 1990s VisualWorks UI moved on from the original MVC implementation into a pile of complexity involving adaptor classes and automated event processing, so even the Smalltalk guys knew the original implementation wasn't enough for most GUI problems.
- sparkie 3y agoI like the Model-View-Adapter[1] architecture, which is basically what you get by reversing the arrows between the View and ViewModel in MVVM. The view and model are oblivious to each other and to the adaptor directly (but interact with it indirectly), and the adaptor depends on both the view and model. My use case for this a bit different than regular UIs though. I've used it in an MMO server, with the view representing the network protocol which clients interact with, and the model being the state of the game world. The adapter receives messages from game clients asynchronously and updates the world, then sends messages back to the clients affected by the change in the world state. IMO it makes sense to have the inverted dependency in this case. If the view depended on the adaptor, then changes to the game server behavior would impact the network protocol, which would also force changes to user clients each time the server gets updated. Ideally we want to be able to make regular updates to the server without impacting clients. [1]:https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93adapter https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93ada...
- chvik 3y agoIn the referred paper the Controller sends messages to the View but never interacts with the Model, so the diagram in the article incorrectly represents that concept.
- rambojohnson 3y agoconvoluted nonsense
- t3rra 3y agoWhat MVC refers these days is not of MVC from 1979 but from the Design Patterns by Gags of Four and they did not mean the patterns should be applied strictly as is. So.. what? What is the point of the article? He does not seem to really understand the purpose of design patterns and it in practice
- fifticon 3y agoI would upvote for 'gags of four'.
- EdwardDiego 3y agoA visitor walks into a bar...
- regularfry 3y agoMVC isn't a Pattern in GoF.
- chunsj 3y agoFor OpenStep/NeXTSTEP style MVC, which is very similar to the original MVC, is well explained in the book "OpenStep for Enterprises", https://www.amazon.com/OpenStep-Enterprises-Nancy-Knolle-Craighill/dp/0471308595 https://www.amazon.com/OpenStep-Enterprises-Nancy-Knolle-Cra... . I just cannot understand why the author says it's different from ST80 style MVC.
- layer8 3y agoIs the explanation in that book better/different than the one in https://cdn.preterhuman.net/texts/computing/nextstep-openstep/discovering.pdf https://cdn.preterhuman.net/texts/computing/nextstep-openste...? Just curious.
- derefr 3y agoSo, the original MVC was designed in the context of green-screen terminal systems. In that context, this “design pattern” really isn’t a design pattern per se; it’s just a formalism over the code you’d inevitably write to make such a system work. In a green-screen system: • the “view” is the terminal buffer state — not even a “virtual DOM” version of it, but literally the buffer state itself (under 3270 protocol, properties like “editable” are basically bits in the TTY buffer applied per-cell — you can think of them like ANSI TTY-cell background colors and not be far off.) Think of it as an mmap(2)ed file in backend memory, holding structs of almost the same type as the view, save for OS-syscall-time remapping to prune out the form labels. • the “model” is the ADT over the record-oriented mainframe datafile backing the terminal (How does the model know how to change the view? Because it’s a very thin abstraction: fields in the view-state, and fields in the DB state, are 1:1, with no parsing or serialization — leading to things like passwords only being stored in the DB at the size of the form-field for them.) • the “controller” is the serial line-discipline that interprets the key codes sent from a TTY into editing actions like “overwrite a character” or “backspace”, and applies those actions to the data in the model (how does it know what part of the model is active? “Spatial databases” have something like a hierarchical navigation-path DB cursor as part of their descriptor state. Switching the active view is a model state change!) • you need an “editor” separate from the “controller” because otherwise every character edit action sent to the TTY would provoke an instantaneous commensurate change in the DB data. If you need to store and validate live edits before committing them to the DB, then you need an editor “proxy” object to hold that “draft” state. All in all, pretty different from anything we’re doing these days. Or is it? Depends on where you draw the line of abstraction! In modern terms: • the classical MVC “controller” is the frontend or per-component view controller — observing the client’s actions and feeding them into the system as events. • the classical MVC “view” is the API query result set, databound through the client DOM components. If your app is server-side rendered, it’s the HTML DOM itself as loaded into the browser! • the classical MVC “model” is the entire backend, through its API • the classical MVC “editor” is the changeset — a CQRS Command-in-draft. (In a HATEOAS context, an HTML form is also this.)
- gumby 3y ago> So, the original MVC was designed in the context of green-screen terminal systems. Not at all: this was designed at PARC in the context of the Alto and the D machines running systems like Smalltalk. It even mentions the mouse. It talks about querying the type of a field, that might for example contain text. You reasonably mapped it to a serial character terminal but this is not at all what it was designed for.
- LudwigNagasena 3y ago> Model updates View, View sees User, User uses Controller, Controller manipulates Model. > This makes a lot of sense to me, and I think I understand it pretty well. It looks simple at first glance, but it actually makes zero sense under closer inspection. Let’s take a simple example. A table of users. You take a table from the database and put it into an html tag table. Wait, who is “you”? The model? Do you want your model to know about html? The view? Do you want your view to know how to connect to a db? The glue code for them? If so, then it is the model-view-controller-glue, not model-view-controller. This is why what the author calls Apple-MVC is far more common. It is just hexagonal architecture. You take different components that take care of their own area of concern and glue them together to fit specific needs of your app. That glue code is called “controller” in that case. It is intuitive and simple; and thousands of junior developers probably reinvent that type of architecture every day.
- LeonB 3y ago> You take a table from the database and put it into an html tag table. Wait, who is “you”? The model? The model tells the view about itself. This is early O O. Everything is an object. And objects have power and self awareness. When the view receives the message telling it about the model, it does what it has to do to make the model viewable. So the model and the controller don’t know about html. The view received a message (the current state of the model, or a delta thereof) and responds accordingly.
- fardo 3y agoThe way I typically think of it is • Model is “whatever you need to store persistently, how you represent that data, how should the data be structured and stored when it’s at rest (eg in a database, nosql environment, or big data query system), how you are expected to query that data when you need it, mediates common CRUD data query operations on the store, and broadly handles giving back the results of any stored data query. Intent of the model is to be a black box the controller can talk to whenever it needs something from “storage”. If you did it right, you can change the entire underlying data store and endpoint, and as long as the API for the model is preserved, the controllers don’t even notice. • Controllers mediate “turning prepared or cached model data queries into something to give back to the user” and “listening for the user wanting to do something and responding appropriately by fetching needed model data or server resources”. Handles moving between pages, incoming API calls, last mile data filtration (where last mile is based on milliseconds to do it, >25ish or so and it probably belongs on the model) and cleanup if any is needed, and is first line of contact (and defense) for anything a user’s triggered. • Views are whatever the user can visibly interact with and see, and provide buttons, links and interactibles which hook into controller calls to change things or give back data I’ve found the above model typically has good separation of concerns, usually avoids most fights of “does this belong on the model or controller”, and you can usually cleanly parallelize work between multiple people on a small team if you use ~~waterfall~~ scrum to agree on a data model for each endpoint and needed functions before starting.
- hk1337 3y agoA bit pedantic. It’s just a design principle not a scientific law.
- roncesvalles 3y agoMVC is one of those things (like Agile) that doesn't actually mean anything and people just nod their heads and gloss over it when someone mentions it. You know when something is that kind of thing when most discussion on it is about the definition.
- ozim 3y agoIt does mean something specific and useful. (both mvc and agile) Only that people who are productive take it and try to use it and stop caring about nonsense details. Where bunch of other people try to dissect it to find “true way” which is bunch of time wasting and annoying for people who need to get job done. Then these people also blame flawed use of “pattern/process” for whatever went wrong because only if they could do it perfectly as described in some blog post everything would be perfect. Meanwhile while they were arguing if daily standup should be 10 or 12 people and maybe 23 minutes instead of 19, and if controller is really a controller and should have less or more logic - productive people shipped two versions of app to test server and presented it to the customer already.
- joeyguerra 3y agoFun article. Just a note, MVC requires the Observer Pattern. If the Observer Pattern isn't present, it's not MVC. And it's fine if it's not MVC. It can be called something else. It's fine. RoR doesn't implement the Observer Pattern; thus, not MVC. It can just be RoR. AspNet MVC doesn't implement the Observer Partner; not MVC. It can just be AspNet. Here's another reference to Tyrgver's explanation of the MVC language. Although, it's lack of code (and details) is probably one reason why people misunderstand MVC ;) https://folk.universitetetioslo.no/trygver/themes/mvc/mvc-index.html https://folk.universitetetioslo.no/trygver/themes/mvc/mvc-in... Woohooo! Fun times.
- regularfry 3y agohttps://github.com/hotwired/turbo-rails/blob/main/app/models/concerns/turbo/broadcastable.rb https://github.com/hotwired/turbo-rails/blob/main/app/models... is designed to close that loop with automated view updates from ActiveRecord changes.
- adamrezich 3y agofor simple web application backends, why does one need more than just "models" (structs, that describe database tables/rows, using something like "an ORM" but more lightweight, so as to provide query building, caching, etc.) and "routes" (procedures, mapped to URL patterns, that execute logic such as accessing models (cached or queried) and then responding with output from a simple HTML template system, or possibly a cached template rendering, or JSON)? I was never trained/educated in the MVC pattern but back when Rails was new and I was trying it out, it just seemed like a lot of unnecessary boilerplate, and it was cool that Rails helps you scaffold it out and all—but why? I'm working on building a framework that is more or less what I describe above, and so far it's going great. I can make simple CRUD apps with it pretty dang easily. I don't really have an interest in using React or whatever the newest frontend framework is to do fancy front-end stuff. is there something I'm missing, or does my approach seem reasonable? I just don't really see the need for having separate Vs and Cs when it comes to web backend things. this article helped give me a bit more context as to where these ideas came from, and I appreciate it, but as of right now, as the article itself and some other commenters have mentioned, it doesn't seem to make sense to take this MVC pattern as-is and apply it to contemporary backend web development. but, I've never built websites from scratch that were bigger than "small to medium", so it's possible there's something I'm missing?
- yawnxyz 3y agoI'm using Sveltekit and doing pretty much what you're doing, and never touched Rails before. I'm equally confused about the MVC pattern I hear so much, and why it was so big back then, and why it isn't very big now. Was this more of a design / architecture "fad" or a design around the constraints of the time?
- lizardking 3y agoMVC offered a formalized separation of concerns for data, ui, and business logic at a time when many developers were cramming all of their application code into massive php or C# files. The pattern was delivered via frameworks (RoR, Cake, Asp.net MVC) that handled a lot of the boiler plate for you and made for an easier development experience than what most of the people switching to it were used to at the time. As web applications became more focused on the client code, the template driven server side rendering capabilities of these frameworks was less useful or no longer necessary. Initially when the mindshare began to move to the client code, front end tool chains actually did do a lot of hemming and hawing of what variant of mv* they were. Eventually tools like react came around and whatever variant of mv* they were wasn’t what was interesting about the building paradigm. More or less that’s where we are now.
- jrochkind1 3y agoThe Rails-style MVC is very very similar to the WebObjects MVC, which came from NeXT then was at Apple (and may still be used internally). Wikipedia says the first public demo of WebObjects was 1995. Original WebObjects tried to ignore the web's statelessness by keeping state on the server, and encoding state in a path param in every URL. It was not exactly designed to fit a stateless environment as designed to let the developer ignore the fact that the environment was stateless, put an abstraction on top that made it appear stateful. But maybe that's semantics. But later WebObjects, towards the end of when it stopped being a commercial product, grew out of this -- it was in fact a very bad fit for the web. Encoding an opaque identifier in every URL to connect to back-end state is bad for cache-ability, idempotency, persistent URLs, etc., it's not what Tim BL or Roy Fielding wanted from URLs at all. BUT, despite all that (differences in "routing", URL-to-app mapping), as far as the MVC break-down, the original WebObjects was still very much like the architecture of Rails, to the extent that I've often wondered if the Rails originator(s) were exposed to WebObjects. But, then, I'm not sure that this architecture, actually was motivated by, as OP says: "but in a way that makes sense for the web. The components don't have references to each other, because and nothing is alive. Each object is only around long enough for the page to be rendered" -- because the earlier WebObjects, as far as MVC split very much like Rails, in fact did it's best to keep the objects alive after all on the back-end, and provide abstractions that hid the statelessness of the web from the developer, connecting each HTTP request to the kept-alive-in-back-end objects, where things did have references to each other, or appeared to, that ought to have not been possible. But still had the same MVC breakdown that could be diagrammed the same way. Actually here's a 2001 version of the WebObjects manual, note they are pointing this out as different than classic MVC, but it is very much like Rails too. > Note: WebObjects uses the term “model” differently from MVC. In WebObjects, a model establishes and maintains a correspondence between an enterprise object class and data stored in a relational database. In MVC, model objects represent the special knowledge of the application. — https://developer.apple.com/library/archive/documentation/LegacyTechnologies/WebObjects/WebObjects_5/WebObjectsOverview/WebObjectsOverview.pdf https://developer.apple.com/library/archive/documentation/Le... page 28 More on MVC in WebObjects there too > Acting as a mediator between Model objects and View objects in an application is a Controller object… Because of the Controller's central mediating role, Model objects need not know about the state and events of the user interface, and View objects need not know about the programmatic interfaces of the Model objects. Familiar, right? And different from what the OP is saying was original MVC; maybe consistent with both what OP calls Apple-style as well as Rails-style MVC? I haven't found an earlier dated WebObjects manual online (such as actually from NeXT days!), but they definitely existed, would be interesting to see how they referred to MVC. You can see a little bit about the weird ways original WebObject tried to encode state in URLs, mapping to persistent back-end state, in this other legacy WebObjects doc I found on the web, see "Component Action URLs" on page 12, and following through page 17. https://wiki.wocommunity.org/download/attachments/1049043/Web_Applications.pdf https://wiki.wocommunity.org/download/attachments/1049043/We...
- 1propionyl 3y agoYes, because what is called MVC today is really MVP (originating at Taligent), which was a simplification/derivation of Xerox MVC intended for loosely coupling business logic to user interfaces. This is just my speculation but I think the mixup between MVC/MVP was largely the fault of Rails' popularity coupled with a general lack of awareness of Xerox MVC, and after its popularity other frameworks have rolled with the corruption/redefinition. That said, whether you call it a Presenter or Controller is largely irrelevant in practice. It's just a particular application of the mediator pattern (requiring some form of observer-like pattern) with the goal of decoupling the Model from the View. The presenter/controller's job is to mediate between the model and view. The P/C references and can directly call both M and V, but also observes M and V such that neither M not V knows about P nor about each other. The key benefits here are that the M is now testable in isolation, and it's much easier to swap V out for V' (with an accompanying P'). MVVM is another story, but it's in the same MVP derived family. Xerox MVC is largely a relic, though as some other commenters have pointed out there are some echoes of it in some React/Vue architectures today.
- ggm 3y agoI've always tended to think these analytic frameworks are tools to aide discussion not actual proscriptive ground truths. I do believe CAP. I don't think you can optimise for all 3. But that aside, I never yet found a compelling "this is how we do it" which didn't come with exceptions, which turned out to be anything BUT "exceptional" when it came to what I observed in the system at large. Atomic ops which were dependent on subsequent calls. Databases which said they implemented transactions but it turns out people code around them because of the barriers in parallelising outcomes. Systems which say they depend solely on update in the browser but which make persisting calls back into the server to update state, and fail if that doesn't work. Views and Projections, Message Buses, Eventual Consistency, they all turn out to have "mostly" tacked on the back. "its CRUD, Spock, but not as we know it" -Mostly. ("it's life jim": octopuses, coral.. deep earth mineral digesting worms, bryophytes, mitochondria... prions...)
- agumonkey 3y agoMVC discussions makes me miss state machine minimization and linear algebra.
- revskill 3y agoThe problem with MVC is not MVC, it's the problem with documentation. Who's the caller for the dependency chain ?
- BulgarianIdiot 3y ago[dead]
- nologic01 3y agoSomehow applications running on a single machine (classical desktop apps) cannot be the same class of patterns as a browser-webserver combo where two different machines may persist different pieces of data, respond to different types of events etc. The browser receives human user input and displays model information. For the web server the "user" is the browser. Effectively you might want to start with an abstract stacked MVC-MVC pattern and see if anything is actually redundant. I dont think clearing those things up is an academic pursuit. The confusion about those patterns is an important data point about the quality and accuracy of our communication about architectural designs. If you thing of the MVC discussion as a sort of metacode, its full of metabugs.
- mpweiher 3y ago> Model updates View, View sees User, User uses Controller, Controller manipulates Model. Yeah, not really. The View is actually also used to manipulate the model, most of the time. The Controllers are there for more complex situations, and stuff that isn't really relevant any longer, like handing the physical input devices. We've abstracted most of this away now and it is packaged in the toolkits in such a way that you don't have to translate between the mouse controller and the UI/Model. It is also important to note that these are roles not objects, meaning a single object can have multiple of these roles. As an example, Apple's views have had a lot of controller functionality in them since forever. Which is why the appearance of "ViewControllers" really confused me. At best I can tell there were two reasons for them: first, to implement all the "remaining" functionality that couldn't be handled by the hooking up widgets to CoreData-generated entities using bindings in Interface Builder. Alas, that turned out to be quite a bit. Second, as a memory optimisation in early iOS, as placeholders for Views that could be discarded and recreated on-demand. Neither of these is relevant today. See also: https://blog.metaobject.com/2015/04/model-widget-controller-mwc-aka-apple.html https://blog.metaobject.com/2015/04/model-widget-controller-... https://blog.metaobject.com/2015/04/reactnative-isn.html https://blog.metaobject.com/2015/04/reactnative-isn.html https://blog.metaobject.com/2017/03/concept-shadowing-and-capture-in-mvc.html https://blog.metaobject.com/2017/03/concept-shadowing-and-ca... https://blog.metaobject.com/2022/06/blackbird-simple-reference-architecture.html https://blog.metaobject.com/2022/06/blackbird-simple-referen...
- EGreg 3y agoTLDR: So what, indeed? Does any of this matter? I mean, not really.
- layer8 3y agoOne question which always preoccupied me is how those MVC components interact with nesting/recursion. For example, a view may include a scrollbar, which has state, and can be interacted with, sometimes independently from the model displayed by that view. So the scrollbar has it’s own model (containing e.g. the scrollbar position) and it’s own view (responsible for how the scrollbar is rendered) and controller (allowing the user to operate the scrollbar). This nested mini-MVC for the scrollbar however is primarily or exclusively part of the larger view. The scrollbar’s model, however, may have to refer to the larger model, for example when the scrollbar size depends on the size of the larger model’s data. Or maybe its the scrollbar’s controller that queries the larger model (or gets notified by it) and then updates the scrollbar’s model. In any case, it’s not obvious how exactly the nesting could or should work. More complex cases are for example a combo box, which consists of a text input, a dropdown button, a dropdown list, which in turn may have a scrollbar. And this is just one relatively basic control within a potentially much more complex UI. I’ve never seen a systematic treatment of that topic. Given that UIs use nested controls, one would think that this would be widely addressed by architectural patterns for UIs.
- mejutoco 3y agoThe approach Elm uses is every event goes through a main "router", no exceptions. If you want to do sth special on the account page modal scroll, you issue a specific event for that, and deal with it in the same way as any other. It is a very simple and clean model, but not complicated enough for some people :) of course it helps that with a good type system you can catch missing or incorrect cases.
- EVa5I7bHFq9mnYK 3y agoThis is what MVVM is for. Last two letters mean View Model - a model of the view - data structures for each user control, and code that synchronizes these structures with Model structures.
- layer8 3y agoBut that’s not a recursive pattern. I would disagree that there is only a single level on which MVC, MVVM, or whatever, is relevant. For example, the controller or View Model of a view containing a combo box should not have to manage the internal mechanics of the combo box. So it makes sense for the combo box to have its own internal MVC/MVVM. Similarly, the view may be embedded into a larger dashboard, where the dashboard should not have to manage the internals of the view, but would have its own MVC/MVVM.
- danabrams 3y agoThe M in MVC has come to mean “data model,” but it originally referred to the “mental model” of the user. What kind of thing are we trying to manipulate and what is the user’s mental model of such a thing? How about a bank account? A mental model of a bank account would include useful operations like deposit, withdraw, transfer, checkBalance, and these would be the methods on the object. The data schema and the persistence would be necessary, of course, but an implementation detail. Models were smart and mapped to human perceptions of a thing, rather than dumb data persistence layers. These kind of business logic operations have often been moved into controllers, which couldn’t have been further from the original intention. MVC, smalltalk, OOP we’re all about stopping and thinking about the way humans think while interacting with computers. It was about designing nice interfaces for interaction based on human expectations, not database requirements. Internal object schemas and data persistence were implementation details of an object that could—if you did it right—be easily changed without changing the interface. But we can’t help ourselves, and instead OOP today is a world of getters and setters with a little bit of data validation (if we’re lucky) and models are just a schema plus a generic data persistence interface (maybe an orm). And the business logic exists in the controller, the least important, least reusable component of the architecture.
- samsquire 3y agoThanks for this insightful comment. I think of the model as being the perfect API for your system that you would happily use if you were in a REPL or in a command line. It's primary goal should be elegance to do the things that a user would want to do with your system, from a programmatic perspective. The programmatic interface is a user interface that's not necessarily graphical. Very few people treat OOP as interacting objects with message passing as in Smalltalk and I think we've lost something.
- danabrams 3y agoI agree, and I wonder if this is just what happened as an accident of history or so much a tendency of human nature that we couldn’t have done it any other way. Maybe simple data models is the mental model of computing that couldn’t be easily changed.
- unconed 3y agoJust going to leave this here: "There is a View, which only knows how to tell you something. There is a Controller, which only knows how to manipulate something. This is a crack team of a quadriplegic and a blind man, each in separate rooms, and you have to delegate your UI to them? How, in the name of all that is holy, are you supposed to do that? Prisoner dilemmas and trolleys? No really, if the View is a TextField, with a keyboard cursor, and mouse selection, and scrolling, and Japanese, how is it possible to edit the model backing it unless you are privy to all that same information? What if it's a map or a spreadsheet? ばか! This implies either one of two things. First, that the Controller has to be specialized for the target widget. It's a TextController, with its own house key to the TextView, not pictured. Or second, that the Controller doesn't do anything useful at all, it's the View that's doing all the heavy lifting, the Controller is just a fancy setter. The TextModel certainly isn't supposed to contain anything View-specific, or it wouldn't be MVC. Wikipedia does helpfully tell us that "Particular MVC architectures can vary significantly from the traditional description here." but I would argue the description is complete and utter nonsense. Image-googling MVC is however a fun exercise for all the zany diagrams you get back. It's a puzzle to figure out if any two actually describe the same thing." https://acko.net/blog/model-view-catharsis/ https://acko.net/blog/model-view-catharsis/ MVC is a cargo cult, and at the end of the day separating your view from your controller isn't going to accomplish anything if the code can't be easily upgraded to multiplayer with undo/redo, which is what users want.
- ptx 3y ago> This implies either one of two things. First, that the Controller has to be specialized for the target widget. It's a TextController, with its own house key to the TextView Yes, this appears to be the way it worked in Smalltalk-80 [1]. You had StringHolderView and StringHolderController which used a StringHolder as the model. > Or second, that the Controller doesn't do anything useful at all The controller in Smalltalk-80 controlled input focus. The view wouldn't be able to receive any input without a controller: "Class Controller does include default scheduling behavior. It takes the point of view that only one controller is to be active at a time; that is, only one controller at a time mediates user input actions. Other views could be displaying information in parallel, but the user's actions are to be interpreted by a single controller. Thus, there is behavior in class Controller for determining whether a controller needs to receive or maintain control." [1] https://web.archive.org/web/20100921030808/http://www.itu.dk/courses/VOP/E2005/VOP2005E/8_mvc_krasner_and_pope.pdf https://web.archive.org/web/20100921030808/http://www.itu.dk...
- ptx 3y agoInteresting article. I didn't know about JSP Model 2. Another detail that's not mentioned, but very useful for understanding the original pattern, which is described in [1], is that controllers had a specific and unique responsibility in the original system where the MVC pattern was defined: The system gives the input focus to a controller, not to a view, so you can't accept keyboard input without a controller. So, unlike pretty much every other GUI toolkit, it's not a matter of having the view delegating input to a controller as a matter of good design, but rather that the controller is simply the way that the system provides the input to the application – you have no choice in the matter. This also meant that there was one controller per widget that could receive focus (corresponding to each HWND in win32), not just one controller per screen. The same document also contains answers to some frequently debated questions about the true, proper and orthodox way to do MVC: Should the view subscribe to model or should the view updates be mediated by the controller? Should the model represent the pure domain logic or also contain view-level state? Should the model be a simple value object or also contain domain logic? It turns out the answer is: All of the above! The original MVC in Smalltalk apparently used all of these options in different applications depending on the circumstances. [1] https://web.archive.org/web/20100921030808/http://www.itu.dk/courses/VOP/E2005/VOP2005E/8_mvc_krasner_and_pope.pdf https://web.archive.org/web/20100921030808/http://www.itu.dk...
- layer8 3y agoAs a side note, taking the model out of the equation, the split between controller and view is very similar to command-query separation [0], in the original MVC. [0] https://en.wikipedia.org/wiki/Command–query_separation https://en.wikipedia.org/wiki/Command–query_separation
- kaba0 3y agoIt’s a topic I’m very interested in! A very eye-opening comment I have seen on HN was this: https://news.ycombinator.com/item?id=4190252 https://news.ycombinator.com/item?id=4190252 > It helps me to remember that in Smalltalk the idea was to always have <view|controller> pairs. They were always the same object split in two; each view had its own controller and vice versa. The controller is supposed to be input-oriented and the view is supposed to be output-oriented Another commenter here put it nicely: your “whole application” is the model. The view-controller pair over could be one for a terminal, or a website, or a desktop app, the model should be reusable. A controller isn’t, handling a click on something doesn’t make sense in a terminal.