12 ms·
The key to getting MVC correct is understanding what models are
- deleted 1y ago[deleted]
- pixelworm 1y agoI think nearly every definition of MVC I've read has been different. At this point it just means you split something into three classes as far as I can tell.
- cypherpunk666 1y agohttps://en.m.wikipedia.org/wiki/Trygve_Reenskaug https://en.m.wikipedia.org/wiki/Trygve_Reenskaug THE OG
- mpweiher 1y agoAnd here is the original paper: https://web.archive.org/web/20090424042645/http://heim.ifi.uio.no/~trygver/1979/mvc-2/1979-12-MVC.pdf https://web.archive.org/web/20090424042645/http://heim.ifi.u... Enjoy!
- andrewflnr 1y agoOh, I think I see the problem now. He doesn't want views to know anything about concrete inputs, but our modern GUIs are so closely connected to input that that's pretty much impossible. And really if you want to click on a sub element of a view, that's hardly avoidable. So modern Controllers can only do their most basic job with these Editor objects that are tightly bound to views, were supposed to be ephemeral, and that LITERALLY NO ONE TALKS ABOUT.
- mmahemoff 1y agoA major advantage of pure models is testability. If your conception of a "model" is perversely a user-facing widget, congratulations, you'll need to write UI tests that simulate button presses and other such user actions, and maybe even inspecting pixels to check resulting state. Tests like that are a pain to compose and are fragile since the UI tends to evolve quickly and may also be vulnerable to A-B experiments. Juice ain't worth the squeeze in most cases. In contrast, pure model components tend to evolve slowly, which justifies the investment of a comprehensive test suite which verifies things like data constraints, business logic, persistence. If automated testing were seen as a priority, this would be a no-brainer for any serious app. However, testing tends to be underappreciated in app development. This goes some way to explaining why frameworks carelessly fold in M, V, C to the same component.
- mikepurvis 1y agoYes to all of this with the provisos that a) there’s enough meat in terms of business logic and validation to justify the indirection of a separate object and b) you’re under a language or CI regime that can validate the boundary between the two classes for basic flubs like function misnames or bad arguments.
- andrewflnr 1y ago> If your conception of a "model" is perversely a user-facing widget Do people really do this? That's mind-numbing.
- RossBencina 1y agoI don't think people called it a "model" but back in Windows VisualBasic/Delphi/C++Builder days the path of least resistance was to set up your GUI in a visual editor by laying out all your widgets in the window. Classically Qt can also be used this way. So you have this UI, you can launch the application and the UI displays and basically works, but none of the buttons do anything. But all the widgets have a great API that you can use to set permissible value ranges, set and query state, etc. And the widgets would fire events when things changed. In other words, the widget contains a model, and implements the Observer design pattern. If you wanted to implement MVC with a separate application data model you had to do work to set up a separate model, and keep it in sync with the UI. None of this class of old tools provided any built-in assistance for defining models separate from Widgets, except for some support for binding UI to database queries/results. Of course this was separate from the Smalltalk world, where there were frameworks for building up models out of pre-defined model "atoms" such as an observable number model that you could bind to various views.
- hackrmn 1y agoTesting by "simulating" button presses and other actions like that, including inspecting pixels, is part of so-called "black-box" testing, and offers merit(s) of its own. At least because software is used by people who click buttons which may modify pixels, and these people are not concerned what your model is, they don't even know anything about the way you may have implemented the latter. In the end everything is run on a fairly RISC-y CPU, it either works or it doesn't (from user's perspective) -- replicating the user's workflow is useful in that it it uncovers issues that matter to users and thus normally affect your bottomline.
- gundmc 1y agoGetting totally lost in several different enterprise software implementations of MVC was a major contributor to my impostor syndrome early in my career. Glad to have some sort of vindication that I wasn't alone
- whstl 1y agoThis problem that MVC has is similar to the problem with OOP itself, with monads, or with some design patterns: the original/popular definitions were so incredibly abstract and disconnected from real life usage that they ended up being whatever the person implementing it wanted it to be. And then, 10, 20 years after the fact, people will start attacking popular implementations that differ from the original using some "new canonic interpretation" that is either extremely recent, or an interpretation that is old but was lost in time. This is especially common around Smalltalk and OOP for some reason. Smalltalk's OOP is nothing like what existed either before or after, but since Alan Kay invented the term, Smalltalk is weaponised against C++/Java-style OOP. Not that C++/Java OOP is the bees knees, but at least their definition is teachable and copyable. Design patterns suffer because in most explanations the context is completely missing. Patterns are totally useless outside very specific contexts. "Why the hell do I need a factory when I can use new"? Well, the whole point is that in some frameworks you don't want to use new Whatever, you dummy. If only this was more than a two-sentence blurb in the DDD book (and the original patterns book totally glosses over this, for almost all patterns). And monads became the comical case, because they are totally okay in Haskell, but once it gets "explained" and migrated to other languages they become this convoluted mostly useless abstraction at best, footgun at worst (thinking of the Ruby one here).
- deleted 1y ago[deleted]
- aryehof 1y ago> Smalltalk's OOP is nothing like what existed either before or after, but since Alan Kay invented the term. Rubbish. In terms of OO language constructs, Smalltalk is almost entirely derived from Simula. Let’s not revise history.
- to11mtm 1y agoIDK I think it's still worth considering where certain languages 'got the right things right together' to be constructive... That said as someone fairly unfamiliar with Smalltalk I'd like an example of what other parts of Smalltalk play well with it's OOP Sauce...
- lukasb 1y agoAny implementation of MVC I've seen the V and the C are so tightly coupled the separation seemed artificial. Skill issue?
- andrewflnr 1y agoYeah, it's really hard to tease them apart in a GUI sort of environment, since the input is so tightly tied to the graphical view. Model and View have always seemed pretty obvious to me but I've never gotten a compelling answer as to what a controller is. My best guess from this article, given then "associated by observer" link from View to Controller, is that the View is supposed to pass events to the Controller, which will interpret them into changes to the Model. But what's the format of these events that's both meaningfully separate from the View, e.g. could be emitted from different views to maybe different controllers, but doesn't just force the View to do most of the work we want the Controller to do?
- to11mtm 1y agoAt least in my head, the 'controller' is what can either take 0 or more parameters or input models as 'input' and the controller can either provide direction to the browser as to what to do next. e.x. in a 'proper' ASP.NET MVC 4 project I 'inherited', the View took input data in and with a tiny bit of JS magic/razor fuckery around the query page etc, but overall the controllers would return the right hints for the Razor/JS 'view' to move the application flow along or otherwise do a proper reload.
- grugagag 1y agoIn ASP.NET MVC is a modified version of classical MVC adapted for the web. The Controller in ASP.NET MVC takes on the role of both the classic Controller and part of the classic Model's role (orchestrating the retrieval/updating of data). The connection between the View and the Model is completely severed and mediated by the Controller.
- to11mtm 1y ago
- mkoubaa 1y agoThe reason MVC got so abused was because of RAD frameworks: rapid application development. Most of this started with visual basic. Basically, the thinking was to let the programmer design the view and then implement the code-behind. I'll spare you from my rants about this, but it was popular. Nowadays, with vibe coding, there is no need to use obtuse design patterns for the sake of RAD. Sensible architectures can easily by used by LLMs without sacrificing engineer or designer agility.
- b_e_n_t_o_n 1y agoI feel like MVC is trying to get at a core concept of having your application state in one place, your view objects/state in another place, and then having a third piece that updates the application state. So like in React, you'd have your Redux store as the Model, React components (with useState etc) as the View, and then your Controller is the reducer which is called from UI code and updates the Model. Maybe that's incorrect definitionally, but it makes sense to me.
- js8 1y agoThat's what I call "single vortex principle". The graph of data dependencies (flow of updates) in your application should ideally have only one circle (which includes the user). The minimal circles of data dependencies are what I call "vortices". Every time you have two different vortices in your application, a potential ambiguity arises about sequencing the updates. These are difficult to deal with and can cause bugs. As you say, in MVC, the vortex should be User -> Controller -> Model -> View -> User. Best if this is the only vortex (Flux pattern). This can be nicely expressed functionally. That's why I think beans (and mutable variables in general) are bad because each has it's own small vortex of updates.
- jerf 1y agoOne of the other markers of "true MVC" I look for is that you ought to have pervasive mixing and matching of the pieces. It is common for models to see some reuse in multiple "views" and "controllers", but if all or almost all of your controllers match up to precisely one view, then you're burning design budget on a distinction that is buying you nothing. If you've got strictly one-to-one-to-one matches for each model, view, and controller, then you're just setting your design budget on fire. Another major aspect of the original "true" MVC is multiple simultaneous views on to the same model, e.g., a CAD program with two completely live views on the same object, instantly reflecting changes made in one view in the other. In this case MVC is less "good idea" than "table stakes". I agree that MVC has fuzzed out into a useless term, but if the original is to be recovered and turned into something useful, the key is not to focus on the solution so much as the problem. Are you writing something like a CAD program with rich simultaneous editing? Then you probably have MVC whether you like it or realize it or not. The farther you get from that, the less you probably have it... and most supposed uses of it I see are pretty far from that.
- catlifeonmars 1y ago> if all or almost all of your controllers match up to precisely one view, then you're burning design budget on a distinction that is buying you nothing. This is a really insightful way to frame it.
- kqr 1y agoOooh. Now I get it. I've been dismissive of MVC for nearly as long as I've known it but I realise I've only seen the bad versions. What you describe as correct sounds much more sensible.
- skydhash 1y ago> If you've got strictly one-to-one-to-one matches for each model, view, and controller, then you're just setting your design budget on fire. That's sensible. But it's generally useful to split your core state from your presentation, and then you'll find strands of logic that belongs to neither, generally glue code, but some can be useful enough to warrant a module of their own. Also your core state can be alien from the view itself (think a game data (invisible walls, sound objects) and the actual rendering). Maybe this architecture is not MVC, but MVC can be a first stab for a quick and dirty separation. Then once a cleaner separation can be done by isolating specific modules (in layers, graph, whatever)
- aryehof 1y agoThis perpetuates the myth that a model is an object. One object. This has lead to todays common misconception that a model is one anaemic data-bucket representing typically a database table. Instead a model is one or more collaborating objects.
- hansvm 1y agoAnd what do you call the Model object holding those collaborating objects? Is that not still one object? The article explicitly supports your position that models can be complicated (see the paragraph starting with "to support more complex views").
- mpweiher 1y agoI actually find it useful to have the Model represented by a single object, usually a facade that coordinates all the other Model objects. Not sure why this would lead to anemic models, which I completely agree are a common anti-pattern. In fact, to me it seems rather the opposite would be true: having the single object facade facilitates having a complex model that coordinates all the different pieces to represent a unified view of said model to the views, which can then be very simple and transparent. In turn, when the models were coupled with views individually, that has tended to lead to exactly that View → DB Table mapping of dumb data objects you rightly criticize.
- globular-toast 1y ago"Model" is an overloaded term. In Domain-Driven Design there is the domain model at the centre of the application. One model consisting of many classes (entities and value objects), functions etc. Then there's the ORM thing, particularly active record ORMs, where "a model" means a database table. And things like serialisation libraries (e.g. Pydantic) where "a model" is one type. Something that changed how I thought of it was in Robert Martin's Clean Code where the says the whole MVC lives in the outer layers of the application. So basically, "model" is context specific. It depends what part of your application you're talking about. MVC is about building GUIs, that's it. An application usually consists of a lot more.
- 1y ago
- travisgriggs 1y agoAs a former and long smalltalker who learned MVC from the ParcPlace crowd… I used to say things like this. M and V were always pretty unambiguous, but “controller” was kind of like “Christianity”, everyone talks like it’s a unifying thing, but then ends up having their very own thoughts about what exactly it is, and they’re wildly divergent. One of the early ParcPlace engineers lamented that while MVC was cool, you always needed this thing at the top, where it all “came together” and the rules/distinctions got squishy. He called it the GluePuppy object. Every Ux kit I’ve played with over the years regardless of the currently in vogue lets-use-the-call-tree-to-mirror-the-view-tree, yesteryears MVVM, MVC, MVP, etc, always ends up with GluePuppy entities in them. While on the subject, it would be remiss to not hat tip James Depseys MVC song at WWDC https://youtu.be/kYJmTUPrVuI?feature=shared https://youtu.be/kYJmTUPrVuI?feature=shared “Mad props to the Smalltalk Crew” at 4:18, even though he’d just sung about a controller layer in cocoa that was what the dependency/events layers did in various smalltalks.
- neilv 1y agoController seemed fairly straightforward to me initially, when I was first learning Smalltalk (ParcPlace), and I took my simple understanding on faith. My programs were simple, so M was data, V was presentations of the data, C was interaction on the M and maybe V. It only got confusing when I got more experience.
- travisgriggs 1y agoWhere “interaction” meant user interaction.
- mpweiher 1y ago> so M was data, M is the Model. That means the data and all the things you might ever want to do with the data. So any interaction you might want to do from the view is (ideally) a single message-send to the model. > V was presentations of the data And editing the data. > C was interaction on the M and maybe V. > It only got confusing when I got more experience. :-)
- mpweiher 1y ago
- deleted 1y ago[deleted]
- jpalomaki 1y agoIt would be interesting to read a case study of how the MVC was applied in some larger SmallTalk app.
- mpweiher 1y agoMy BlackBird reference architecture was inspired by a bunch of real world apps in Objective-C, which isn't Smalltalk but close enough for these purposes. https://blog.metaobject.com/2022/06/blackbird-simple-reference-architecture.html https://blog.metaobject.com/2022/06/blackbird-simple-referen...
- samtheprogram 1y ago> For example, in ObjC an int is an object, but it is not observable. However, an ObjC object with an int property is observable using Key-Value Observing I haven't written Objective-C in a decade or so, but isn't this a pretty big mischaracterization of the language? NSInteger is a typedef to a C type IIRC, while there's NSNumber for the cases you want an object and/or are deserializing -- and which has observable propeties?
- adityaathalye 1y agoI used to be very confused about MVC and MVCC and what have you---I can't keep design patterns straight in my head (personal limitation)---I finally went down a rabbit hole of trying to figure it out from scratch. Like, why do we even need any of that stuff? I blogged about it [1] and spoke about it [2] and the post even got some HN love [3]. The opening parable concludes with this... Multitudes of sworn "Rails developer"s, "Laravel developer"s, "Django developer"s, "Next.js developer"s and suchlike throng the universe… Why? ... ... Once upon a time, there was one. WebObjects. Now they are numberless. The occasional email and DM gives me succour that I am not alone in my confusion. Even people who've "grown up" using traditional MVC frameworks took a minute to self-check and felt "huh, looks like I can look harder at this thing that I do". Clojuring the web application stack: Meditation One [1] blogged: https://www.evalapply.org/posts/clojure-web-app-from-scratch/index.html https://www.evalapply.org/posts/clojure-web-app-from-scratch... [2] talked: https://www.youtube.com/watch?v=YEHVEId-utY&list=PLG4-zNACPCsNVwz3ohXKeoeQjRLoFsc7F&index=2 https://www.youtube.com/watch?v=YEHVEId-utY&list=PLG4-zNACPC... deck: https://www.evalapply.org/posts/clojure-web-app-from-scratch/deck.html https://www.evalapply.org/posts/clojure-web-app-from-scratch... source: https://github.com/adityaathalye/clojure-multiproject-example/tree/master/projects/fnconf2025 https://github.com/adityaathalye/clojure-multiproject-exampl... [3] discussed: https://news.ycombinator.com/item?id=44041255 https://news.ycombinator.com/item?id=44041255 165 points by adityaathalye 3 months ago | 39 comments
- zkmon 1y agoIt was basically the 3-tier architecture hijacked by some authors with hyper sales-pitch who messed it up beyond recognition. The 3-tier model has 3 simple layers - Data, Business, Front-end. The MVC inventors called data as "Model" - I could not get my head around this weird naming. What does "Model" mean in plain English? And why do you need those dotted lines between Front-end and Data layers bypassing the Business layer? MVC is a fake that lasted for decades.
- mjevans 1y agoIt makes so much more sense in that light. It was __sold__ not to programmers, but to NON programmers. The model is the underlying shape (the data in storage). The Controller is like the security guard for the warehouse / building. The View is what's presented to external clients (end users).
- anon7725 1y agoMVC came from desktop applications. It was later repurposed to client-server apps when the web arrived, but it was always an impedance mismatch. In desktop GUI apps, the delineation is much crisper: the model is the data that the application manages (the CAD geometry, the document, etc). The view is one or more renderings of the data to screen, and the controller is the input and command processor that updates both the model and the view. Storage is not central to this architecture - it exists, of course, but it’s not really described as part of these core relationships.
- dragonwriter 1y agoThat’s a nice story, but completely ahistorical; MVC was not originally a distributed architecture but an architecture for local desktop GUI apps. While it was later applied to client/server apps, that isn’t its origin (and even in that context it was never equivalent to the 3-tier model, which you can easily note by all three of M, V, and C being represented by backend components in web frameworks like Rails—the View being the backend component that renders what is sent to the frontend in that version.)
- avodonosov 1y agoEveryone knows what model is. Almost noone knows what is controller.
- mpweiher 1y agoLargely agreed, I wrote about the confusion around 10 years ago[1] and wrote 2 years later about the problem of concept capture we have with MVC[2] : I'd like to add a couple of points to TFA. Yes, it is absolutely paramount to understand what the model is. It is the abstract representation of the domain. The rest of the architecture serves the model and should be as minimal and transparent as possible. Particularly Apple-space code tends to get this very wrong by having very thin models and all the logic in the Massive View Controllers. It is also important to understand that MVC is not about specific objects, but rather about roles and communication patterns. Different objects can have those roles, and they can actually be usefully combined at times (though do keep the model separate, please). One crucial part of the communication patterns that TFA duly notes is that models do not know about views. That means that views only ever pull data from models, models never push data towards views. It also means that in an update, the model just says "I have changed". It does not send the data that changed. The "the model changed" notifications is also the only reason a view gets updated. No, the controller doesn't poke the correct updated data into the view after it has notified the model, that leads to update chains and cycles. IIRC, that was one of the problems that React was trying to solve with "MVC", except it turns out that actual MVC never had those problems in the first place. Mis-application of MVC does. Having the view always update itself from the model means that view state is always consistent, even if you miss or skip intermediate updates. Skipping intermediate view updates is important, because the model can potentially change a lot faster than the view can update, never mind the user processing those view updates. Also, one common misunderstanding (that also leads to Massive View Controllers) is the mistaken belief that views must not edit models, that you must have a controller to edit it. That is actually not in the original MVC paper[3]. In the original paper, views can edit models and that makes things a lot more sensible. Controllers are a bit of a catch-all for stuff that didn't fit anywhere else. The Views in Cocoa actually take over some of those roles, and that works absolutely fine. (Imagine my confusion when ViewControllers were introduced...) [1] https://blog.metaobject.com/2015/04/model-widget-controller-mwc-aka-apple.html https://blog.metaobject.com/2015/04/model-widget-controller-... [2] https://blog.metaobject.com/2017/03/concept-shadowing-and-capture-in-mvc.html https://blog.metaobject.com/2017/03/concept-shadowing-and-ca... [3] https://web.archive.org/web/20090424042645/http://heim.ifi.uio.no/~trygver/1979/mvc-2/1979-12-MVC.pdf https://web.archive.org/web/20090424042645/http://heim.ifi.u...
- rubymamis 1y agoI think what Qt is doing with the Model being written in C++ and notifying to a QML View using Signals & Slots is the best way to do it.
- ahartmetz 1y agoIn Qt, have found that it's often best (much less and simpler code) to have simple editing actions right in the model, which has the data available anyway. The distinction between model and controller buys you nothing but a lot of extra code and complication in such cases. As someone mentioned in another thread, a separate controller starts to make sense if there are several views or views + other parts that somehow access (some of) the same data. Qt model-view initially didn't even involve QML by the way, and QTreeView etc still exist for the classic desktop look and feature set. I don't use them much anymore neither, but that's because I mostly do embedded stuff. I wouldn't want my e-mail client or text editor to be written in QML though.
- rubymamis 1y agoFirst off, I've built a block editor (which is also a text editor) in QML. I wrote about it extensively[1]. It was an amazing developer experience, I enjoyed every bit of it. > In Qt, have found that it's often best (much less and simpler code) to have simple editing actions right in the model, which has the data available anyway. I believe that's also what I'm doing. [1] https://rubymamistvalove.com/block-editor https://rubymamistvalove.com/block-editor
- sureglymop 1y agoThis doesn't just apply to MVC but also for example the Elm architecture. The thing is that they are quite simple in theory but in practice, programming them from scratch can be much more difficult, mostly due to the View. For example, what if you have two widgets that need to be side by side? And the user needs the ability to use the keyboard to switch between them? What if now you have a third widget below them that is also tabbed? At this point you need a state machine to track the state and where the user is currently at. It's easy if this is done for you but pretty difficult otherwise in either architecture.
- indigodiddy 1y ago[flagged]
- cheschire 1y agoMeh, I disagree. Models can represent data stores, models can represent data views, and models can be for data transfer. This is necessary for zero trust in application design. Traditionalists really seem to struggle with this shift in mentality that, when you are designing a system, trust is where the problems come from. Just as an example, collecting date inputs from a user might be three different fields in the view model and only one field in the data model, and be completely different data types (int vs datetime). If you are working with a client side application then you may not want to pass the entire object to the client because you don’t trust them with all the information, and you cannot trust them to maintain state, so you only transfer the date value in a data transfer object. These are all models with wildly different intents. If you can’t understand the intent of this separation of concerns then you are designing insecure systems.
- frollogaston 1y agoIt's trust and also org chart. One team will make one service, two teams will probably make two.
- ChrisMarshallNY 1y agoEh. I’ve been writing Apple software for a long time (since 1986). Most of that time, it’s been some pattern that resembles MVC, and almost all was OOP (in a few different languages). UIKit is explicitly designed for MVC. If you want to write the most concise, performant, maintainable, UIKit code, you do so, using MVC, and classic OOP. I have tried other models, but they end up as messy kludges. SwiftUI was designed to be more flexible, and can employ other patterns. I find that OOP is sometimes useful (especially for things like observable models), but there’s no reason not to do it, using other methods. It doesn’t force you to use anything in particular. The main issue with SwiftUI, is that it’s still quite “unripe,” and we are limited in what we can do with it. I am looking forward to this changing, over time (it’s already improved, quite a bit). Time will tell, whether or not it can completely replace UIKit. I haven’t really been able to use it for any of my shipping projects, yet. I know of a number of apps that have, but I’ve been unwilling to make the compromises necessary, to do it, myself. Some tools were designed to be used in certain ways, and coercing them into methodologies for which they weren’t designed, can result in a mess. If I want to bang nails into a board, a hammer is the best tool. I have banged nails in the past, by flipping a screwdriver around, and using the handle, but that damages the screwdriver, and doesn’t work especially well. But maybe a nail isn’t the best way to join the boards. If I use screws, then the join will be much better. In that case, the proper tool is a screwdriver. I guess I could still use a hammer, but the results are unlikely to be satisfactory.
- twelvedogs 1y agoMVC always seemed fucking pointless to me, like shit code isn't gonna get good if you put it in boxes
- kybernetikos 1y agoI've become convinced that the real problem is probably impossible to get away from. Ultimately we want a nice set of reusable UI components that can be used in many different situations. We also want a nice set of business logic components that don't have any kind of coupling with the way they get represented. In order to make this work, we're going to need some code to connect the two, whether it's a 'controller' or a 'view model' or some other piece of code or architecture. However we choose to achieve this task, it's going to feel ugly. It's necessarily the interface between two entirely different worlds, and it's going to have to delve into the specifics of the different sides. It's not going to be the nice clean reusable code that developers like to write. It's going to be ugly plumbing, coupled code that we are trying to sweep into one part of the codebase so that we can keep the rest of it beautiful.
- vbezhenar 1y agoSounds like very simple task to solve. You have Table component. You have TableData interface. Table component asks TableData interface for data to show. You have TableCallback interface. When user interacts with Table, like click or whatever actions are implemented, TableCallback methods are called. When you want to use Table with your data, you implement TableData and TableCallback for your data. That's about it. I've seen this approach implemented in most UI frameworks. You might rename TableData to TableModel or whatever, but essentially that's it.
- kybernetikos 1y agoI'm not saying it's not simple to write, I'm saying it's ugly and contingent and you can't really avoid that. It's exactly this reason that has led to a proliferation of MV* patterns, including the one you describe. But to try to explain myself more clearly - in the architecture you describe, who is that it is implementing TableData and TableCallback? Is it your beautiful clean business logic classes that have no coupling to their representation - in which case that is weirdly coupled in an ugly way, or is it some other class that acts as the bridge between the two worlds, in which case, that's where your ugly code is living.
- frollogaston 1y agoLast time I cared about MVC was AP Computer Science. Model is fine, but there's no reason for view vs controller. The UIView vs UIViewController thing in ObjC/Swift was one example of the silliness, something for devs to waste time arguing over. React (Native) refreshingly had no such thing. Angular was all about MVC, but they recently slimmed it down. Also, a while back it was way less common for UIs to have backend services. Nowadays those have taken away most of the "model" side in a lot of apps.
- bsaul 1y agoafter 15 years refactoring poorly designed iOS apps i can guarantee you 100% of the problems come from an insufficiently designed model layer. Apple is to blame, as they give absolutely O clue on that part (only demo apps with structures that don’t scale)
- ednite 1y agoI’m still an MVC fan, thanks in no small part to Scott Allen’s teaching (RIP). I agree that if controllers stay tiny and boring, your model stays rich and your app stays portable, testable, and easier to evolve. If you’re learning MVC, Scott’s OdeToCode/Pluralsight material still nails the fundamentals and the why behind them.
- cheschire 1y agoThe man that taught me C#. I had no idea he passed. Thanks for sharing this!
- izackp 1y agoHi, I've been making iOS apps for over 10 years now. I've experimented with many different styles, and even started doing android and web development. One thing I learned is that every abstraction or indirection makes things slightly harder to read and debug. Observers seem to have been a solution to 'callback hell' before async was a thing. However, it's rife with pitfalls. With Observers: We have hidden control-flow and lost intent. They subvert the readability of the developer's intention, in some cases they make you lose the callstack, and it has you searching the project on what code modifies a variable which is a lot harder than searching for a function call. Don't get me started on dealing with handling errors and out of order events. And oh man, is it easy to just avoid using encapsulation and creating a good interface/api for your piece of code. Most of your code isn't re-usuable as you think: A lot of things are naturally and forever tied together. Your UI is a reflection of _some_ model, The actions it can perform is based on it's current context, and if your UI changes then your business logic and model probably changes as well. This die hard need of separation and modularity only increases the complexity of the code with the majority of times the code not even being reused. The only case that I've found somewhat reasonable to use observers is the database. What caused the database to change and effect it has is already pretty far removed from each other when a piece of UI needs to reflect the database. Granted, It's possible to work around some of these issues, but please please I'm tired of debugging why a menu only opens 50% of the time because there is a piece of code several classes away from the context that doesn't fire correctly and looks like if (child.preferred.child.model.somethingElse.isFinished) { child.menu.child.openMenu = true }
- layer8 1y agoWhat I find confusing about the Smalltalk diagram of MVC is that the view can update itself from the model without help from the controller (and without the controller even necessarily being aware of it), but updates to the model based on view events apparently have to go through the controller. This raises the question of why if the view is capable of reading the model on its own, it is not likewise capable of modifying it, and/or conversely, if the controller is used to customize how the model is updated based on view events, why it can’t also be used to customize how the view updates itself from the model. What would make more sense to me is to simply define the controller as an intermediary between model and view for updates in both directions. The controller would simply represent whatever needs to be specific to the particular combination of model and view in the particular application context. Depending on context, you might use a no-op controller when no customization is needed, as in the example of the article where a checkbox (view) is bound to a boolean property (model).
- cpburns2009 1y agoThis is exactly how I conceptualize and use "MVC". The controller mediates all communication between the view and model, and in fact drives everything.
- Marazan 1y agoI will never get tired of MVC holy wars. A hundred people with their own clearly self-evident truth as to whether models are thin or fat. Absolute burning certainty as to where validation logic lives. And maybe 3 or even as many as 4 mad hermits who claim to understand what a Controller is.
- PaulHoule 1y agoOn the web there is a lot of confusion about "MVC" in that the heart of it is not the model, it is rather having the controller (router) which is able to look at the URL, form parameters and such and decide which view to show you. This is in contrast to the 1990s model of web programming where you wrote an HTML page with a <form>, pointed the action to some URL, and that URL was a cgi-script that couldn't redraw the form so error handling was difficult. In a lot of cases you could say the data fetching is a dependency of the view and not the other way around, for instance if it is a blog post you might have a model object for the actual blog post but then want to put arbitrary widgets into the view which in turn requires fetching whatever model objects are necessary to draw the widgets. From the viewpoint of a CMS user, for instance, they want to drop the widget into the template and have it "just work" (have the framework figure out the fetching.) The first exposure a lot of people had to this paradigm was Ruby-on-Rails and since it had a rich model system people thought the model system was the important bit but I'd say the router is the most important bit and how you fetch the data and format it is secondary, in fact it's totally fair to use different fetching and templating paradigms for different pages that live under the same router.