4 ms·
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 pu
by nightpool 3y ago
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
- ebiester 3y agoUntil 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.
- LeonB 3y ago> models have to call other models. “You're very clever, young man, very clever," said the old lady. "But it's turtles all the way down!"
- deleted 3y ago[deleted]
- regularfry 3y agoThis 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.
- ebiester 3y agoWhat, then, is a service other than a model without a database table?
- regularfry 3y agoEh? It's a service. It represents a domain operation (or group of operations) that hasn't been coalesced into either a value type or a transient entity, both of which are also models without database tables, both of which are preferable to a service if they fit the domain. None of this says that putting business logic into a separate class to the thing that happens to back onto a database row is correct because of single responsibility. That's a fundamental misunderstanding of the SRP.
- dikei 3y agoFat models is the opposite of single responsibility: doing both business logic and data retrieval/storage logic inside the same class is already more 1.
- jbverschoor 3y agoYou’re confusing fat models with the active record pattern vs repository pattern.
- smaudet 3y agoI'll throw a wrench in - I like heavy views. In HTML, in desktop GUIs/mobile Apps, in Databases, maybe games. HTML is founded on the principle that your data is semantic, it knows how to submit and modify itself. You have <form> tags. Every thing you can do in your view, is another thing you don't have to submit to some slow service or wait for a controller to do. GUI frameworks are often like this as well, complex well-written UI components tend to remove a lot of supporting code from Controllers that just was there to half-support the UI having a slightly different formatting. The more you can push into your view, the more you can delete controller code, the more model code becomes a glorified "save" button. If your data is well-formed, and/or semantic, this model code can be very simple. Games can be a lot like this as well - after you've loaded your geometry, pushing everything off to the GPU means your "game" code can be focused on simple things. Advanced things like physics and collision can be handled by actor-event logic. Controllers are still there to do some puppeteer-ing and models exist so save and networking code works. Even databases can be view-heavy. A lot of database work amounts to building views of the same set of tables. Some analysis is done on the views, maybe, but keeping everything in normalized tables means losing out on view caching. Possibly this is more how vector databases work, as part of the data is where the data is not just what type the data is or which table it happens to be in. Of course, none of this works great for heavy-networking cases (lots of net-code, lots of multiplayer events, lots of cross-database replication), but those are maybe less interesting to me - I prefer decentralized distributed models anyways. I generally value having more functionality at the local compute node, versus some monolithic service that may fail in a couple years time on the other side of the planet. But that's just me.
- nightpool 3y agothat's fine! I'm happy with heavier views. The thing i'm arguing against is the Rails pattern of having FooBarService classes that are effectively just a single method and cobbled together in completely random ways instead of using actual model methods.
- pmichaud 3y agoI use services, but they are not a random grab-bag of methods. What do you even have in mind when you say this?
- zerbinxx 3y agoI too use services and they are where the business logic lives. In the case of “create user” they’re basically no-op repository methods, in the case of “sync user profile data” they may invoke storage or external service calls in a certain business-logical order, but they map exactly to the applicable domain(s) - putting user-profile methods in the user service is when you end up with muddled service boundaries
- cies 3y agoYou start with MVC, following "the fat-model, skinny controller" rule of thumb. Now the Models become obese. So you split out the Repository logic. Now you need a place to do "client onboarding" which creates a Customer, a User, a BillingInfo, a bunch of things to show the new client a non-empty environment... Where does this live? In the Customer model? Nah. In a repository? Certainly not. No. That's when the OnboardingService comes along. note: We use jOOQ so our "Model entities" are generated from the db schema and thus logic-less.