3 ms·
The problem with the OO style taxonomy is that doesn't just model the taxonomy but it also structures your code, that's usually where the problem is, and it lea
by sirwhinesalot 5y ago
The problem with the OO style taxonomy is that doesn't just model the taxonomy but it also structures your code, that's usually where the problem is, and it leads to issues like what is the proper superclass: Square or Rectangle.
A square is a kind of rectangle but the "API" of a Square is more restrictive than that of a Rectangle (where both width and height can change independently). I've seen this issue discussed in either this year's or last year's CPP-CON...
- seanmcdirmid 5y agoIf the square and rectangles are not mutable, you can indeed treat a square as a rectangle (however you want to express that type). If they are mutable, then a square is of course not a rectangle. In OOP systems that support predicate-style dynamic inheritance, rectangles pick up the square trait only when their width is equal to their height. We don't talk about such systems very much today (JavaScript does not have a notion of type, and updating an object's type is a mutable operation rather than one driven by a rule), but there were experimental systems from the 90s that looked at this.
- sirwhinesalot 5y agoPretty cool to hear about those, didn't know there was such a dynamic approach to the problem. Either way, the problem in my view is that the question is silly to begin with, Squares and Rectangles should be PODs (or, even better, simple structures), and not have any associated behavior. The decision of whether they are mutable or not then depends solely on the needs of the software, and not on irrelevant modelling constraints unrelated to the problem. There's no need for them to have a taxonomy relation unless the problem being solved involves taxonomies of shapes.
- nec4b 5y agoWhat have you solved by having squares and rectangles as PODs? Now you won't be able to treat them as same in some way (e.g. IShape, IDrawable, IPrintable, IArea,...) and you will need twice as many functions for doing same things.
- sirwhinesalot 5y agoIf you make a square and a rectangle into IShapes (with no inheritance hierarchy) you still need 2 separate implementations for GetWidth(). Either way, it's simply not true that you can't treat them the same way because you've made them PODs, there are more kinds of polymorphism beyond subtype polymorphism. Even for the latter modern languages split the data (structs) from the behavior (traits/protocols), see Rust or Swift for example. If you explicitly need to treat squares and rectangles as a single entity to draw them (alongside other shapes), rather than thinking of each of them having a "draw()" function (likely breaking the single responsibility principle), you should instead have a function square_to_drawable, rectangle_to_drawable etc, where a drawable is also a POD but one that has the relevant drawing data (textures, triangles, whatever). Then a drawing system is responsible for actually rendering these drawables. That's how it's done on modern game engines. It takes a while to wrap your head around but it works really well. This style is used a lot by modern game engines because performance is way better with this style.
- nec4b 5y agoEverything you are describing is still OOP. Again, inheritance in not necessarily the best tool to model all relationships.
- sirwhinesalot 5y agoThe most basic principle of OOP is the bundling of behavior and data. If you don't have that, you don't have OOP. PODs + independent functions is not OOP. ECS-style designs are not OOP because ECS-style designs are PODs + independent functions (it's a relational model). OOP and the relational model are not equivalent, if they were the object-relational impedance mismatch wouldn't exist. Polymorphism exists independently of OOP. OOP is not the only way to model relationships. OOP is not the only way to encapsulate data. OOP is not the only way to abstract things. Sometimes it is by far the best way to do all three. That's when you use it, not because of some silly attempt at purity of style. People have a really distorted view of procedural-style programming where it's all global variables and copy pasted code. Couldn't be further from the truth. Even within OO codebases you have tons of procedural-style code that just happens to be stored in a class with the little "static" keyword in front. Many "procedural" codebases (i.e. stuff written in C) have lots of OO-style code with structs full of function pointers. But it's wrong to say that it's all just OOP in disguise. If behavior and data are not bundled it's not OOP, and most code doesn't need that, not even when you need abstraction + polymorphism. Encapsulation is the main one where OOP is often the best approach.
- dragonwriter 5y ago> The problem with the OO style taxonomy is that doesn't just model the taxonomy but it also structures your code, that's usually where the problem is, and it leads to issues like what is the proper superclass: Square or Rectangle. “Rectangle" is a superclass of “Square”, if you are referring to the entities in geometry. > A square is a kind of rectangle but the "API" of a Square is more restrictive than that of a Rectangle (where both width and height can change independently) Neither the width nor the height of either can change without changing the identity, just as neither the whole or fractional part of a real number can change without changing what number it is. If you've got something with mutable side lengths, it's no longer a Square or Rectangle, it's probably some kind of Drawable that might have a mutable state variable for position and a mutable state variable for a shape, but just as numbers, but geometric shapes themselves, like numbers, are immutable values (they can be in a mutable container, but then you are changing which one is in the container, not changing the shape while retaining it's identity.)
- sirwhinesalot 5y agoThe Square vs Rectangle issue is just an example. They shouldn't even be modeled as a hierarchy they should just be simple structs. It's just an example on how OO taxonomies are a silly (and detrimental) exercise.
- dragonwriter 5y ago> The Square vs Rectangle issue is just an example. Yes, it's an example of a problem that has nothing to do with OOP and everything to do with applying model concepts from one domain to a different domain. > They shouldn't even be modeled as a hierarchy they should just be simple structs. Whether they are structs or objects with state and attached methods is an orthogonal concern to whether they form a type heirarchy. It's true that geometric squares and rectangles make sense as value types like structs. They also form part of a natural heirarchy that it is perfectly useful to leverage in code. > It's just an example on how OO taxonomies are a silly (and detrimental) exercise. Except that isn't what it is an example of. It's an example of why you can't apply a heirarchy from geometry to things which don't represent the concepts that heirarchy applies to. It doesn't show that OO taxonomies are silly or detrimental.