| These discussions tend to boil down to OOP vs FP. That's a false dichotomy. The alternative to OOP is not FP, it's pre-OOP imperative programming with various techniques a la carte. Should data and functions be together? That's a choice you can make on a case-by-case basis. It makes total sense that a HashMap has an insert() method. On the other hand, maybe your Player object is just some data which is interpreted by a PhysicsSystem and MovementSystem etc. Maybe it's clearer that all the physics calculations are in a common PhysicsSystem rather than being spread out into several implementing classes. Should you use a switch-statement or a polymorphic interface? If you're traversing a graph with a fixed set of nodes, or you need to change all systems when new nodes arrives, the (exhaustive) switch may be preferable. I'd certainly prefer it to the visitor pattern. If you can extract a calculation into a pure function, then that's great. If you're doing something inherently stateful, FP techniques are probably not too great. Maybe you can afford a high-level functional interface, but keep the implementation stateful. The problem with OOP, FP, etc. is not that the techniqures are BAD, it's that all techniques are trade-offs. We're very good at talking about the advantages of some technique, but seem always forget the costs associated with it. |
The problem is that not many things actually need to be an object. But when something needs to be one, there is no distinction. No way to tell whether somebody made a thing an object, because it makes sense or just because that's the only way he could make it. So you have all those User/DateFormatter/Encoding objects for no reason, but language limitation. And then, on top of that, when you want an actual object, something that does its thing, have internal state and an interface to communicate (not a method call), you are on your own.