MVC is dead, it's time to MOVE on (2012)
cirw.in
cirw.in
The controller should have and only have logic which absolutely cannot be moved to a service layer.
Too many developers use controllers as part of their logic layer, instead of simply using it as a router for where models should be directed on a service level.
After people realise that the controller is actually the plumbing that just connects stuff, you can easily use MVC with services as described on the Eric Evans book for example and your codebase gets neatly organised, modular and testable.
You can tell that this is happening because there is a 1:1 mapping between foos_controller and views/foo.
There's nothing wrong with MV code and it's a great paradigm for a simple app. But lots of rails apps are no longer simple...
Rails has done so much to move application development forward, but if I had two nits to pick, they are the same today as they were in 2007:
1. Assuming/requiring a folder structure named after the pattern an object fits, rather than conceptual domains of an application.
2. Naming its templates "views", and not hinting to people that presentational logic should belongs in a full instance of a class, rather than in-line in template code. Partials help but insufficiently, and helpers have too many gotchas.
The sprawl of gems that attempt to address #2 this is evidence of its impact. While I appreciate the "omakase" argument, it still leads a lot of smaller or less-experienced teams to make a big mess before realizing they have better options.
Anyway, as often as I see "service objects" solutions helping a team tame their Model-View-Mess, just as often I see the solution lying in adding an actual View layer (or adding Presenters if that fits better).
I like ActiveRecord, ActiveRecord::Relation, ActiveSupport, and all the other things people tend to gripe about in Rails-land, but the specific folder structure has always been a stick in my craw.
It's possible to implement a proper separation of concerns and clean architecture using Active* modules, but Rails actively encourages bad design. I still like Ruby, and there's a lot of good software within the Rails ecosystem, but Rails itself is poorly-architected and encourages bad design.
How you achieve this depends upon the language. One thing I like to do in statically typed object oriented languages is to use classes for basic data rather than spread primitives everywhere. This makes it obvious where to put validation - e.g. the PhoneNumber class in the model will necessarily ensure the data its passed isn't bad. Repeating that logic in a controller or view tends to be a poor decision.
Seems kind of a stretch to come up with a distinct name for such an elementary software design concept. Just like I think it would be silly to call the helper functions I write for my view layer "ViewServices", and then act like its some novel thing that the newbies aren't doing enough of.
There should be a real separation of concerns/division of responsibility.
So the direct controller "only" coordinates the model, view, and services. I put it in quotes because there's still a lot in there (which should be organized as well): changes coming from the model, UI events from the views, and events from each of the services involved.
Well, I guess you can call all of that DRYing, but it is definitely a deeper activity than just factoring out repeated code. There's real design to be done, to determine what the key concerns are exactly and how they compose to form your app.
(Put another way: you can superficially factor out repeated code and still end up with a soup of interconnected services, controllers, models and views with a variety of communication mechanisms between them.)
If you come across the doc I’d be happy to read it.
I believe Trygve Reenskaug (the inventor of MVC) would agree with this point. After MVC he went on to invent "Data, Context, Interaction" (DCI) [0], which aligns with what you're describing.
[0] https://en.wikipedia.org/wiki/Data,_context_and_interaction
But yes your comment makes sense. It also applies to the react world, where I have seen many apps with a ton of logic inside the lifecycle methods of react components. Lifecycle methods are the new controllers.
1) Avoids bloating model objects.
2) Avoids creating complicated controllers.
3) Makes it much easier to move to a microservices architecture when the time comes, because business logic has already been grouped into isolated components.
https://multithreaded.stitchfix.com/blog/2015/06/02/anatomy-...
https://www.toptal.com/ruby-on-rails/rails-service-objects-t...
Just chopping up every single part (even table view cells) into view controllers made everything so simple that not only Controllers are super thin and dumb but also ViewModels remain really thin, but not to the point where they start feeling like a unnecessary abstraction.
Making a split between "more like a View" ViewControllers and UI code free ViewModels really helps, but I guess it's also the dirtiness of UIKit MVC that kind of forces you to abandon the ViewController.
I've seen lots of people fail to separate that code in a clean and extensible manner. The result is a still-fat layer that's split across a bunch of different files and methods. But every piece is still concerned with almost every piece of context that was originally passed into the controller.
Composability and separation of concerns are the answer, but it's much more of an art than something I've ever seen a simple tutorial for. It's gonna look different for different business cases.
Conway's Law rules. We need constructs that easily help us fit the stack to our teams and shop conventions. MVC allowed a shop to throw masses of people and code at a problem instead of removing the need for masses of people and code.
The web made a mess out of CRUD app programming and MVC was a first step in taming the mess, but it requires fat staffing and lots of specialists to manage the screwy parts.
Sorry, which letter in MVC is the "service layer"?
One of the reasons I don't buy into MVC is that MVC doesn't mean anything any more, and hasn't ever since the web people got their hands on it. If you ask ten developers what MVC is and get 13 different answers (see half the sibling replies to this comment), well, that's not itself a problem, but it does mean that running around telling people that they should or should not do "MVC" has been pointless for a long time.
I still like MVC for its original purpose: Multiple views in a CAD/CAM program. Makes perfect sense there. I don't think I've yet seen a place where it belongs other than that, though.
One of my major objections to the concept is the way people think good design == MVC and MVC == good design. I could describe to you my architecture, but then someone stuck in the MVC mindset would see my discussion of how the UI controls will drive the map object, and say "AH HA! Aren't you saying that the map is a View and the UI controls are the Controller?" To which my reply is, if MVC describes everything, and you can squeeze anything into it if you squint hard enough, it describes nothing, because that makes everything "MVC" and therefore you can't distinguish the quality of a design by whether it is or is not MVC if everything is MVC.
On the other hand, if MVC isn't everything, but is in fact a very precisely specified combination of OO patterns, then no, my Google maps design would not be MVC, because I would not use the MVC patterns as my guideline in the slightest and the odds the resulting design would happen to conform to the strict definition by the end of the project approach 0, even if you could pick out bits and pieces that sort of seem to resemble it sometimes kinda sorta. I don't "avoid" models, views, or controllers, but I never chase them.
Your question, sarcasm and all, makes no sense and either reflects bad faith or ignorance. The model in MVC is the model, even if it depends on the service layer or not. Design patterns describe components with respect to their roles, and the fact that the concept of service is not necessary to explain the design pattern that does not mean it should be in the acronym. In fact, models are quite obviously wrappers around repositories/gateways/services/etc etc etc. The reason behind this, obviously, is that if your goal is to simply provide a UI then it makes absolutely no sense to drag or leak the application or service layer into the interface. You just add an adapter to the repositories/gateways/services and then use that adapter to input and output the data you need to be in the UI.
> One of the reasons I don't buy into MVC is that MVC doesn't mean anything any more,
That cop-out doesn't cut it. MVC is well documented, and objectively defined. Just because some people either ignore its meaning or get a bit "creative" with their personal definition (I'm looking at you, Qt) it doesn't mean there is no concrete definition, or that you have any excuse to criticise something you don't know.
I'm skeptical. Do you have a link or quote of the "official" definition so we can critique it?
http://www.math.sfedu.ru/smalltalk/gui/mvc.pdf
The pattern is known for having been made popular by Smalltalk. In the 1980s. It makes no sense to assume that a design pattern that has been widely used for, say, 40 years is somehow not described.
As Martin Fowler says[1] in his a GUI architecture overview:
"As Smalltalk developed in the 80's and 90's this led to some significant variations on the classic MVC model. Indeed one could almost say that MVC disappeared, if you consider the view/controller separation to be an essential part of MVC - which the name does imply."
In that case, almost nothing called MVC is MVC. For one thing, MVC has no network component to it, so anything involving client/server is automatically not using MVC, which immediately whacks what appears to be 90% of the claimed uses to me. A network layer is too important to the design of a program to just slip it in between one of the M-V or V-C or M-C layers as if it's no big deal.
I also personally consider it a critical component of MVC that it is the normal case that there are many-to-many relationships between all of the components, because otherwise, the pattern is pointlessly complicated for no gain. But it's very normal to have MVC where almost all, if not simply, all of the VC relationships are 1-to-1. You don't really have "MVC" if you have multiply-used models, but the VC element is degenerate in every use. It isn't particularly uncommon to have 1-to-1 relationships between the models either, although it is certainly the case that the models are most often reused. But then you just have data objects, not "MVC".
MVC works in CAD/CAM and similar situations, and is somewhere between "uselessly complicated" to "nonfunctional" in almost every other use case it has been ported to. (Jamming it in where it isn't necessary may "work", but is hardly a win for the pattern. Having "M" is not enough to have MVC.) Or, the term has stretched to the point where it's just useless.
Yes, many times, in many mutually incompatible ways.
> models are quite obviously wrappers around repositories/gateways/services/etc
You can add other layers and frameworks in addition to using MVC. That doesn't mean MVC is pointless.
It's quite possible, I would think, to define an entire application in terms of Models, Views, Operations and Events.
I'd have to try it for awhile to determine if it's a good idea. It's pretty compelling however. I may give this a spin next time it comes up.
And "Events" is essentially Controller code.
(There might be an argument that this describes a "fat" model vs some devs/frameworks choosing "thin" models that are just state rather than state + logic. )
Operations is pretty much a rebranded Controller, here. But it's a good rebranding! I've seen Controllers turn into a "God class" too many times, where you end up with big lumps that do more-or-less everything.
Or, what's closer to the original paradigm, you have one Controller per Model, but that's the thing: a given action will routinely involve two or more models. Do you put a bit of persistence logic in the User Controller or the Session Controller?
Thinking in terms of Operations should encourage small classes that each do one thing, and follow their own logic, not View logic or Model logic.
And having everything communicate through well-defined Events is great, this would make it much easier to add additional sources and sinks by reusing an already-established Event with a new Operation.
The more I think about it the more I like it.
But the topic is MVC not some particular application. I think jerf's point is that it's weird to say that a service layer is an important part of working with MVC when it's not even part of the same idea. Your statement here confirms that.
One can be talking about an expansion of the idea of MVC as if it were MVC itself, but that just proves jerf's point, too, about MVC being meaningless.
A Model View Repository Controller Service framework!
Sometimes a whole application looks to be done in an MVC style; in those cases, the "application"—i.e. all the business-logic mechanism, though not necessarily all the policy controlling it—is probably some upstream thing written by a third party (e.g. someone else's API; someone else's DBMS; someone else's game engine), and the repo consists entirely of your adapter for that application.
CRUD apps, of course, really are just a reshaping of an RDBMS's DML (INSERT, UPDATE, DELETE) API, so MVC (on top of an RDBMS) really is a 100% solution to CRUD problems.
That sounds intriguing. Could someone expand a little on it? Why is MVC more suitable for that particular problem?
The same pattern applies to MOVE. Events are data and operations should do nothing else than hand off to a service layer; if it's more than 1 or 2 lines of code, it probably is mixing concerns and should therefore be refactored. Otherwise you just moved the problem (bad pun, sorry) and made it even harder to test because now your business logic is a side effect of an event that is processed asynchronously.
Service layers are easy to test because it's just easily mockable constructor/initializer injected dependencies + a bunch of stateless functions that take input and produce output (and side effects). Classic mistakes here are to make the dependencies global variables and/or making the service layer initialization actually initialize dependencies.
There are a few frameworks that work this way, but many don't and developers have to constantly add caching layers to get anything done (and then spend tons more effort fixing cache invalidation well enough that nobody notices it's still broken)
And views for their presentation and models for their data abstraction? The horrors!!
To address another comment, MVC does not mean only MVC, it's just a framework that allows you to add layers where appropriate.
The most important thing is to separate concerns, and to agree on some sensible structure for managing views and state, and communicating between them. Usually the details of that should arise from the needs of the application, not come top-down from some idea about "the perfect application architecture". Aside from that, everything should just be kept as simple as possible.
IMO it actually adds a lot of unnecessary pain and complication to a project when a team is too rigid about which letter of an acronym each piece of code must fit into. VIPER would be an extreme example of this. It should not take five+ separate code files to execute an HTTP request and display the results in a list view.
The third thing can be a controller (true MVC), a presenter, a view-model, or, in the case of the article, operations and events.
The big deal with all this is that we have a view, usually provided by a UI framework, a model, usually provided by the app developer, and some kind of loose coupling. That's it, the good old idea of separating data from its representation.
What you stick between the model and the view is just an implementation detail of your particular framework, optimized for your particular use case.
It's not a pattern if it's not clearly identifiable as a pattern, MVC (original) applied to GUI interfaces. ASP.net tried to apply MVC to the web and it resulted in Webforms, which is true MVC, ASP.net MVC ironically isn't true MVC.
Like everything in IT MVC eventually became a buzzword thus lost all significance, that's why it doesn't really mean anything anymore since it doesn't describe anything specifically to most people who use the expression.
Well the article introduces weird new lingo which I don't think is all that great, but whatever.
"operations+events" can be equaled to "business logic". Let's keep that separated from the controllers. I want to create a new user via an http request, but I also want to do the same via a console command and since I want to do both things with the same code but one of these shouldn't be returning http status codes, it makes sense this should live in a different layer.
The whole events & operations separation in the article don't make sense to me. A "login attempt" as described in the article with a "login attempt" event being triggered by the view and that being picked by a decoupled "operation"? I don't see the value. If the operation needs to check privileges does it trigger an "check privileges" event, wait for another operation to complete? does that operation trigger another event to report the result? Wait a second... this sounds a lot like a convoluted Redux clone. Then you realize the only reason we are not doing Redux in the backend is because we are used to mutable state databases.
With Views, it seems to be easy for devs to understand that there is significant differences in the underlying approaches: are you organizing your views into page templates, serializing for some special client to consume, building components that compose one another, etc. I don't know why we can't wrap our heads around Controllers also having different approaches.
In my opinion, the mistake the OP makes is in not realizing that the dogmatic application of a design pattern is the fundamental issue to begin with.
So then the solution offered is another design pattern that can be dogmatically followed.
If we know that you need a UI (view), and we know that you need to represent your data in an expressive manner (model), and you need something to pull those things together for a user, a router and controller does not automatically come to mean “put all your logic here!” Instead, it means something more like “here’s where you can tie things together in whatever way makes the most sense for your application”, which lets you e.g., use AOP to handle auth (like Django decorators or middleware), delegation to a service like a REST API (e.g., Django REST Framework), or basic one-off views for simple tasks.
If something like this MOVE was to become the next big thing, I think there’s a good chance we’ll be rewriting a lot of projects to use MVC in 10 years.
Don’t blame bad code on a proven and very flexible design pattern that solves a very real problem. Blame bad code on bad coders.
That aside, lots of people in the web world have a sort of "Operation" layer in MVC but call them a "service". Deciding to use events is another architectural decision some people make even in web MVC.
But you can take or leave any piece of this stuff and I feel like you don't need a new acronym for every combination of architectural decisions.
But I Like Acronyms So Much.
Web "MVC" rarely was really MVC. Except that it changed the meaning of the term.
https://wiki.c2.com/?ModelViewControllerHistory https://wiki.c2.com/?WhatsaControllerAnyway
It seems you're mixing up implementation details with the actual design pattern. It makes no difference if you implement MVC with events or objects or imperative programming. The only thing that matters to a design pattern is the pattern, and the pattern is how three components interact to drive an user interface.
Model: The Javabean
View: The HTML
Controller: Whatever Java code that calls the service layers,
Service: The services in the lower layer,
JS: Since you have js with your HTML, then the JS also acts kind of like a controller for complex parts of the UI,
REST: Well that’s a second entry point to your service layer, to which the JS transmits Events (as in MOVE) that cannot be managed by a page reload. It’s a back channel unknown to the Controller.
So perhaps React has a point ;)
I am not sure we even got any implementation that is more convenient than event based UIs from a couple of decades ago. It does certainly looks like such implementations exist, they feel just within grasp, but there is a long way into "proven".
1. Any operation that changes the state the program is being used to manipulate should go to a single place and be fanned out to subscribers from there. 2. You want to be able to build compound views from simpler views and still treat them as the same kind of thing. 3. You want to be able to parameterize views over the behavior from interacting with them, e.g., you want to parameterize a button over what should happen when you press it, what its label should be, and if it is enabled.
You can do strict MVC in JavaScript just fine (https://github.com/madhadron/mvc_for_the_web). React has one major win that MVC can't give you: if you have lots of teams all putting things onto the same page, React controls the refresh loop so one team's code can't keep updating and destroy the performance of the whole page.
In fact, it is easier to list UI frameworks that are not MVC-based: WPF, which is based on MVVM and React+ReactRouter+Redux, which is based on Flux.
MVVM was invented in order to support 2-way data binding. Inspired by WPF, many early JavaScript frameworks supported 2-way data binding. These days 2-way data binding is widely acknowledged as a poor design as it makes it hard to keep track of how data is flowing through your application. For more on that see [1].
React was originally introduced as the "V in MVC" [2]. Since then it drifted away from MVC in an ad-hoc manner. In part this is because of ReactRouter, which made router a view component (!), and in part this is because of Flux/Redux. The facebook engineer who came up with Flux famously declared that MVC doesn't scale (!!). This assertion was widely challenged, and later she acknowledged that it is bidirectional data flow that doesn't scale [3]. She had assumed that MVC automatically implies 2-way data binding. Redux, an implementation of the Flux architecture then became popular, and became closely associated to React, so much so that many developers believe using React implies using Redux. This is unfortunate because Redux requires tons of boilerplate ("so much throat clearing", as one developer put it), which MVC does not require.
[1] https://changelog.com/131/ (starting around 0:43)
[2] https://github.com/facebook/react/tree/015833e5942ce55cf31ae...
Not _required_. There's both "inherent" and "incidental" complexity around Redux [0]. We've created our new Redux Toolkit package [1] to specifically eliminate the "incidental" complexity and simplify common Redux usage patterns. It includes utilities to simplify several common Redux use cases, including store setup, defining reducers, immutable update logic, and even creating entire "slices" of state at once.
We also just released the official Redux template for Create-React-App [2] to help speed up the process of setting up a new app.
[0] https://blog.isquaredsoftware.com/2019/10/redux-starter-kit-...
[1] https://redux-toolkit.js.org
[2] https://github.com/reduxjs/cra-template-redux/releases/tag/v...
If all of those are MVC, does MVC even mean anything?
What are the core commonalities across all those development frameworks that make them "MVC"?
The Views accept data and generate a UI of some kind. They have no idea where the data comes from, or what their requests actually do.
The Controller knows about both the Model and the View. It maps request from the View to operations in the Model, and then uses data from the Model to update the View.
M <= C => V
That is the broad structure behind how all those things works. They aren't all the same, but that's not the point of a design pattern.
https://docs.djangoproject.com/en/3.0/faq/general/#django-ap...
It's funny how the software industry can simultaneously produce games with hundreds of textured 3D models flying around the screen at 60 fps, but if I want to load a big data table of nothing but text in a web browser, the fans start spinning and the scrollbar locks up.
It's such a perfect representation of the coder trope of loudly proclaiming that this new thing I found makes everything else obsolete. Eight years later, MVC is still miraculously not dead!
It's kind of an insult to death.
All you have to do is type all of your project documentation in MS Excel, print it out, and then throw it all over the place... Then Developers can simply pick what's on top and meet for 23 minutes (once every 2 years) to discuss their emotions... It's been a very productive decade for us so far.
One of the reasons I see feeding this is tossing around senior dev titles with 3 to 5y experience. Even as a higher producing developer, all it did was open my eyes to how much I really had to learn.
The reality is seeing one, let alone two 10y cycles of software changes your relationship to architecture of code so much .. that I really hope seniors with 10y exp may not be the same as seniors with 20y experiences in the sheer amount of trauma they have had to help organizations heal from using the latest and greatest that is reinvents the same libraries and frameworks, and leaves more technical debt behind than it offsets by requiring refactoring in months instead of years.
Most languages are now very reasonably capable due to quality frameworks for most. This alone will do more to improve the quality of code bases in the next 10y than a replacement for MVC..
Either way, an insightful read.
Because that's how to write headlines people click on.
Controversy! Extreme positions! All or nothing!
1. The person saying it doesn't use the platform.
2. The vendor the person saying it wants to sell a new service.
3. The people saying it are palm readers who can predict the future, and they've already seen it.
All very solid reasons.
I've never gotten into any of these patterns in 20 years but can get the job done efficiently as I don't put codes all over the place but at where it's easy to find for easier debugging.
Usually average people try to put their codes into these patterns without truly understanding and their logic is also not efficient, turning codes into very unreadable state instead of just dropping the pattern and write as you please (with at least minimal separation of views and consolidate identical codes).
Have these patterns really helped you in the web?
Discussed at the time: https://news.ycombinator.com/item?id=4189811
(Links are for the curious; reposts are ok after a year or so: https://news.ycombinator.com/newsfaq.html)
It's been 20 years - have I been missing out on a crucial details?
I don't really think most people understand how to do MVC. A LOT of people mostly pick a framework that incidentally has it slapped on the side and that's about it...
People seem to assume "view" has to mean template, "model" has to mean "database access," and controller means "anything else." When in reality, they're far simpler and more abstract and has nothing to do with the web or services:
Model - Data View - Output Controller - Takes input, fetches data for input(s), gives output
Do you have a part of your application that takes input and gives output? Well then MVC is probably great for that part of your application, maybe not.
I have not ever had anyone say "the adapter pattern is dead, don't use dat shit, my dear, brometheus" because most people, quite accurately, don't think it's some sort of philosophical statement it's just way to organize some shit to make your life easier when it applies.
/shrug
Use the right tool for the job; you can waste a ton of time trying to use a screwdriver on nail, or you could just get a hammer...
I've posted a version of this comment before, but my main problem with MVC isn't that it's a bad architecture, just that in practice there's a huge amount of disagreement about what MVC (or MV* more generally) actually _is_, which can lead to confusion or weird/bad hybrid implementations.
I tend to use the "model" and "view" concepts a lot when discussing architecture, but in my experience it's almost always a mistake to try and reference any specific MV* pattern for explanatory purposes - it does not have the effect of making the discussion clearer.
The issue is that there isn't actually a consensus about what constitutes the definitional features of these patterns, especially when it comes to how the concepts involved actually translate into code. For any sufficiently notable discussion of an MV* pattern, you're going to find an argument in the comments about whether the author actually understands the pattern or is talking about something else, and typically the commenters will be talking past one another.
Note that I'm NOT claiming that there's anything wrong with MV* as an architecture, or your favorite explanation of MV* - it may be perfectly well defined and concrete and useful once you understand it. The issue is a feature of the community: lots of other people have a different (and possibly worse) understanding of what MV* means, so when you start talking about it and your understandings don't align, confusion arises. Getting those understandings back in alignment is more trouble than the acronyms are worth.
I've seen enough conversations about concrete development issues suddenly turn into disagreements about the meaning of words to realize that nothing useful is conveyed by mentioning MV* and assuming anyone knows what you're talking about - it's better to spell out exactly what you mean in reference to the code you're actually talking about, even if you have to use more words.
I like this MOVE scheme because it seems to me to divide up the conceptual space at the joints in a way that's relatively hard to misunderstand, and it seems a little easier to see how to directly relate those division back to code.
Every platform has it's own challenges to work around. Trying to take a pattern you used in Qt and applying it precisely the same way to a Javascript/HTML application would be unwise. Things like the DOM, CSS and even the quirks/strengths of Javascript mean you should approach the problem differently. This can mean you are forced to structure your code differently. The same is true if you are dealing with iOS and Swift.
IMO, MVC should mean something different in a way that supports the context it is being applied within.
The ViewController isn't bad all by itself, but calling it MVC is just not it.
Ben Jaffe of Udacity cally is MVO where O = Octopus. Basically, as the author points out, Models and Views are relatively well defined, but the Controller can be anything. Octopus, ViewModel, or in this case Operations and Events.
I do think Operations and Events are clear, but
1. are they comprehensive and
2. do they organize the code more intuitively?
It seems like you would want to put them in the same place since Events will trigger operations that operate on the model and the view. Sort of like a controller... oh, wait.
The idea is that devs and large companies have a tendency to constantly move away from tried and tested concepts not because the juice is genuinely worth the squeeze, but because doing so forces the devs "in their dust" back into learning mode and out of productivity mode, thereby maintaining or creating leadership over them (i.e. you force them into playing catchup -- catchup to your new "hot" thing).
Case in point with this article: an attempt to declare that a tried and tested and widely used concept is now outdated, and they know the "right way" we should be doing it.
This paradigm is important from a dev management perspective, in that there must be an element of actively suppressing this in a dev organisation.
E.g. having approved tech lists so you don't have another half dozen js frameworks inserted over the next 12 months, requiring permission to stray outside standard paradigms, and compartmentalizing experimental time from production time.
Otherwise your dev output drops through the floor.
MVC is fine. Its a basic concept that aligns with the underlying hardware: model - memory, view - screen, controller - cpu. It ain't broke, don't let your devs fix it.
If you're having to search your entire code base to see what happens when a user logs in, and then what happens if that user is marked as "blocked", it can get very complicated quickly.
Even worse, trying to backtrack events can be more complicated. What caused the "add to cart" event that added this special product type that is actually a digital download, but that wasn't a UI event? It could have happened in one of 10 places, debugging is difficult because you have to start somewhere in the middle and work your way backwards.
This is the issue I've had with wordpress development, actions and filters can make intuitively understanding what's going on under the hood very very difficult. Of course they give a lot of flexibility with plugins, extension points, etc, but when multiple plugins are interacting it can get very confusing.
Compare that with a more imperative controller where you branch based on conditions and you can generally follow the logic flow. Of course, there are ways to make that complex too like Form classes, validation, ORMs, etc. But I still find the more imperative paradigm of MVC easier to follow, such as in a Django case.
Where I say this can get interesting is in a use case like React. In a way, events are propagated through a tree and can be kicked off by data changes, such as in redux. If you design it right, there might be more promise in an event-based system, but introducing both server side and client side tends to complicate things.
The implication is that what goes into controllers is not well-defined. But if what goes into models and views is well-defined, as the author agrees, then defining what goes into controllers as everything else is actually a precise definition.
It looks like E (events) is simply to illustrate oh yeah some communication is happening between these layers. I think that is pretty obvious?
I'm not necessarily putting down what he was saying, but I don't think this is something revolutionary. I think he just dove deeper and expanded.
Operations ^H^H^H Functions A common function for applications is logging a user in. It’s actually two sub-functions 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.
Functions are the doers of the MFVE world. They are responsible for making changes to your models, for showing the right views at the right time, and for responding to events triggered by user interactions. In a well factored application, each sub-function can be run independently of its parent; which is why in the diagram events flow upwards, and changes are pushed downwards.
What’s exciting about using functions in this way is that your entire application can itself be treated as an function that starts when the program boots. It spawns as many sub-functions as it needs, where each concurrently existing sub-function is run in parallel, and exits the program when they are all complete.
HN, rediscovering main()
Components being Views
And
Hooks being Operations
> [Under MOVE, e]vents are used to join all these components together safely.
The problem with events is that you put all interactions into events, creating a labyrinth of ad-hoc protocols.
Events are messages, and messages are just methods in disguise: worse ones, that don't have a call stack you can inspect.
Under this MOVE, someone will sooner or later hit the problem of wanting the V to manipulate the M in some way that O doesn't support, and will just end up creating some hack whereby a whole chunk of the M state (perhaps all of it) is downloaded via some stream of events, edited, and sent back via another stream of events.
1. this is a complicated domain.
2. the lack of a very clear coherent "right answer" tells me not to dwell too much on it. I'll see more gains by getting my UIs into production and initiating the feedback loop than trying to get the architecture right.
As for item 2, I have absolutely iterated on underlying architecture, non-stop. But I feel I've been immensely successful in never letting that get in the way of shipping early and often and learning the 90% of stuff you can't learn without shipping.
As in, not the pattern, but the real-world usage of it. Development constraints always end up corrupting the pretty pattern in ways that make the current problem at hand easier to solve, and this de facto architecture IMO never ends up looking like proper MVC for me.
I want to say I like Action-Domain-Responder better, but I haven't seen any real-world implementations of a ROA with it yet.
Let us assume a concrete architecture where views are html documents and events are put into some distributed queue. Is an operation a process that consumes events from that queue or is it something more tangible? Are operations data? In other words, are they interpreted? By what interpreter?
I think the idea of describing your business system as some giant, distributed, parallel DSL interpreter has some merits. But has it ever been implemented as such somewhere?
DCI is better thought out than MOVE.
Sometimes it doesn't matter what the rules are just that there are rules because the rules bring order and consistency that allow for quick comprehension of the written code.
Heres a modern iOS dev defending MVC:
https://www.dotconferences.com/2020/02/guilherme-rambo-mvc-m...
Sensational title at best.
Go check out the "Microsoft Patterns and Practices" frameworks from decades ago to see many examples of this.
Didn't the Smalltalk team invent MVC? Because I believe Smalltalk in the 70s supported both.
If it's not meeting your needs that just means it's not a good abstraction of your problem. And yeah, you should probably look for something else.
What's good for websites is not necessarily good for data-centric CRUD. MVC tries to cater to both, and does neither well because it has to compromise to make both camps happy.
I'd like to see, first, the file/folder location be flexible. If a team wants to store the view together with the model (or view-model) in entity folders, they can. Make the file look-up mechanism more flexible, or at least have a few templates to choose from. Our shop would prefer something like this:
Models
- model01.code // friendlier names not shown
- model02.code
- etc...
AreaX
- EntityY (folder)
- - ViewModel.code
- - View.code
Second, navigation (menus, URL's, and breadcrumbs) should probably be table-lized in the RDBMS so analysts and project managers can change paths and titles and perhaps even role assignments without re-coding. The "path math" of controllers is confusing and hard to debug. Put the damned tree(s) in tables instead so we can do nice reports and analysis of them without digging through verbose code. There was an anti-DB movement in the early 2010's that was wrong-headed in my opinion, so everything was shoved into app code instead. It's time to embrace DB's and use them again for what they are good at. We then wouldn't need controllers, at least not in everyday work.Note: If I say something bad or wrong, please explain in a reply instead of give a hit-and-run negative score. I get better with clear feedback. Thank You.
I should note I'm a fan of the CASE idea of the 90's. It was just that the products were proprietary and too expensive. 90% of most CRUD apps can be attribute-driven. Menus, navigation, page titles, field attributes, etc. can largely be stored as meta-data in RDBMS where they are readily change-able and query-able. Buried in code makes them harder to work with. Over-focus on OOP killed the CASE dream, but I suspect it will come back. RDBMS are good at storing and managing masses of related attributes, code just isn't. (Dynamic Relational would help with attributes that are different or custom per UI widget etc. I wish it would take off.)
What's CASE?
It's essentially a glorified integrated ERD + IDE. If you think about it, most of the info that goes into a typical CRUD application can come from tables. Related: "Data Dictionary". When I first saw them, I went, "Wow! This is the future!", similar to my first Macintosh visit. (One tricky part is dealing with the 15% or so that still needs custom adjustments. I have some ideas about that, but that's another long topic.)
The implementations of MVC are generally terrible, because the "C" is extremely subjective and you cannot find consistent patterns to follow universally. One developer's MVC app is going to look a lot different from another's unless they work on the same team or follow the same policies.
MVC (in practice) ultimately says "ok here's 80% of the puzzle I cannot figure out, good luck dealing with it". We can mostly agree on what our various businesses need or want (models+views) as well as what the browser API standards are (mostly views). The tricky bit is synchronizing those worlds in the middle. I personally find that pulling as much of the front-end into the back-end as is feasible is the most productive path to go down. It might not be the most scalable, but there is something really magical about being able to inject a business service you wrote 5 years ago into a .NET Core 3.1 Blazor component, write a small in-line LINQ mapper, and have it directly populate a table marked-up with BS4 (which then updates in real time via basic CLR event subscription). Is that MVC? I don't know. I don't really care either. It gets the job done, is easy to maintain, and makes me look good when it "just works".
Step 2: ?
Step 3: Profit
[1] https://github.com/EamonnMR/Flythrough.Space/blob/master/src... [2] https://github.com/EamonnMR/Flythrough.Space/blob/master/src...
https://medium.com/better-programming/object-oriented-progra...
It is more difficult to implement ECS (there isn't a long tradition of it and libraries like MVC has) but well worth the effort.
It's more suited to native UIs than webapps though.