4 ms·
That implicitness is part of the problem. In an object, all the functions implicitly take that state (or explicitly don't if you mark them static). So instead
by frobozz 7y ago
That implicitness is part of the problem.
In an object, all the functions implicitly take that state (or explicitly don't if you mark them static).
So instead of namespace::function(arg1), you now have namespace::function(obj, arg1), even when your function has nothing to do with obj. From the outside, you then have to wonder which members of obj might be being read or written inside the function. If lots of those methods call other methods, which may or may not modify the state of the object, you can end up in a situation where it's hard to reason about the functions because you have to read a lot of code to work out what the inputs and outputs really are.
This is the problem in the Java-style "everything must be a member of a class" approach. People have a tendency to make everything into members of objects.
A function that only takes the values it needs is much easier to reason about.
I think that you are right in that there isn't much practical difference between the two approaches when well-written (in particular when staticness/mutability/constness are clear). However, I find poorly written OO (e.g all methods are instance methods, local variables stored as members) to be really tricky to reason about, and all too common. I haven't had that problem with poorly-written non-OO code.
- UncleMeat 7y agoI think this can reasonably be described as a footgun rather than a bad design. Instance methods should relate to the state of the instance. If they don't that's a poor design choice. This is a pretty easy code smell to reject in code review. Perhaps Java would be cleaner if it had free functions. But this isn't so different than a big class that has a pile of static methods. C++ also addresses the "you have to wonder what members might be read or written inside the function" by encouraging the use of "const" as much as possible. You get really nice invariants preventing surprise state changes in receiver objects and other parameters through judicious use of "const", even if everything is a class or object.
- frobozz 7y ago> This is a pretty easy code smell to reject in code review. It is if the code was reviewed. If, OTOH, it just grew until something needs to be done (like the object with 60 public methods that I'm currently trying to refactor), you can have a devil of a time unpicking it. The same could be true where free functions are preferred, but it seems that most programmers seem to have grasped the idea that global variables are hard. > by encouraging the use of "const" as much as possible. I'm a big fan of const-correctness. I haven't written C++ in years, but I always used to love putting 'const' everywhere.
- UncleMeat 7y agoIf you aren't doing code review then no design principles will save you.
- frobozz 7y agoBut that's the point I'm trying to make - Over my career, I have inherited bad code in both styles - "prefer objects" and "prefer functions". In my experience, bad objects tend to be a nightmare. Bad free functions tend to just be a bit annoying. There are only two ways in which code review can keep your codebase clean in this situation: Stop doing any other development until it's all nice, or invent time travel.