Encapsulation
Encapsulate - "To enclose or be enclosed in or as if in a capsule". [the free dictionary]
In software
Encapsulate - "To enclose or be enclosed in or as if in a capsule". [the free dictionary]
In software
Encapsulation is the practice of having classes/objects not
expose their data but expose methods to act upon the data. It also relates to
how we choose to put methods and data into classes (Putting data with the relevant methods that use it).
There are many ways we can choose to decompose systems into
objects but encapsulation is an effective way of making systems easier to
understand and maintain. By restricting access to data we can change the
internals of a class/module without requiring changes in the code that uses
that class/module.
Example
Example
I have a class “Person”
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Now take the following method:
public string FullName(Person person)
{
return person.FirstName + person.LastName;
}
If this method is not in the Person class the class must
expose the firstname and lastname data for this method to work. So any other piece
of code then has access to firstname and lastname and can use it. This means
that if at a later point you decide to store the person’s name as just a
fullname string you must change code that is outside of the person class. If this
method is part of the person class you only have to update the person class and
as long as its public interface is well designed and not affected by the change
you should not have to change any other classes.
Design
Design
By carefully thinking about how we compose our classes we
can hide the details (implementation) from the outside world, this can be a
massive advantage when maintaining large systems as we can completely rewrite
the internals of a class and have it not affect the rest of the system. When
classes are encapsulated well it can lead to a better conceptual model (set of
classes that represent the system), and often a better set of abstractions
making the system easier to code against.
How to achieve
You can use Getters and Setters to make it easier to encapsulate data, in .net an auto property can achieve this quickly. This will let you change the data later and still use the same property. Generally I would prefer using methods to act upon a class though.
Put methods in the same class as the data they are operating on, this should help achieve cohesion and make modification easier later.
Avoid
Classes exposing their data and their internal workings, this can even include the way you design your methods. Sometimes you can encapsulate how the object works by avoiding sharing of implementation details. For example return amount of fuel as a percentage left rather than gallons.
Having your method access and change data within another object (see if you can move the method to within the other object, where hopefully it will make more sense)
Put methods in the same class as the data they are operating on, this should help achieve cohesion and make modification easier later.
Avoid
Classes exposing their data and their internal workings, this can even include the way you design your methods. Sometimes you can encapsulate how the object works by avoiding sharing of implementation details. For example return amount of fuel as a percentage left rather than gallons.
Having your method access and change data within another object (see if you can move the method to within the other object, where hopefully it will make more sense)
Scope
Spend time thinking about anything that is not private, is there a way you could increase encapsulation by reducing the amount of data shared. Is your publicly accessible interface clean and free of clues as to how the object is implemented.
Also be wary of protected members, it can seem natural for inherited objects to have access to data but this can lead to problems refactoring later. Loose coupling between inheritance trees is hard to achieve but important to consider.
Also be wary of protected members, it can seem natural for inherited objects to have access to data but this can lead to problems refactoring later. Loose coupling between inheritance trees is hard to achieve but important to consider.
Benefits of
encapsulation
- Increase cohesion (Relation of data/methods within a class, high cohesion is good!)
- Decrease coupling (High coupling of classes can make them hard to reuse, replace and test)
- Better separation of concerns (when classes are highly cohesive a class is more likely to only focus upon itself)
- Easier to reuse (A loosely coupled class will be easier to reuse in other places)
- Easer to make changes (Only changes to the public interface require changes in other places)
- Reduces complexity (By only requiring you to think about one class at a time)
Disadvantages of
encapsulation
- Can require more code (Boiler plate, getters/setters etc.)
Inheritance and
encapsulation
Inheritance can be seen to be breaking encapsulation as you
are exposing the workings of the class to the class that is sub classing. Over
use of inheritance where it is not required will often lead to the breaking of
encapsulation. So we should favor composition (Containing another object) over
inheritance as a mechanism for code reuse.