5 ms·
That is an atrocity on so many levels. For one, you're creating a hard coupling to a specific flavor of SQL. And that's not too mention the fact that you're ta
by JustLurking2022 4y ago
That is an atrocity on so many levels.
For one, you're creating a hard coupling to a specific flavor of SQL. And that's not too mention the fact that you're taking an otherwise purely data object and embedding persistence logic into it - a horrifying abuse of OO.
- asalahli 4y ago> you're creating a hard coupling to a specific flavor of SQL. I fail to see why this is a problem. Switching databases is a costly move, and is pretty rare as far as I know. When it does happen, it is usually from one type of db to another type, not between two RDBMSs. IMO it doesn't, by itself, justify sticking to an ORM rather than raw SQL.
- JustLurking2022 4y agoI do it all the time - I use SQLite for testing and something else in production.
- lenkite 4y agoSwitching databases can be an easy move depending on how you design schemas, versioning and migration. We have a multi-cloud, multi-db offering - customers choose their DB. Without ORM, this would not be feasible.
- ajgrover 4y agoMany/most ORMs (the ones that follow the ActiveRecord pattern) do this as well though. I prefer to avoid mixing concerns and use datamapper-based ORMs myself, but what GP wrote is fundamentally not that different than what a lot of ORMs do.
- JustLurking2022 4y agoI'd dispute "most", as it does not match my experience across a number of languages. Yes, active record sorta does it but, as best I recall, those methods are all implemented generically as mixins, so not actually a part of the data object. This seems to be advocating for data specific queries to be added to each class.
- ajgrover 4y agoRails and Django are both AR, and are still probably the two most widely used backend frameworks, for better or for worse. I don’t disagree with the overall point you’re making, I’m just pointing out that it’s very common
- JustLurking2022 4y agoUmmm... No. See my previous comment - at least in Rails, the queries aren't part of the data object themselves, but are instead mixins or default handlers (don't recall which offhand), so it's really just syntactic sugar that makes it appear as though they are methods on the data class. Even if they did the same thing you're suggesting, by that logic, we should all use PHP because WordPress does, and it's probably more popular than those two combined. Take a look at something like Spring or Entity Framework to see other takes on ORM patterns. And again, you're trying to argue against ORMs, while citing that your suggested alternative is supported by the way ORMs do it.
- ajgrover 4y agoI’m not the person that suggested handwriting object methods. As I’ve said, I agree with the point you’re making, I’m not arguing with you, or for any specific ORM design. I don’t see what the nuance is you’re getting at with the mixin vs object method argument though. They both have the same issues around testability and violation of SRP.
- JustLurking2022 4y agoAhh, apologies misread the tree. In terms of the nuance around a mixin vs object - a mixin can be defined and tested in its own separate library independent of your data model, so it's at least cleaner in terms of separation of concerns.
- ajgrover 4y agoThat’s fair. My issue with the mixin approach is that then your app code can hit the database from anywhere you have access to the model object, which makes testing your own code in isolation much more difficult
- gwbas1c 4y ago> you're creating a hard coupling to a specific flavor of SQL You're just trading one coupling (specific flavor of SQL) to another (your ORM.) Assuming your application is layered correctly, when you write your own queries, all of your SQL queries are in a single place and can be updated. BUT: If you're using an ORM, and you let your data bound objects leak into all layers, the coupling is much much much harder to fix if you chose to change your ORM. IE, if you do things like lazy loading, or construct your queries in business logic, switching ORMs will be extremely painful. I've done it both ways (write my own SQL and use an ORM) and I would say the single biggest mistake is to assume that you absolutely should (or shouldn't) use an ORM.
- JustLurking2022 4y agoNot at all - in most architectures, your data objects know nothing about how they are being stored, instead delegating that to a repository class or something similar. Adding persistence logic to a data object adds all kinds of bloat - it has to have a connection to the database, which now makes unit testing a pain in the neck and introduces all kinds of weirdness around serialization. Now it has a bunch of CRUD methods, so developers have to know which methods are for business logic versus persistence. Also, data objects with persistence logic aren't really suited to be published in a shared library as clients should not access your database directly. All around, it's just a really terrible idea.
- gwbas1c 4y ago> Adding persistence logic to a data object adds all kinds of bloat That's not what you do if you write your own queries. That's what a novice does after learning object oriented programming. For a more accurate example, look at things like Hibernate / NHibernate / Entity Framework and lazy loading. They inherit from classes at runtime and will transparently run queries as business logic navigates relationships on an object graph. It's "not wrong," but it can lead to all kinds of problems and painful refactors. (But it's totally "worth it" in prototypes, one-offs, and throwaway code.) If you don't do lazy loading, Entity Framework still requires that you pre-declare which relationships you will traverse. It's intended that your business logic uses Entity Framework APIs to say what part of the object graph it will use. (Thus tightly coupling your application to your ORM, which means your trading tightly coupling to a database to tightly coupling to a framework / library.) But, keep in mind that the ORMs I mentioned tie the objects to the database connection. It isn't quite as intense as "Adding persistence logic to a data object", but they do track that, if you modify an object, it can only be saved on the transaction that it was loaded from; or if you're using lazy loading, lazy loading only works if the transaction is still open. If you build a layer around your data access code that fully shields your business logic from your ORM, you've "done it right." But, at that point your ORM's value becomes negligible, because from the perspective of your business logic, it doesn't matter if your data access layer has hand-optimized SQL or an ORM; but you've lost one of the real selling points of an ORM, which is that you can easily do your data access from within your business logic. Which is why I say that the biggest mistake is assuming you should, or shouldn't, use an ORM.