Abstraction is one of the so called four pillars of object-oriented programming, at its heart its about hiding the details of implementation and concentrating on the functionality offered to the user.
"Abstractions should NOT depend on details. Details should depend on abstractions."
As someone creating an abstraction I should construct it to present the functionality in the most convenient and logical way from the point of view of the user, then figure out the details of how I achieve that interface.
As the user of the abstraction I don't want to be exposed to the detail of the implementation because it was easier for you to code that way.
So if thats how we approach abstractions, why should we want to use them?
Sorry, I've Had To Make A Change
Fundamentally good software design is about dealing with change. Change is a fact of life for a variety of different reasons, software that can't adapt will become fragile and untrustworthy.
One of the things most likely to change are details,You want to change the details of a server API? You want to change the schema of a database? You want to use a different 3rd party library to handle analytics?
This is where abstractions will save the day. By depending on an abstraction only concerned with functionality you are completely isolated from changes in the details of implementation, and at some point these detail will change.
Let Me Worry About That
Good use of abstraction will help bring encapsulation, if I don't know the details of an implementation I can't interfere with them.
By not exposing details you gain protection from someone relying on something you didn't intend them to use, from misunderstanding the purpose or consequences of a method or by just generally not understanding your thinking.
Abstractions allow details to be your domain, you handle that and I'll use the functionality.
Test The Code, Not Your Patience
By not having any dependency on detail it becomes trivial to provide mock implementations when testing your code.
Many people reading this may be saying "Ah well my testing framework can handle this even when I use concrete classes".
My answer would be I'm sure it can, I'm also sure that your tests take longer to write, are more fragile, and that eventually you'll hit something you can't test.
Higher Level Thinking
When we put the effort in to define what abstractions our system is going to need we are forced to think about the bigger picture of what it is we are trying to build and how we want it to be used.
All implementation is detail, its only importance should be that it works and is well engineered. Getting bogged down in the details and only thinking at a low level, especially when first designing the system, will ultimately lead to a system without a clear vision or goal.
In my view there are very few reasons to not put all functionality behind abstractions.
- Its very difficult to predict change, why would you not want to be protected against it?
- Why would you not want your code to be testable?
- Why would you not want to protect a class from outside interference?
- Why would you not want to think about the big picture?
When designing good software abstract thinking isn't weird it should be the norm.
No comments:
Post a Comment