Not the Dragonball Z kinda style

Introduction

Following the 4 pillars of object oriented programming

I am going to talk about encapsulation today. In my article about abstraction I gave a sneak peak about the usage of encapsulation to achieve it. Basically speaking encapsulation is the process of putting all data and operations performed on that data into one single container while limiting access to it. Thus, encapsulation is all about information hiding and implementation hiding.

The Problem with this problem

In the world of object oriented programming we put our variables (data) and methods (operations) into our classes (container). I will again take the Preferences.class as an example. Look at the following code:

[pastacode lang=”java” manual=”public%20class%20Preferences%20%7B%0A%0A%09HashMap%3CString%2C%20Object%3E%20allPrefs%20%3D%20new%20HashMap%3C%3E()%3B%0A%0A%09Persister%20persister%20%3D%20new%20FilePersister()%3B%0A%0A%09public%20Preferences()%20%7B%0A%09%09persister%20%3D%20new%20FilePersister()%3B%0A%09%09allPrefs%20%3D%20(HashMap%3CString%2C%20Object%3E)%20persister.load()%3B%0A%09%7D%0A%09%0A%09Object%20getPreference(String%20key%2C%20Object%20defaultValue)%20%7B%0A%09%09Object%20pref%20%3D%20allPrefs.get(key)%3B%0A%09%09return%20(pref%20%3D%3D%20null)%20%3F%20defaultValue%20%3A%20pref%3B%0A%09%7D%0A%0A%09void%20setPreference(String%20key%2C%20Object%20value)%20%7B%0A%09%09allPrefs.put(key%2C%20value)%3B%0A%09%09persister.persist(allPrefs)%3B%0A%09%7D%0A%7D” message=”” highlight=”” provider=”manual”/]

What do you think is wrong with this class? We took all our variables and methods and put them into one class. Great success on this part. But what about the information and implementation hiding? Let us now assume we have another class that uses our Preferences.class. We instantiate a new preferences object and try to save some preferences. We are now able to do some shenanigans like:

[pastacode lang=”java” manual=”preferences.allPrefs%20%3D%20new%20HashMap%3C%3E()%3B” message=”” highlight=”” provider=”manual”/]

or

[pastacode lang=”java” manual=”preferences.persister%20%3D%20null%3B” message=”” highlight=”” provider=”manual”/]

which definitely can and will lead to huge problems. So what to do? Let’s call the Avengers!

Refactoring baby

First we will have a look at how we can hide information. Typically information hiding is done by using access control on your variables and methods. This is done by declaring your variables and methods either private, public or protected. We then end up with:

[pastacode lang=”java” manual=”public%20class%20Preferences%20%7B%0A%0A%09private%20HashMap%3CString%2C%20Object%3E%20allPrefs%20%3D%20new%20HashMap%3C%3E()%3B%0A%0A%09private%20Persister%20persister%20%3D%20new%20FilePersister()%3B%0A%0A%09public%20Preferences()%20%7B%0A%09%09persister%20%3D%20new%20FilePersister()%3B%0A%09%09allPrefs%20%3D%20(HashMap%3CString%2C%20Object%3E)%20persister.load()%3B%0A%09%7D%0A%0A%09public%20Object%20getPreference(String%20key%2C%20Object%20defaultValue)%20%7B%0A%09%09Object%20pref%20%3D%20allPrefs.get(key)%3B%0A%09%09return%20(pref%20%3D%3D%20null)%20%3F%20defaultValue%20%3A%20pref%3B%0A%09%7D%0A%0A%09public%20void%20setPreference(String%20key%2C%20Object%20value)%20%7B%0A%09%09allPrefs.put(key%2C%20value)%3B%0A%09%09persister.persist(allPrefs)%3B%0A%09%7D%0A%0A%7D” message=”” highlight=”” provider=”manual”/]

If you now want to use the instance of the Preferences.class, you can only set or get preferences. The API only exposes the methods the user needs to interact with the class. Exactly as intended.

Now let’s have a look at implementation hiding. As the name already states, we use inheritance to hide specific implementation details. Let’s have a look at our example. You might have noticed the

[pastacode lang=”java” manual=”public%20class%20Preferences%20%7B%0A%0A…%0A%0A%09private%20Persister%20persister%20%3D%20new%20FilePersister()%3B%0A%0A…%0A%0A%7D” message=”” highlight=”” provider=”manual”/]

The Persister actually is an interface and the FilePersister is an implementation of the interface. They look as follows:

[pastacode lang=”java” manual=”public%20interface%20Persister%20%7B%0A%09public%20void%20persist(Object%20obj)%3B%0A%09public%20Object%20load()%3B%0A%7D” message=”” highlight=”” provider=”manual”/]

[pastacode lang=”java” manual=”public%20class%20FilePersister%20implements%20Persister%20%7B%0A%0A%09private%20File%20file%20%3D%20new%20File(%22definitely%2Fnot%2Fthe%2Fpath%2Fto%2Fmy%2Fdesktop%22)%3B%0A%0A%09%40Override%0A%09public%20void%20persist(Object%20obj)%20%7B%0A%09%2F%2F%20ommited%20for%20simplicity%0A%09%7D%0A%0A%09%40Override%0A%09public%20Object%20load()%20%7B%0A%09%2F%2F%20ommited%20for%20simplicity%0A%09%7D%0A%0A%7D” message=”” highlight=”” provider=”manual”/]

As you can directly see, the FilePersister hides all his internal functionality inside the class and just exposes the methods inherited from the Persister interface. This allows us to implement another Persister, e.g. a DatabasePersister and simply exchange the Persister within our Preferences.class without breaking any code. And that, ladies and gentlemen, is the true power of object oriented programming.

What have we learned?

As we saw, encapsulation is the process of hiding internal variables and methods within a class from other classes. The true power of encapsulation lies within the two concepts of

  • information hiding by using access control
  • implementation hiding by using interfaces

In the final article of this series we will implement more Persister interfaces and have some fun with them.

Categories: Blog Posts