Live data from Hacker News

MVC Isn’t MVC

collindonnell.com

101–110 of 165 posts

Re: MVC Isn’t MVC

#101
post #88
post #28

Earlier quoted context omitted.

> My take on the model layer is : write everything that’s not strictly specific to your UI there. My take is this, except with the caveat that the larger a model gets, the closer to declarative it should become. You touched on this by saying the model layer rather than just the model, but it's worth emphasising. You can achieve this by abstracting out the messy bits, e.g. moving some hooks to a task queue (processing…

Yes, there's definitely a confusion in the meaning of the word "Model": All objects belonging to the model layer don't have to match a data type. For an online shopping app, you may have an "Item" object, but your purchase logic may be in a "Purchase" service object, which needs a "PurchaseRestAPI" to perform HTTP calls, etc.. They all belong to the "Model" layer. Correctly structuring your model layer is the key for…

But dumb, passive data structures still have their place in that "Model", and unfortunately, those are usually referred to as model. Note how I picked up your quotes and capitalization for the former, that's very helpful here. This is really where I see the root of why MVC is such a useless term: the "view" feels intuitively unambiguous, there's always something that is very tempting to declare model and everything else will either be declared controller in one broad sweep or assigned to one of the other two in an elaborate act of design-by-committee (even if you're all alone and it's only the different positions in your head).

Personally, I've made it a pet heuristic to blanketly assume the worst whenever I hear MVC. Perhaps there's good code out there despite its makers trying to find salvation in those troublesome letters, but I assume the false positive rate to be acceptably low.

Re: MVC Isn’t MVC

#102

> Model updates View, View sees User, User uses Controller, Controller manipulates Model. > This makes a lot of sense to me, and I think I understand it pretty well. It looks simple at first glance, but it actually makes zero sense under closer inspection. Let’s take a simple example. A table of users. You take a table from the database and put it into an html tag table. Wait, who is “you”? The model? Do you want you…

> You take a table from the database and put it into an html tag table. > Do you want your view to know how to connect to a db? I think this is where there's a misunderstanding: you think of your model as "a database". A database is not a model, a database is just a storage layer. A model is an object that provides an api with high-level business operations and views on data. At that point, your view needs only to re…

> A model is a ... view on data.

I think this is part of the reason the MVC names persist, they are so generic that you can describe the Model as a type of View!

Re: MVC Isn’t MVC

#103

Is it weird that the inconsistent citation scheme really jumped out at me? > In December of 1979 _Tyrgve Reenskaug_, an employee of _Xerox PARC_ Later >In 2004, a Danish man

The author is being cute in the second citation and is referring to David Heinemeier Hansson who is famous in the web dev world for creating Ruby on Rails.

Re: MVC Isn’t MVC

#104
post #9

Not sure why author got the impression apple’s models had to be « dumb data containers ». Actually, having dumb models is the surest way to completely screw up your controllers design, since you’re now left with no other places to write your business logic in. This leads to either weird trees of controller inheriting each other for the sake of reusing some data processing piece, or singletons everywhere which makes t…

Personally I kind of like dumb models. Dumb models means I don't have to think too hard about "a.affect(b)" vs "b.be_affected_by(a)". I can just write functions that do what I want right now. "do_my_thing(a, b)". No reason to be doing anything else when programming. If you have people making controllers inherit each other just to share functionality then they're probably brainwashed by OOP. Stuff like inheritance and…

data objects have to be dumb, the managers don't.

both C# and Java can be used in a sane way, but ... at what cost, right!? C# is tied too much to the regular MS circus, and it's just a few more years and Java will finally be great! oh wait.

of course, actual, real-world walking-talking problems can be solved in both of these ecosystems, but ... almost always the real constraints are not the actual language. (... trying to do HFT with a JIT-less language, or some other faux pas)

Re: MVC Isn’t MVC

#105

Earlier quoted context omitted.

No, please for the love of god stop writing services. Having random grab-bags of methods makes it infinitely harder to find what code lives where, instead of putting it into models where we have 20+ years of OO design principles (single responsibility, open to extension, liskov substitution, interface segregation, etc) to guide us. "Fat models, skinny controllers" is a Rails guiding principle for a reason

Until the moment that models have to call other models to get anything done. The problem is that the models often get too tied with the database implementation. Then, you're separating business logic that doesn't make sense to separate. The fat model ruins single responsibility because the database table is not a good proxy for one reason to change.

This is a specific problem with the Active Record pattern, rather than something intrinsic to MVC, and it's exactly why AR is fine for simple apps where the business logic looks a lot like manipulating a row in a database, but breaks down for anything more involved.

But also there's no reason you can't have non-database-backed classes sat next to AR models, if they make sense in the domain. Not everything needs to be a database row.

Re: MVC Isn’t MVC

#106
post #94

Earlier quoted context omitted.

> Model-View-Controller-Service-Repository Where would you put validation logic, though? I mean, some of it might need to just check whether a domain object has its fields filled out, but other validations might need to cross reference DB data to make sure that everything is valid in accordance to the business rules. Ergo, we might have Model-View-Controller-Service-Repository-Validator Even without being silly, it's…

