Skip to content

Commit 95cfd28

Browse files
author
ccarella
committed
added lsp, isp and dip
1 parent cb172e7 commit 95cfd28

16 files changed

+194
-1
lines changed

README.md

+50-1
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,53 @@ It might be tempting to just open up the `Guitar` class and add a flame pattern
2424
throw up in our application.
2525

2626
Following OCP we create `SuperCoolGuitarWithFlames` by extending the Guitar class we can be sure that our existing
27-
application won't be affected.
27+
application won't be affected.
28+
29+
### Liskov Substitution
30+
31+
**If class A is a subtype of class B, then we should be able to replace B with A without disrupting the behavior
32+
of our program.**
33+
34+
Defined a `Car` interface, we have implemented a `MotorCar`. We want to introduce electric cars which by definition
35+
is a car without the engine. `ElectricCar` is the implementation. This a violation of Liskov substitution principle.
36+
37+
One possible solution would be to rework our model into interfaces that take into account the engine-less state of
38+
our `Car`
39+
40+
### Interface Segregation Principle
41+
42+
**Larger interfaces should be split into smaller ones. By doing so, we can ensure that implementing classes only need
43+
to be concerned about the methods that are of interest to them**
44+
45+
We define a `BearKeeper` class. As avid zookeepers, we're more than happy to wash and feed our beloved bears.
46+
However, we're all too aware of the dangers of petting them.
47+
48+
Only the crazy zookeepers can do that. But with this implementation we force every zookeepers to pet bears.
49+
50+
We create 3 new interfaces `BearCleaner`, `BearFeeder` and `BearPetter`.
51+
52+
Now, thanks to interface segregation we can implement `BearCarer` and `CrazyPerson`.
53+
54+
### Dependency Inversion Principle
55+
56+
**The principle of Dependency Inversion refers to the decoupling of software modules. This way, instead of high-level
57+
modules depending on low-level modules, both will depend on abstractions.**
58+
59+
In `Windows98Machine` class by declaring the `StandardKeyboard` and `Monitor` with the new keyword, we've tightly
60+
coupled these 3 classes together
61+
62+
Not only does this make our Windows98Computer hard to test, but we've also lost the ability to switch
63+
out our StandardKeyboard class with a different one should the need arise. And we're stuck with
64+
our Monitor class, too.
65+
66+
To implement DI we:
67+
68+
- adding a more general Keyboard interface
69+
- rewrite it to `Windows98MachineDI`
70+
71+
Now our classes are decoupled and communicate through the Keyboard abstraction. If we want, we can easily switch out
72+
the type of keyboard in our machine with a different implementation of the interface.
73+
We can follow the same principle for the Monitor class.
74+
75+
We've decoupled the dependencies and are free to test our Windows98Machine
76+
with whichever testing framework we choose.

src/main/java/dip/Keyboard.java

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package dip;
2+
3+
public interface Keyboard {
4+
}

src/main/java/dip/Monitor.java

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package dip;
2+
3+
public class Monitor {
4+
}
+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package dip;
2+
3+
public class StandardKeyboard implements Keyboard {
4+
}
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package dip;
2+
3+
public class Windows98Machine {
4+
5+
private final StandardKeyboard keyboard;
6+
private final Monitor monitor;
7+
8+
public Windows98Machine() {
9+
monitor = new Monitor();
10+
keyboard = new StandardKeyboard();
11+
}
12+
13+
}
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package dip;
2+
3+
public class Windows98MachineDI {
4+
5+
private final Keyboard keyboard;
6+
private final Monitor monitor;
7+
8+
public Windows98MachineDI(Keyboard keyboard, Monitor monitor) {
9+
this.keyboard = keyboard;
10+
this.monitor = monitor;
11+
}
12+
13+
}

src/main/java/isp/BearCarer.java

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package isp;
2+
3+
public class BearCarer implements BearCleaner, BearFeeder {
4+
5+
@Override
6+
public void washTheBear() {
7+
// I think we missed a spot
8+
}
9+
10+
@Override
11+
public void feedTheBear() {
12+
//Tuna Tuesday
13+
}
14+
15+
}

src/main/java/isp/BearCleaner.java

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package isp;
2+
3+
public interface BearCleaner {
4+
5+
void washTheBear();
6+
7+
}

src/main/java/isp/BearFeeder.java

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package isp;
2+
3+
public interface BearFeeder {
4+
5+
void feedTheBear();
6+
7+
}

src/main/java/isp/BearKeeper.java

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package isp;
2+
3+
public interface BearKeeper {
4+
5+
void washTheBear();
6+
void feedTheBear();
7+
void petTheBear();
8+
9+
}

src/main/java/isp/BearPetter.java

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package isp;
2+
3+
public interface BearPetter {
4+
5+
void petTheBear();
6+
7+
}

src/main/java/isp/CrazyPerson.java

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package isp;
2+
3+
public class CrazyPerson implements BearPetter {
4+
5+
@Override
6+
public void petTheBear() {
7+
//Good luck with that
8+
}
9+
10+
}

src/main/java/lsp/Car.java

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package lsp;
2+
3+
public interface Car {
4+
5+
void turnOnEngine();
6+
void accelerate();
7+
8+
}

src/main/java/lsp/ElectricCar.java

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package lsp;
2+
3+
public class ElectricCar implements Car {
4+
5+
@Override
6+
public void turnOnEngine() {
7+
throw new AssertionError("I don't have an engine!");
8+
}
9+
10+
@Override
11+
public void accelerate() {
12+
//this acceleration is crazy
13+
}
14+
}

src/main/java/lsp/Engine.java

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package lsp;
2+
3+
public class Engine {
4+
5+
public void on() {
6+
//vroom
7+
}
8+
9+
public void powerOn(int amount) {
10+
//do something
11+
}
12+
13+
}

src/main/java/lsp/MotorCar.java

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package lsp;
2+
3+
public class MotorCar implements Car {
4+
5+
private Engine engine;
6+
7+
@Override
8+
public void turnOnEngine() {
9+
engine.on();
10+
}
11+
12+
@Override
13+
public void accelerate() {
14+
engine.powerOn(1000);
15+
}
16+
}

0 commit comments

Comments
 (0)