In software development there are two similar concepts - encapsulation and information hiding. Someone thinks that these are synonyms, someone does not, but it is not so important.
A bit of history: David Parnas in the 70th year in the article “On the Criteria for Modules” first introduced the concept of information hiding as a key design tool. This principle sounded like this: decomposition of a system into modules should not be based on the analysis of a block of circuits or execution threads. Instead, each module must hide inside some solution (design decision), providing the minimum amount of information about it to its customers.
Here is a small example.
Let's say you are developing an application that does something important. Any normal application usually requires some configuration: well, connection parameters to the database or server, and other valuable information. And so, the experienced articulator (*) along with an equally experienced client are asked to read the configuration from the configuration file.
(*) this is not a typo, please do not edit it!
During the conversation with them, you understand that no one really knows why you need to read the configuration from the file, what its format should be and what exactly should be stored there.
Now you are faced with a choice: you can “spread” configuration information in an even layer throughout the application. Each component that needs some parameters will get into the app config itself, pull out the necessary data from there, parse xml or json and be ready to serve. On the other hand, it is obvious that the decision on where the configuration is stored and in what format may change in the future. Therefore, a more sane decision would be to hide the location and configuration format information in a single module, for example, using the Configuration
and ConfigurationProvider
classes. In this case, when (yes, precisely “when” rather than “if”) the requirements change, then only the implementation of the ConfigurationProvider
class will change, and all other users of this class or configuration will remain unchanged. Similarly, when the format is changed, only the process of parsing changes, not the configuration consumers.
This example seems contrived, but it is not! We quite often encounter the variability of requirements, but, unfortunately, we use one of two approaches:
• Completely ignore the possibility of changing requirements and do everything head-on or
• We create a super complex solution with a dozen levels of indirection that must withstand changing requirements in any direction without changing the code at all.
More sensible approach is somewhere in the middle. Every time I start developing a feature, I think how many pieces in the code will have to be changed if the requirements or implementation details change significantly. However, I do not try to reduce the number of changes to 1 (well, like, if we follow the SRP, then there should be only one place, in case of a change in the requirements). I try to make these places a little, and the changes were simple.
Actually, this is the essence of information hiding and his younger sister - encapsulation.