The WHAT – What’s with the Encapsulation Thing
So, in a previous article I talked about Abstraction and how it simplifies a specific concept. But how exactly does that actually happen? This is where Encapsulation kicks in. Abstraction and Encapsulation are complementary principles. While abstraction simplifies a concept, encapsulation is the way this simplification happens: from a concept to something more concrete/tangible.
Encapsulation composed of two main concepts:
grouping related ideas in a single concept (drawing boundary on something)
information hiding.
In my very own, personal opinion, the grouping related ideas in a single concept has its origins in the abstraction part and is finalized through encapsulation. You need to hide information (by encapsulation) to make the object simple to work with (by abstraction).
The HOW – Applying it in the Simplest Way Possible
This information hiding may sound complex (maybe you think about it in a form of encryption or steganography) but actually it’s dumb simple: you just literally hide the information (as in limit the access) from other objects. That’s it.
Access modifiers is the fancy word used to describe how you control the information from an object to another (as in what do you want to share or hide with other objects). These access modifiers are just some reserved keywords in a specific programming language which do exactly that: limit access to specific parts of your code from other objects.
In C# for example we have the following access modifiers:
private – not shared with any class (most restrictive)
protected – shared only with derived classes (through inheritance). To make it painfully simple: if I have a class (let’s say A) and I mark a method as protected, this method will only be visible by classes which derive from class A. So if I have a class B which inherits class A, my protected method will be visible from class B
internal – shared by all classes in a specific assembly (dll). An assembly is a group of classes in a project whose functionality is merged in a single binary output file => a dll file. Classes which are outside this assembly will not be able to use a method marked as internal. In other programming languages an assembly is the equivalent to packages or libraries
public – shared with all classes (least restrictive)
These access modifiers can be applied to: classes, properties, members, methods. This way you have total control over what functionality is available from where. Please note that the access modifiers might be slightly different depending on the programming languages used but they have the same purpose.
The WHY – What’s the Point and Why Should I Care?
Ok, so why do this? Why shouldn’t you use the public modifier everywhere? Well you could, but it would make your life harder, a lot. The thing is that if you make all you methods public, your class will most likely have multiple methods available to someone who wants to use it. If that someone does not know exactly what each method does, it will most likely misuse it.
Remember the car example from abstraction? You need fuel to start the engine, you need various mechanisms to transfer the energy from the engine to the wheels, etc. It’s something mandatory for a car, yet the driver (user) does not need to know them in order to drive it. So, in order to simplify this concept, what do you do?
You hide the details (marking them as private) which are mandatory for you as an object, but the user does not need to know them: GetPowerFromBattery(), IgniteFuel(), GetOilFromTank(), LubricateEngine(), TransferEnergyToFrontWheels() and allow the essential ones to the user (marking them as public): StartEngine(), Accelerate(), Break(), TurnLeft(), TurnRight().
Of course, in different contexts you might want to go with protected and internal as well.
The main idea is to adopt a “don’t tell me how you do it, just do it” mindset.
Another example: I tell you to walk from point A to B. Assuming you agree, you just do it. You don’t think about how your brain got the trigger, how it sends the commands to the locomotor system (in this very specific order):
to lift left leg about 10 cm from the ground
lean forward while keeping balance
move it 40 cm forward
put left leg down on the ground
lift right leg about 10 cm from the ground
…so on and so forth
repeat until you arrive at point B
If I were to model this behaviour in OOP, I could have made all these methods public, but then I would have added complexity to my object and it wouldn’t be as easy to use. If the user called the method to move the foot before lifting it, most likely the object would “fall” due to losing balance.
Instead, I can keep all these methods private and make a public one named Walk(from, to). Then, I can call all the private ones above in the order which makes sense for me as an object. These methods are irrelevant for the user/caller/other object and it does not need to know them and also shouldn’t care.
Another aspect you should think about is: security. You might want to hide certain information from other objects for security reasons.
Imagine going shopping to the mall having your credit card information at sight for everyone to use with your pin attached (e.g. printed on your t-shirt with big fonts). It is useful for you because it’s “handy” and you won’t forget your PIN. But this is personal information, which should be contained, otherwise other people will also use it and you won’t be happy about it.
Conclusion
Encapsulation is complementary with Abstraction. You can’t have one without the other in the OOP world. Keep it simple by adopting “the don’t tell me how you do it, just do it“, you’ll thank yourself later.
Still having questions? Contact me via Facebook or drop me a line, I’ll follow up on it, I promise.
Comments