Java Reference
In-Depth Information
If we reflect on these different approaches, it's pretty clear that we've diverged quite a bit
from the traditional open/closed principle. In fact, when Bertrand Meyer first introduced the
principle, he defined it so that the class itself couldn't ever be altered after being completed.
Within a modern Agile developer environment it's pretty clear that the idea of a class being
complete is fairly outmoded. Business requirements and usage of the application may dictate
that a class be used for something that it wasn't intended to be used for. That's not a reason
to ignore the open/closed principle though, just a good example of how these principles
should be taken as guidelines and heuristics rather than followed religiously or to the ex-
treme.
A final point that I think is worth reflecting on is that in the context of Java 8, interpreting
the open/closed principle as advocating an abstraction that we can plug multiple classes into
or advocating higher-order functions amounts to the same thing. Because our abstraction
needs to be represented by either an interface or an abstract class upon which methods are
called, this approach to the open/closed principle is really just a usage of polymorphism.
In Java 8, any lambda expression that gets passed into a higher-order function is represented
by a functional interface. The higher-order function calls its single method, which leads to
different behavior depending upon which lambda expression gets passed in. Again, under the
hood we're using polymorphism in order to implement the open/closed principle.
The Dependency Inversion Principle
Abstractions should not depend on details; details should depend on abstractions.
One of the ways in which we can make rigid and fragile programs that are resistant to change
is by coupling high-level business logic and low-level code that is designed to glue modules
together. This is because these are two different concerns that may change over time.
The goal of the dependency inversion principle is to allow programmers to write high-level
business logic that is independent of low-level glue code. This allows us to reuse the high-
level code in a way that is abstract of the details upon which it depends. This modularity and
reuse goes both ways: we can substitute in different details in order to reuse the high-level
code, and we can reuse the implementation details by layering alternative business logic on
top.
Let's look at a concrete example of how the dependency inversion principle is traditionally
used by thinking through the high-level decomposition involved in implementing an applica-
tion that builds up an address book automatically. Our application takes in a sequence of
Search WWH ::




Custom Search