Software Development

Can Objects Be Friends?

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.

Raging Bull (1980) by Martin Scorsese

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?

You may also find these related posts interesting: Encapsulation Covers Up Naked Data; How Much Your Objects Encapsulate?; Object Behavior Must Not Be Configurable; How an Immutable Object Can Have State and Behavior?; Gradients of Immutability;

JavaScript is disabled in your browser, that’s why you can’t see comments under this post.

Reference: Can Objects Be Friends? from our JCG partner Yegor Bugayenko at the About Programming blog.

Yegor Bugayenko

Yegor Bugayenko is an Oracle certified Java architect, CEO of Zerocracy, author of Elegant Objects book series about object-oriented programing, lead architect and founder of Cactoos, Takes, Rultor and Jcabi, and a big fan of test automation.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Cromm
Cromm
7 years ago

Nonsense. What’s the problem of delivering a getTemperature() method?
Also, the class Temperature should be declared abstract, then other two classes — Celsius and Farenheit — should be created and inherit from Temperature. Both subclasses should have methods like toFarenheit() and toCelsius().

Alain
Alain
7 years ago

A nice example of tight coupling

Back to top button