Hiding Data Access & Boundaries
In programming, it’s easy to distinguish between command and query method calls just by looking at them. When a method returns a value, it’s called a query, which puts the caller responsible for handling that value by traveling to the left. On the other hand, a command method call is when we don’t expect to receive a value, just a side effect, and it travels to the right. If you use a compass to navigate your code, you’ll see that queries go westward while commands go eastward. It took me a while to understand this concept, but looking at my code made it easier to grasp.
A Query method allows access to data within an object. The object providing the data must ensure that consumers do not cause issues. For programmers, the inflection point occurs between the Query method being called and the value being returned. The provider must enforce these values.
Object-oriented design is about managing dependencies; that statement is still true, but it’s just one truth about design.
To improve Encapsulation in an object, it’s best to hide data access behind methods and send messages to access variables instead. Start each class definition with as many private methods as possible to identify if the object is doing too much quickly. However, data access should be handled differently. By limiting access to the object’s internal state, external users are prevented from altering its structure. This small optimization can significantly enhance Encapsulation in an object.
Encapsulation refers to grouping data with the methods that manipulate that data. Encapsulation conceals an object’s information, represented by its data or internal state. This is important because it increases coupling when objects access each other’s internal data. The concept of “Tell, don’t ask” is central to information hiding, but it can be challenging because it assumes that an object should always know what to say or answer.
In Ruby, a practical way to enforce Encapsulation is to always return “self” from every method that modifies the state. This improves Encapsulation by defining clear boundaries between objects and reducing the risk of exposing internal structures. Objects should be owners of their data and responsible for disclosing methods to access that data.
[¹]: Practical Object-Oriented Design: An Agile Primer Using Ruby