Validation logic needs to be spread throughout the system because your validations are all context sensitive to the operations being performed. It's not always possible to front-load that into a simple schema in your transports and each component needs to be correct in its own domain.

> Validation logic needs to be spread throughout the system because your validations are all context sensitive to the operations being performed.

While it certainly isn't always possible, I've definitely seen it be aggregated in a single place in monolithic codebases that focused on CRUD.

Essentially, it was structured like so:

  +--------------+   +------------------------+   +-------------+
  |Resource (API)|---|Service (business logic)|---|DB Repository|
  +--------------+   +-------------------------   +-------------+
                                |              \
                     +-----------------------+  \ +-----------------+
                     |Validator (validations)|   \|REST clients etc.|
                     +-----------------------+    +-----------------+
The Resources were typically just API endpoints (HTTP), that passed data onwards to Services. Those could then call upon other services or service requests on their own: store/persist data with Repositories, deal with scheduled processes, or pass data on to other systems through REST clients etc.

Before Services did any of those, they reached out to a Validator to make sure that the data matches the business rules and constraints. Sometimes there was additional validation context passed in (essentially a map and some enums), sometimes there were certain constraints that an entity needed to always follow within the context of the business and so on.

In practice, it was good because you could see all of the constraints in one place, that an entity has to match before it can be persisted in the DB, or passed onwards to another system. But then again, that's not always viable in more modern architectures. Of course, it wasn't the most traditional approach to MVC either, even if those concepts translate pretty well to it.

Re: MVC Isn’t MVC

#107
post #9

Not sure why author got the impression apple’s models had to be « dumb data containers ». Actually, having dumb models is the surest way to completely screw up your controllers design, since you’re now left with no other places to write your business logic in. This leads to either weird trees of controller inheriting each other for the sake of reusing some data processing piece, or singletons everywhere which makes t…

> apple’s models had to be « dumb data containers ». They don't "have" to be, but that's very much the result of what Apple has been advocating, what the community tells itself and what happens. > Actually, having dumb models is the surest way to completely screw up your controllers design, since you’re now left with no other places to write your business logic in. Exactly. And the coordination logic. Alas, that is e…

> The "Model" is an object that is the headless application

Wow, that's a great mental model (wink) to have.

I never thought of it in those terms, but I think I do follow it, mainly because I tend to follow John Ousterhout's guideline of "Deep Modules, Small Interfaces".

This way the model ends up being exactly what you're talking about. It is testable, issues are easier to reproduce, it's easier to reason about, it is portable to other contexts: server-rendered web app, JSON API, GraphQL API, desktop app, mobile.

I think the biggest obstacle for people using popular frameworks is realizing that a "Model" doesn't have to be necessarily one single class. The important part is having a model-like API that is good and self-contained. Previously I didn't have a mental model for what is "good" but with your comment I think I can put that into words a little better.

One of the biggest problems I have with Services and other patterns such as Operations, Interactors is that developers often couple them to Controllers and Views. Also often I see duplication happening when new patterns are added because they're seen as separate. If you think of them as "part of the model", however, and follow the "the model layer is its own headless application" those issues have a smaller chance of happening.

Re: MVC Isn’t MVC

#108
post #44
post #9

Not sure why author got the impression apple’s models had to be « dumb data containers ». Actually, having dumb models is the surest way to completely screw up your controllers design, since you’re now left with no other places to write your business logic in. This leads to either weird trees of controller inheriting each other for the sake of reusing some data processing piece, or singletons everywhere which makes t…

There's two definitions these days for the term "model" in MVC: 1. An object that models part of the service/product. Meaning, not something related to the operation of the medium by which the service/product is delivered, but any operation that models the service/product itself, independent from medium. This could be a representation of a DB row, a service object, a decorator, or any other piece of logic that relate…

Def 2 is actively bad and wrong, though. It happens to fit simple apps (and simple bits of complex apps) so it looks reasonable, but what's really needed is an off-ramp to let the model actually be what it should be, which is a domain object.

Active Record is an optimisation that by rights ought to be premature, but the downsides don't start to bite until a certain complexity threshold which a lot of apps might just never hit.

Re: MVC Isn’t MVC

#109

Earlier quoted context omitted.

> You take a table from the database and put it into an html tag table. > Do you want your view to know how to connect to a db? I think this is where there's a misunderstanding: you think of your model as "a database". A database is not a model, a database is just a storage layer. A model is an object that provides an api with high-level business operations and views on data. At that point, your view needs only to re…

> A model is a ... view on data. I think this is part of the reason the MVC names persist, they are so generic that you can describe the Model as a type of View!

MVC “view” is on the user level, the model is a “view” (facade/adapter/whatever) on the programmatic level.

Re: MVC Isn’t MVC

#110

Fun article. Just a note, MVC requires the Observer Pattern. If the Observer Pattern isn't present, it's not MVC. And it's fine if it's not MVC. It can be called something else. It's fine. RoR doesn't implement the Observer Pattern; thus, not MVC. It can just be RoR. AspNet MVC doesn't implement the Observer Partner; not MVC. It can just be AspNet. Here's another reference to Tyrgver's explanation of the MVC language…

https://github.com/hotwired/turbo-rails/blob/main/app/models... is designed to close that loop with automated view updates from ActiveRecord changes.
Post reply on HN