|
> Every display object has a x y width and height for example. Intuitively¹, I feel like this is something that should be separated out into a BoundingBox object. Every component that needs a bounding box satisfies a small `HasBoundingBox { getBoundingBox(self) -> BoundingBox }` interface. Maybe there's a larger `Resizeable` interface which (given a type that satisfies `HasBoundingBox`) specifies an additional `setBoundingBox(self, bb)` method. You don't end up with a tidy hierarchy this way, but I'm not sure you'd end up with a tidy hierarchy using inheritance, either. I feel like this sort of UI work leads toward diamond inheritance, mixins, or decorators, all of which complicate inheritance hierarchy. Flat, compositional design pushes you toward smaller interfaces and more explicit implementations, and I like that. The verbosity can be kept in check with good design, and with bad design, the failure mode leans towards more verbosity instead of more complexity. For more complicated features, composition & interfaces can make things more verbose, but honestly I like that. Inheritance's most powerful feature is open recursion (defined in the linked article), and I find open recursion to be implicit and thorny. If you need that level of power, I'd rather the corresponding structure be explicit, with builders and closures and such. [1]: Not saying this is correct, but as someone who prefers composition to inheritance, this is what feels natural to me. |
Well, I am sure, that all the graphic libaries I ever used, had this inheritance model. (The graphics libary I build, as well.)
The libaries I have seen, that used a different model, I did not really like and they were also rather exotic, than in wide use. But I am willing to take a look at better designed succesful inheritance free ones, to see how it can be done,.if you happen to know one ..