3 ms·
> However, the only way to prevent two unrelated objects from manipulating the same part of the state is to create a tree, i.e., a strict hierarchy between all
by baryphonic 5y ago
> However, the only way to prevent two unrelated objects from manipulating the same part of the state is to create a tree, i.e., a strict hierarchy between all objects in the system.
I see this claim from time to time, and perhaps it's true in typical Java, C++ or even Python, but I don't think I've ever seen anything close to a proof of it. I suspect it is false, since an interface boundary that leaks no state is possible to implement and can give freedom to the designer regarding internal state.
> If, on the other hand, you treat your data as just data, preferably flat and immutable, and keep the code that acts on it separate, then you won't run into this problem. You will be able to change the parts of the code that act on the data structures independently.
This claim is true only insofar as the underlying state being tracked doesn't change much through the lifecycle of the program in development, which is a reasonably good assumption for a game, but not for most other applications.
The problem is that "data" by definition does not capture all of its own invariants. I have personally witnessed long-lived codebases suffer from brittleness when multiple areas of code must read from and manipulate the same underlying data structure. Inevitably, some programmer on the team forgets one of the invariants, since they aren't specified in code (which would make it OO), and then we have a production bug. The solution is then usually to add another "if" statement somewhere. The solution thus makes the code harder to understand and thereby increases the likelihood of this kind of bug related to this particular structure recurring.
- taffer 5y ago> [...] an interface boundary that leaks no state is possible to implement and can give freedom to the designer regarding internal state. Your suspicion is justified. As long as the objects only send immutable messages to each other, encapsulation remains intact. But then you have something closer to an actor system than what people typically think of when they say OOP. Once you pass references to mutable objects, all bets are off. The ability to specify which states are allowed and which are not, is not a special feature of OOP. In the functional and relational paradigms, there are types and constraints that specify in a declarative way what states should be possible. Types and constraints are enforced by the runtime and are not based on (leaky) encapsulation.
- baryphonic 5y ago> But then you have something closer to an actor system than what people typically think of when they say OOP. This is fair. I tend to think of OO per Alan Kay's description, i.e. message passing, encapsulation and extreme late-binding.[0] That does look closer to actors or even FP than it does the so-called OOP languages, which is what most might think. > The ability to specify which states are allowed and which are not, is not a special feature of OOP. In the functional and relational paradigms, there are types and constraints that specify in a declarative way what states should be possible. Types and constraints are still code that are tightly bound to the data they describe (since in a real sense, they are executed, either at compile time or runtime, and the most powerful type systems are Turing complete). The data oriented advocates sometimes forget this when decrying code tightly coupled to data. As types and constraints are added to specify only the proper behavior, the data gains more signal and less noise, and thus becomes more like information and less like data. [0]http://www.purl.org/stefan_ram/pub/doc_kay_oop_en http://www.purl.org/stefan_ram/pub/doc_kay_oop_en