DEV Community

Cover image for MVC Tutorials Are Broken

MVC Tutorials Are Broken

Ovid on March 15, 2021

Note: The Model, View, Controller pattern, or “MVC”, actually comes in many flavors, but for the purposes of this article, I’m referring to MVC fo...
Collapse
 
bbrtj profile image
bbrtj

Model is usually (in most frameworks) connected to database with some ORM. There were some frameworks which also used models for different stuff like form models. I actually liked that.
However, if your model is connected to the database, I wouldn't put any business logic into it, other than getting even more data from the database. ORM objects are rather hard to instantiate in tests and unstable to pass around in your application. I don't ever feel safe when my object has the ->save method.

  • you don't ever know what is going to save it and where
  • as mentioned earlier, creating a new instance of that model (not to get it into the database, just to have something to work on) gets an additional mental overhead
  • often harder to debug, as these objects contain much more than just the data you need
  • and they are actually coupled with the framework

So what I've been trying to do lately instead is to create DTOs (Data Transfer Objects) for pretty much everything and repositories to save and fetch DTOs. Models are just used by the repositories. It is much easier in Perl because with Moose MOP you can skip tedious creation of DTOs and methods to translate DTO to model (usually two per model).

DTOs are easy to create, safe to pass around and in my case, they already contain all the right type constraints (with Type::Tiny). I also created a common DTO method named ->dummy which creates a new offspring class for the DTO with all the same type constraints but with no required fields, so that I can create DTOs even if I don't technically have all the data it needs. I admit that it's not a tested solution but works pretty well where I use it, and when I talk with my coworkers about it (in PHP context) they often agree.

Let me know if this is interesting to you, I can extend that to a full dev.to post with some Perl examples and such

Collapse
 
ovid profile image
Ovid

I think seeing a dev.to article about that would be great!

Collapse
 
brianwisti profile image
Brian Wisti

Even though Python can't legibly get the terseness of a Perl or Ruby, I still aim for the shortest clearest function / method that gets the job done.

I often start sloppy, putting the logic where I think of it, then refactoring out as I see repetition or big chunky complexity that obscures the job of the current function. Pretty remarkable how often those refactored bits end up being useful for other contexts within the application.

Collapse
 
ovid profile image
Ovid

I can understand that point of view and I used to be there. Over time, I discovered that when I knew that a particular place was bad for my code, leaving it there would cause issues in the long run. Refactoring a large, working application is hard work.

That being said, just because I know where something doesn't belong doesn't always mean I know where it does belong. Software is still hard 😃

Collapse
 
brianwisti profile image
Brian Wisti

Well, yeah. There is that. "Where I think of it" isn't quite as random as it was for me say ten or twenty years ago. Plus, the "refactor" flags start waving about five to ten lines in. The river follows the path of least resistance, but often enough it follows the path that already worked.

OTOH it's not uncommon for me to wake up to an ugly chunk of code I added last night at 2am that urgently needs to be cleaned up for my own sanity.

Collapse
 
smonff profile image
🌌 Sébastien Feugère ☔

How can we change the fact that people who implement those bad practices sometimes just follow the recommendations of doing the work the fastest and cheapest way, imposed by decision makers who don't know what they are doing, without thinking of the future, that will surely be a mess if done that way? 😭

Collapse
 
ovid profile image
Ovid

We'll never fully eliminate that because sometimes, doing things the fastest, cheapest way is what's needed to stretch the budget towards hitting that MVP. It's not an either/or proposition.

However, it can be mitigated by strong hiring practices up front. Hiring is one of the things tech companies are worst at (they're getting better a hard skills, but not soft skills). But if you get the right devvelopers, their default position is doing good work and cutting corners as needed. When the default is cutting corners, doing good work becomes much more expensive and much less obvious.

Collapse
 
ninofiliu profile image
Nino Filiu

Thanks for putting into words what I've had in mind for months!

In the same line of thought, I once had a senior dev tell us

The web UI and the database access should be implementation details

and as a dev whose work for the past years has basically been connecting web UIs to databases I took it very personally because I was like "so, what's left? :'("

Only with experience I later realised how important it was to have a Model that is agnostic to what happens outside of the business logic, that doesn't do database calls, and that doesn't generate any HTML

Collapse
 
ovid profile image
Ovid

It's a sad problem that for many companies today, a "senior" dev is decided by years of experience, not ability. Thus, technical ability is sometimes dismissed by the business side.

That being said, "years of experience" often means "business knowledge" and that's something which is sometimes dismissed by the technical side.

I've given talks before about how to bridge this divide, but it's hard to do. So many have chosen which side of the management/technology divide they're on and they're happy to stay there.

Collapse
 
jj profile image
Juan Julián Merelo Guervós

In general, tutorials are broken, at least from the student point of view. They show a single solution to a problem that may have different trade-offs, which are swept under the rug. They put the student into the mentality of "this is how it's done". That's rarely the case in a complex business environment.
Not to mention the speed with which they become obsolete, or how they introduce bad practices on the emitting side, and cargo cult programming on the receiving side.

Collapse
 
systemz profile image
Zahir Lalani

Separation of concerns is such a key aspect that many dont get

Collapse
 
randalschwartz profile image
Randal L. Schwartz

My brief way of saying this is "if your tests are hard (or impossible) to write, you probably need a refactoring or two or three..."

Collapse
 
ovid profile image
Ovid

Absolutely! I should write a post about that: tests that are hard to write are often a code smell.

Collapse
 
moopet profile image
Ben Sinclair

In particular, they had a 3,000 line “method” for their search engine.

Those are rookie numbers