4 ms·
The #1 complaint I always see with classes is due to inheritance. When classes inherit from classes that inherit from other classes, you can very easily end up
by remmargorp64 7y ago
The #1 complaint I always see with classes is due to inheritance. When classes inherit from classes that inherit from other classes, you can very easily end up with a tangled web of methods over-riding and extending other methods, and run into all sorts of unexpected behaviors and difficulties wrapping your head around what is going on.
This is why (at least in the Ruby world), it's generally considered best practice to avoid using inheritance and just use mixins instead (whenever possible).
Completely avoiding classes because you are using them incorrectly is kind of like throwing the baby out with the dirty bathwater. Don't throw away your tools just because you are using them incorrectly!
- arcosdev 7y agoI'm not sure how using mixins is better. Now you don't know half the time what is overriding what. Composition seems to be the better tool IMHO.
- dyeje 7y agoAren't mixins a form of composition?
- arcosdev 7y agoI would argue no they are not. I am thinking of their implementation in python specifically, so my understanding is likely skewed. My notion of composition with classes would be: class Dog(object): def __init__(): self.wagger = Wagger(); #composing the Wagger class in python mixins look like this: class Dog(object, WaggerMixin): ...etc...
- babypuncher 7y agoIf I had a nickel for every blog post I've seen highlighting an incorrect usage of a pattern as a reason not to use the pattern at all...
- Vinnl 7y agoAren't classes in Javascript mostly syntactic sugar to make inheritance easier?
- crimsonalucard 7y agoInheritance is a debate that already ended long ago with OOP practitioners vehemently against it. The argument now is different. There is another flaw with classes and that is mutation of internal variables with getters and setters. Classes typically allow you to do this and promote this behavior, structs do not typically allow you to do this and are not used this way, typically. It makes it so that a class is more than just a data type, it is a mini program with it's own internal state and api that you are passing around in your program. It ups the complexity of your program by 10 fold.
- T-hawk 7y agoThis is a great post. "A mini program with its own internal state and API" is a great description of what goes wrong with overdesigned classes. Encapsulating state into classes originally made sense with early OOP languages, compared to all of it being global which is even worse, but nowadays we've got better ways of managing complexity. Any time something threatens to be a mutable class-level variable, I refactor that out of the design before proceeding. Most often this refactoring is to separate the data into a struct-like class and the behavioral methods into a static class, with what would have been that mutable class-level variable instead passed in to each behavioral function that needs it.
- meheleventyone 7y agoI feel like you missed a bit of the explanation out there. Where does the struct like class end up being instantiated and how is it linked to the class that presumably would have previously contained it? Does the struct like class get put into some kind of data store and the class that needed mutable state then holds a handle or similar?