3 ms·
OO aims at making future and unforeseen changes easier, I just don't think it achieves its aim. I am also not sure that a discussion on HN is the best medium t
by taffer 5y ago
OO aims at making future and unforeseen changes easier, I just don't think it achieves its aim.
I am also not sure that a discussion on HN is the best medium to discuss the problem in depth. Nevertheless, I will try to give a practical example:
Suppose you have parts (part_id, description, quantity_on_hand) and suppliers (supplier_id, name). Also, each part is manufactured by multiple suppliers and each supplier manufactures multiple parts. How do you model this? Do you let parts reference suppliers or suppliers reference parts, or do both reference each other? Or do you define a third class PartsSuppliers that manages the references? There is no formal method in OO that tells you what is a sound design choice and what is not. Let's say you chose the latter option (PartsSuppliers) and you need to write a method that computes statistics about the parts. Where do you place this method? You need to add it to PartsSuppliers, because no one else is allowed to have private references to Parts, otherwise you would break PartsSuppliers' encapsulation. No matter what design decisions you make in OOP, you will always have to make a tradeoff between encapsulation of state and extensibility.
- mytailorisrich 5y ago> There is no formal method in OO that tells you what is a sound design choice and what is not. System architecture is hard. OO design is a set of principles that helps you design a system better by making it easier to maintain and modify. It does not tell you how you should model your objects. To come up with a good model is usually not straightforward. In fact your example is not an issue specific to OO design. This is a general issue of relationships ('many to many') and there are a number of design principles to help (see database design principles as that's a typical scenario in databases). > Where do you place this method? You need to add it to PartsSuppliers, because no one else is allowed to have private references to Partts That's not true, but as you say, this is too vast a discussion.
- taffer 5y agoI try to put it another way, because it is a much more general problem of OOP: If you have an object A that references an object B and object B references C and A wants to know something about C, we always have to go through B, regardless of whether we are actually interested in B or not. This is because C is part of the private state of B, and if A had a direct reference to C it could mutate C and would therefore break B's encapsulation. > In fact your example is not an issue specific to OO design. This is a specific problem with nested data structures. OO design leads to nested data structures to allow encapsulation. The relational answer to this problem would be to break everything up into flat sets of tuples that can be joined as needed, but if everything is just flat data, you can't have encapsulation.
- mytailorisrich 5y agoBut this is not a good example. Either this should be modelled so that A can directly reference C to start with, or indeed A has to go through B but can do so to get a reference to C (this does not break encapsulation in itself, it depends on the specific relationships) It's impossible to avoid nested data structures because these are simply the natural consequence of the system's complexity. For instance, a book is made of sheets, pages, chapters, sentences, illustrations, etc. entities with nested relationships.
- taffer 5y ago> Either this should be modelled so that A can directly reference C to start with, or indeed A has to go through B but can do so to get a reference to C (this does not break encapsulation in itself, it depends on the specific relationships) If A has a reference to C, B cannot, and if B has a reference to C, A cannot. To keep encapsulation intact, references between objects must form a tree. OOP depends on the partitioning of mutable state for maintainability reasons. There is no other way to keep this partitioning intact than to have a tree of objects. > It's impossible to avoid nested data structures because these are simply the natural consequence of the system's complexity. This is a purely conceptual view. But you don't have to query it that way at a logical level, or organize it that way at a physical level via memory references. HN comments, for example, are conceptually contained in their parent comments and also conceptually contained in the users who wrote them. In a relational database, on the other hand, the tuples would be contained only in their relations/tables. A query could then associate comments with users at runtime, but comments can be queried on their own, since they are not encapsulated in anything. In OO design, on the other hand, all access paths are baked into the object trees, making later, unforeseen changes to the software extremely difficult without taking shortcuts in the tree and thus destroying the encapsulation.
- mytailorisrich 5y ago> If A has a reference to C, B cannot, and if B has a reference to C, A cannot. That's not what encapsulation means, and again, it's up to you to come up with a model that makes sense. > In a relational database, on the other hand, the tuples would be contained only in their relations/tables. A query could then associate comments with users at runtime, but comments can be queried on their own Sure but they are still 'nested' by way of relationship. Of course you don't have to physically nest structures within structures. Both make valid OO implementations. Nothing in OO prevents you from querying comments on their own.
- urthor 5y agoYou're not wrong about what you describe. But maintaining relational state between things is really annoying in general. You've mentioned one of the trickiest jobs there is, it's really hard even with purpose built databases. Doing it in an imperative environment is just hard.