I like ECS when designing certain kinds of systems but I'm not sure how relevant it is here. I'm also not sure it would be particularly useful for your average webapp.
I still see MVC in $dayjob, but it looks like React/Redux have helped a lot. A central module manages state and takes operations on that state. The desired view hierarchy is computed as a pure function of state. A library uses diffing to apply changes to the concrete implementation of the views (say, the DOM, or a native windowing framework).
I'm not sure this pattern as described is comprehensive, but the move away from MVC to other event-based patterns like React/Redux, Elm, etc, clearly did happen. MVC of course still exists in the world.
This article is the first one I’ve read on MOVE. On the other hand I’ve seen multiple in the past few years on MVVM and VIPER, just to name two MVC replacements. My guess is MOVE isn’t used much.
I feel like his answer to what goes in the controller is answered by his acronym MOVE. Operations and Events go in the controller. It initiates the state changes in the model and the view. As an aside it’s cool to see something like MVC staying relevant, it alludes to there being design patterns that are simple and fundamentally useful in some areas.
Events are how MVC was used before the web world came around. The whole point was your controller listens to model and view events so everything is updated real time as the model changes and the user interacts with the UI. The web is a bastardized version of MVC due to the lack of interactivity and state when compared to a desktop GUI application.
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.
> Events are how MVC was used before the web world came around. The whole point was your controller listens to model and view events so everything is updated real time as the model changes and the user interacts with the UI. The web is a bastardized version of MVC due to the lack of interactivity and state when compared to a desktop GUI application.
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.
Then the web came, and we have the MVCS+JS+REST mess. Explanation:
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.
I don't see anything wrong with MOVE... but why does MVC need to be dead?
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!
My cousin's boyfriend's sister went up to the waterfall, and when they found her body 12 months later--after delivery phase--she had been completely burned out from the inside. And there was this thing... that nobody wanted, that didn't work right, just sitting there next to her. Nobody wanted to touch it. So some guys from the federal government came and picked it up with tongs, and said they'd put it in the Source Control Repository facility out in New Mexico, so it couldn't hurt anybody else.
I invented a new methodology called "scattered paperwork"...
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.
It's worse than that. MVC is not only not dead, this little essay has conveniently reinvented it! (The C became an O, and the E was always there in some form.)
"That which is not dead may never die, unless involved in a serendipitous knife fight with a one-arm incestuous twin of your current lover" starts to strain the metaphor a _tiny_ bit. I think it's probably more useful in terms of expressing the problems with NPM.
With time I’m noticing those who think anything is going to die or old/new are often relatively still new in their journey of software development.
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..
Turns out Conrad Irwin was right, but didn't take it far enough. Merge together "Events" and "Operations" into one thing, call "Models" just "state" and you've got Reactive Programming, which appears to have proven itself as the best known way to manage UI state complexity.
Proven in what way? After almost 4 decades in this business, nothing is ever proven. For anything one person says is beyond discussion obvious, another person does something completely different, and gets the same benefits. Every generation comes up with new ways to do things, but nothing has even been clearly better to everyone all the time in all circumstances. You constantly have to evaluate everything that comes along, and see if it's better for you, your team, project, company or industry. Silver bullets are for vampires and the Lone Ranger.
It is "proven", not in a mathematical sense, nor a scientific sense, nor an engineering sense or even a legal sense. It is proven in a javascript sense.
Reactive programming looks like a very good model for UIs, but I wouldn't claim anything is proven.
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".
React is just MVC turned inside out. The core principles still apply:
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.
MVC is understood to be the primary partition of an application's architecture. It does not obviate the need for further code organization, which is done in all parts, Model, View and Controller. When the author says "controllers are nice self-contained bit of...[what I don't know?]", and they use that as the justification to throw away the paradigm in favor of another with Model-View-Operations+Events they show they don't understand this. Worse the proposed paradigm does not then collect all the controller code in one place, so the overall lifecycle of the application would be harder to piece together from Operations+Events modules without an overarching Controller to govern the two of them.
Yeah - build out a graphql service on top of existing models, and you'll get a pretty clear picture about what the C ought to represent. You can find plenty of situations where the implementation of any of those letters is extremely thin: lots of services where the View is almost nothing (often just a JSON serialization of some of the models), or where the models are very thin. It boils down to a weirdly common, but deeply flawed, view that all the letters in your abstraction's initialism should be of equal complexity.
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.
Personally I see this design pattern simply as an application of Dijkstra’s Separation Of Concerns. That MVC is the best (most orthogonal and balanced) division of concerns in a gui based app.
Everyone who has done MVC long enough would also know that the controller is the very thin layer where services are injected and models are passes to.
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.
That is right. And having service layer which dictates model changes, db ops and with its result a view change is pretty close here. This move pattern also reflects a bit the reflux idea of events and actions on models (with my limited redux knowledge).
One of the biggest problems with iOS development is that most of the official coding samples include quite a lot of logic inside the controllers (called a View Controller in Apple lingo) which in turn causes novice developers to assume this is the correct way of doing it. It's such a common thing to find in codebases that the iOS community calls this the Massive View Controller pattern.
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.
it's not just code samples. i remember wwdc conferences at the time of ios3 where apple people used to officially say "we know it gets you worried, but having massive vc is actually just fine"
iOS architecture takes a bit of a while to feel out and see what works for you and your team. It's extremely overwhelming the last few years with how many alternative patterns are being pushed around and touted as the one true way.
Every Rails app I've seen has been MV, not MVC. The app/views directory contains the template part of the view code and the app/controllers directory contains the meat of the view code.
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...
In a Rails context, there are a dozen pattern-esque buckets that folks advocate putting non-template, non-persistence, non-validation logic into. Yet as often as seeing benefits from "service objects" or similar generic, I have also seen benefit from adding an actual View layer.
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.
Yeah, Rails confused an entire generation of developers by combining views and controllers into one messy, bloated, unencapsulated object, calling that a controller, and calling templates views. Rails models are also full of both view and controller logic, via validations, and full of higher-level business logic, and hacks to deal with the lack of a multi-model, transactional persistence layer.
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.
I don't know, I err towards validation in or close to the model. You shouldn't be able to construct an invalid model and that usually involve the model validating the data you're passing to it. Rails certainly doesn't go about it in a great way though and tends to leak view based concerns into the model.
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.
I find the rest of Trailblazer a bit over-engineered and prescriptive, but I really like cells (http://trailblazer.to/gems/cells/). IMO these are good for encapsulating view state. It more replaces the "helper" layer than controller layer, but it also helps you write controllers that just focus on HTTP stuff and nothing else (together with service objects, of course).
Aren't services just the DRYing up of controller code into functions? Like moving ad-hoc 3rd-party API code into a 3rdPartyApi.fetchItems() namespace? Or your inline database calls into a db namespace?
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.
No, not just DRYing (at least, not in my opinion).
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.)
Controllers abstract transport-layer functionality away from application logic. It's not really about "DRY" as it is about "Why should my services have to care about HTTP status codes?"
Yup, This is a pattern I've come to call MVCS. I want to see I saw that in a bit of documentation somewhere but I haven't been able to find it again. The C layer should be as thin as possible and have logic in it that pertains to routing and whatever kinds of transforms your "wire"/"transport" layer needs while the Services do all the heavy lifting and contain most of the business logic.
>The C layer should be as thin as possible and have logic in it that pertains to routing and whatever kinds of transforms your "wire"/"transport" layer needs while the Services do all the heavy lifting and contain most of the business logic.
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.
Where a service could be something external or just a library, module, class or function. I always think service is a bit of vague term describing a bunch of related functionality packaged in some reusable abstraction so you don’t need to reimplement this logic every time high up in your app.
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.
Yeah, the Rails community noticed this a while ago. Put the business logic doing transformations on models and interacting with external dependencies in service classes, which accomplishes three things:
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.
I always say the Controller knows "what" not "how". But after a few years in iOS I kind of settled for a very fine-grained MVC pattern with Repositories, Reactive ViewModels and a separate Layout class per ViewController. Navigation is abstracted away but it's just a protocol implemented by a UINavigationController, nothing special. The ViewController doesn't do anything anymore except holding and wiring up the labels buttons etcetera and respond to events like viewDidLoad.
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 rarely seen people fail to realize that having at on of code in a really fat layer is a problem.
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.
Re: 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.
"Everyone who has done MVC long enough... The controller should have and only have logic which absolutely cannot be moved to a service layer."
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.
CQRS comes to mind. spam events from user interaction, respond to them with any number of disjoint event handlers, with a tiny core runtime that ultimately acts on a specific subset of those events destined to modify the DOM in some way or another
Assuming you are implicitly claiming it only makes sense to use MVC, it couldn't be MVC, because as I said in my other reply, network communication is too big a concern to just slip in to the design. It's a fundamental change. MVC doesn't have any provisions for network in it.
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.
> Sorry, which letter in MVC is the "service layer"?
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.
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.
I still haven't found anything that makes a clear distinction between "controller" and "model". The best explanation I've ever heard is that a controller's job is to map UI activity to the proper model and view. That's a start, but there is a lot of grey area there also as determining such can sometimes be complex in itself, which leaves the door open to "fat" controllers.
I think the biggest distinction to me is that the controller is the entry-point into an action/routine. It takes external inputs and returns an output to be sent back downstream.
In many frameworks the controller isn't even the entrypoint anymore though. Laravel for example has a separate router layer, which is the entrypoint that then passes things into a controller.
The problem is just that other later GUI frameworks didn't follow that design. Smalltalk had a controller for each view to handle user input, but Windows doesn't and neither does GTK, Qt or Swing.
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."
"MVC is well documented, and objectively defined."
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.
Seems to me that what people usually think of as the "Model" layer actually has "Operations", but we usually call them "methods."
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. )
It's reifying Events that attracts me to this model. This would encourage a message-passing style, which has always been a big win for me when I adopt it.
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.
> MVC does not comprise all layers of an application.
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.
It doesn't really matter what MVC "is", but it's very important where MVC goes—MVC, in the https://en.wikipedia.org/wiki/Hexagonal_architecture_(softwa... sense, belongs to one particular "adapter." MVC is not the framework of your application; it's the framework of your application's $foo adapter, where $foo can be "web" or "native UI toolkit" or "GRPC API."
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 and the notion that global variables or state are not a thing in modern software explains most failed UI projects built by juniors initializing things as global variables from controllers that also contain logic, layout, and other stuff that does not belong there (aka. an untestable & disgraceful mess).
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.
Where I've seen this done well, All of the data for rendering a view was pulled at the beginning of the action. The database transactions are over and done with, the cost of each request is very clear, and frequently caching is un-needed because you know that 3 different parts need the same data so you just give it to them instead of waiting for somebody to ask.
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)
This simple concept pretty much bridges all design philosophies in practice. You have MVC and OOP, you have functional services, and you are free to create the appropriate amount of layers you need.
To address another comment, MVC does not mean only MVC, it's just a framework that allows you to add layers where appropriate.
I like this a lot, not as an alternative to MVC but as a kind of conceptual refactoring of the same ideas behind good MVC implementations that's very easy to explain and doesn't have as much ambiguity.
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.
> MVC is a phenomenal idea. You have models, which are nice self-contained bits of state, views which are nice self-contained bits of UI, and controllers which are nice self-contained bits of … What?
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.
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.
I'll never understand the obsession to have one architecture to rule them all. mVC isn't dead. I set up MVC patterns all the time for small projects where I need CRUD with a sprinkling of custom code on top. It's a great pattern.
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.
Now what are operations then? And how are they tied to events.
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?
I've found MVC annoying, but everyone goes "everyone else is doing it so we have to do it also". Lemming Syndrome. In team environments it's usually good to standardize "slots" for certain activities. But MVC doesn't fit our work-structure well (Conway's Law).
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:
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.
Pyramid's resource trees solve the "path math" problem quite nicely, there are some caveats to that kind of design as well, of course (mostly related to enumerability).
What's wrong with them being in the database? Analysts and project managers can then re-arrange things with fewer coding changes, using CRUD editing screens. One may have to re-project some URL's for the end-user's sake, but that's doable. "Pretty" URL's are not that useful for CRUD anyhow, but since customers expect them (because everyone else has them), they can be managed as an aesthetic wrapper.
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.)
Computer-Aided Software Engineering. It has different interpretations, but in my usage it means most of the application is controlled by meta-data that defines navigation, data relationships, field info, screen names, role associations, etc.
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.)
> Since it was invented however, new programming techniques have become popular. Without closures (or anonymous blocks) event binding can be very tedious; and without deferrables (also known as deferreds or promises) the idea of treating individual operations as objects in their own right doesn’t make much sense.
Didn't the Smalltalk team invent MVC? Because I believe Smalltalk in the 70s supported both.
186 comments
[ 4.0 ms ] story [ 89.8 ms ] threadhttps://en.wikipedia.org/wiki/Entity_component_system
[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.
Components being Views
And
Hooks being Operations
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 ;)
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 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.
Sensational title at best.
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.
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."
[1] https://martinfowler.com/eaaDev/uiArchs.html
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.
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.
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.
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.
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.
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?
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:
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.)
Didn't the Smalltalk team invent MVC? Because I believe Smalltalk in the 70s supported both.