SOLID principles:
Classes should be easy to extend and alter without changing their code.
Let's consider the calculator example once again:
class CalculatingMachine {
public static void add(int x, int y) {
System.out.println(x + y);
}
}
How do I change its behavior? What if want it to use something else but System.out
for printing? Looks like OCP is violated here, there's no explicit way I can do it. One of the possible solutions here is to make this class abstract
.
(not for production, illustrative purposes only)
abstract class AbstractCalculatingMachine {
public void add(int x, int y) {
getPrintStream().print(x + y);
}
protected abstract PrintStream getPrintStream();
}
class ConsoleCalculatingMachine extends AbstractCalculatingMachine {
@Override
protected PrintStream getPrintStream() {
return System.out;
}
}
I have all the calculator machine-specific behavior implemented in abstract
class AbstractCalculatingMachine
. I also have ConsoleCalculatingMachine
that uses System.out
for printing the results. As soon as I need a way to print results to file, I'll just subclass AbstractCalculatingMachine
once again and will return file-based PrintStream
in getPrintStream()
. This can be done without altering AbstractCalculatingMachine
class' code.