The Importance of Code Encapsulation

Redan Hassoun
Oct 13, 2020 · 8 min read

Most of the developers, when they hear about encapsulation, they think of it as one of the fundamental concepts in object-oriented programming, and it means that the class (or any component of code) exposes only the relevant data to the outside world and hides the internal data as private members, but this principle is more general and powerful than a lot of developers think, and although it is defined in OOP, you can still apply it one way or another in other programming paradigms.

So, what is the encapsulation all about? What does it really mean, and why do we need it?

According to Wikipedia: “Encapsulation is used to hide the values or state of a structured data object inside a class, preventing unauthorized parties’ direct access to them. Publicly accessible methods are generally provided in the class (so-called “getters” and “setters”) to access the values, and other client classes call these methods to retrieve and modify the values within the object.”

But what does this really mean? When do we hide data\implementation, how, and for what purpose?

Let’s take a closer look at the encapsulation principle, this principle has two main important ideas:

1. Information Hiding:

What information hiding means is separating the interface of some code component (a function\class\module\library\ …) from its own internal implementation, the implementation details should be private and not accessible from outside, any changes to the state is done only using the public API (which is a set of functions\methods that defines what our code can do). The public API should be clear and enable the code users to use it without having to know the internal details. For example, if we have a UI library that helps us render a table of data on our page, if the library is well encapsulated, the developers who use the library doesn’t have to know everything about the internal implementation (which data structure is used to save the data, which algorithm is used to render and update the data, which mechanism is used for pagination and all other internal details, a.k.a: implementation details).

The client (developer) should have a clear and simple API that enables him to use the library without the need to read the internal code, the developer has to see only the things he needs to know about in order to operate that library, not less and not more.

So we can say that information hiding is defining a simple public interface which defines what operations our code can do, and “hide” the implementation of this interface internally, and every piece of logic that is related to that implementation in one place instead of writing code that is scattered around.

In order to do this properly, it is very important to define a good API (interface) for our code, but what is a good API?
In order to better sense this concept, let’s take the following method as an example:

String handleResponse(String response) {

}

Is it possible to know exactly what the function does without peeking into the code?

There are a couple of questions that arise when looking at this function, what is the meaning of the String return value? what should I do if the function returns null? what does exactly the function do to the response? Does it perform any side effects? …

Sometimes it is possible to read the code’s documentation in order to know how the methods\classes should be used, but we don’t always have documentation, or sometimes the documentation is written poorly or incomplete.

So the method signature plays a huge role when it comes to encapsulation and information hiding, and it should answer all the basic questions like what it does and how it is used.

These questions should be answered by the method’s signature (method name, the parameters it accepts, and the return value).

In order to fix the method in the previous example, the first thing that should be done is giving it a better name, the name should be a simple verb that describes exactly what the function performs (note that the function should perform only one thing and do it well — for more information read about the single responsibility principle). Also, it is better to use a data-type that describes the function’s parameter in an accurate way. And lastly, it is very important to choose the correct return type, if the function only performs a simple side effect then maybe there is no meaning for a return value. And if it must return something, the return type should be precise and prevent any ambiguity.

2. The protection of the invariants:

An invariant in general is a property of the program state that is always true, or more precisely a predicate that defines the valid state of an object, this predicate is expected to be maintained by the object’s operations and should be always valid.

For example, the “hasNext” method of the collection iterator returns false if and only if we have exhausted all of the collection’s elements, this invariant must always be true no matter when we call the method, no matter which method we call on our collection, that invariant will still be valid (the worst thing that can happen is that we perform an invalid operation, but in that case, an exception will be thrown as early as possible with useful information about the error).

So what “protection of the invariants” means is that our code should make sure the invariants are always true, and it is very difficult (even impossible) to put an object in an invalid state.

Let’s take a simple Java code example to illustrate this concept, imagine a class that represents a phone book:

class PhoneBook {   private List<Person> peopleList;   public void init(List<Person> peopleList) {      this.peopleList = peopleList;   }   public Person get(int id) {    ...
}
public void add(Person person) { ...
}
public int getCount() { return this.peopleList.size(); }}

And consider this usage:

PhoneBook phoneBook = new phoneBook();phoneBook.getCount();

Looks like the “getCount” method will throw an exception (because the init method was not called), so it was very easy to misuse the PhoneBook object and put it in an invalid state which means this object does not properly protect its invariants so it is not well encapsulated (in this case the developer who uses this class should look into the implementation in order to know how to use it properly), of course, this is only a simple example to illustrate the concept, in the real world, the code can be much more complex and if the code is written poorly, mistakes can waste a lot of time.

The simple solution for this problem would be to initialize the people list on the constructor and make sure to throw an exception if the object is created with a null value, that exception should have a clear message that explains exactly what went wrong (and never blame the user).

This leads us to the “fail-fast mechanism”, which is a mechanism that helps us build systems that report errors as early as possible rather than attempting to proceed with an incorrect behavior, and write error messages in a way that can help the client know what to do to avoid that error.

In addition, if an object has a value which is an invariant that is maintained by that object’s operations, we should prevent changing that value directly from outside the class, because if we do this the wrong way, we may end up with an invalid state on that object, for example, let’s say that this PhoneBook class tracks the count of phone numbers that is divisible by 3, if the class has a method that returns a reference to the “peopleList”, the users of this class can add/remove elements from the list without updating the count of the numbers that is divisible by 3, which brings the object to an invalid state, this issue will lead to unexpected bugs.

So in short, we should design our classes in a way that they manage their state properly and make sure that the users of our code cannot easily reach an invalid state, and if they do something wrong, they should get early feedback with a proper error message.

Why encapsulation is important

There are tons of resources out there that can help you learn encapsulation in more depth,

But, why is this so important?

The encapsulation principle is very powerful and has a couple of benefits, let’s talk about the most important ones:

Conclusion

To wrap up, encapsulation is one of the fundamental concepts on OOP, and in programming in general, it is very important because it helps us write readable code and maintainable systems.

One more important thing I want to point out, that even if you are not using OOP this doesn’t mean you don’t want to apply encapsulation in one way or another, because you will still need to write reusable components, and you will usually write features on top of these reusable components, and even if these components are not classes with a “hidden” state, it is still important to write your code in such a way that you encapsulate related pieces of code into one place and write it in a way that you spare other developers from digging into all the details of your code in order to be able to use it, and also prevent misuse as much as you can.

And more importantly, write a code that even if it is used the wrong way, it gives its user proper feedback about the error and how to avoid it.

So what do you think? Do you also think encapsulation is very important?

The Startup

Get smarter at building your thing. Join The Startup’s +788K followers.

Sign up for Top 10 Stories

By The Startup

Get smarter at building your thing. Subscribe to receive The Startup's top 10 most read stories — delivered straight into your inbox, once a week. Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store