As discussed before, proper encapsulation leads to a complete absence of ânaked data.â However, the question remains: How can objects interact if they canât exchange data? Eventually we have to expose some data in order to let other objects use it, right? Yes, thatâs true. However, I guess I have a solution that keeps encapsulation in place while allowing objects to interact.
Say that this is our object:
class Temperature {
private int t;
public String toString() {
return String.format("%d C", this.t);
}
}
It represents a temperature. The only behavior it exposes is printing the temperature in Celsius. We donât want to expose t, because that will lead to the ânaked dataâ problem. We want to keep t secret, and thatâs a good desire.
Now, we want to have the ability to print temperature in Fahrenheit. The most obvious approach would be to introduce another method, toFahrenheitString(), or add a Boolean flag to the object, which will change the behavior of method toString(), right? Either one of these solutions is better than adding a method getT(), but neither one is perfect.
What if we create this decorator:
class TempFahrenheit implements Temperature {
private TempCelsius origin;
public String toString() {
return String.format(
"%d F", this.origin.t * 1.8 + 32
);
}
}
It should work just great:
Temperature t = new TempFahrenheit(
new TempCelsius(35)
);
The only problem is that it wonât compile in Java, because class TempFahrenheit is not allowed to access private t in class TempCelsius. And if we make t public, everybody will be able to read it directly, and weâll have that ânaked dataâ problemâa severe violation of encapsulation.
However, if we allow that access only to one class, everything will be fine. Something like this (wonât work in Java; itâs just a concept):
class TempCelsius {
trust TempFahrenheit; // here!
private int t;
public String toString() {
return String.format("%d C", this.t);
}
}
Since this trust keyword is placed into the class that allows access, we wonât have the ânaked dataâ problemâwe will always know exactly which objects posses knowledge about t. When we change something about t, we know exactly where to update the code.
What do you think?
P.S. After discussing this idea below in comments I started to think that we donât need that trust keyword at all. Instead, we should just give all decorators access to all private attributes of an object.
