3. SOLID - describes five design principles
Michael Feathers and Bob Martin were heavily
involved in formulating these principles
They help us to write testable code
by using good design principles
I'll present these as SDOLI though...
4. Most importantly
Read up on the principles afterwards and
investigate for yourselves.
Try some of them out
7. Evaluating the design
Pros
●Easy to write (very imperative, like a recipe)
Cons
●Hard to test
●Hard to read
●Not reusable
Let's separate the responsibilities using:
Extract Method
8.
9. Evaluating the design
We have methods with one responsibility now.
But the class still does several things
Makes it harder to test
Separate the responsibilities using
Extract Class
10. This wraps up our database interaction
This wraps up our email server interaction
11. Evaluating the design
We have separate classes with responsibilities
Much simpler
It does require us to navigate in our IDE to see
what MailSenderImpl and OrderDAOImpl do
though
Is it easier to test?
14. Evaluation of our class
Our class is bound to specific implementations:
MailSenderImpl - what if I want to send via
SMS instead of mail?
Generalise the class by refactoring with
Extract Interface
15. Can inject implementations of these interfaces
Programmatically as well as with Spring!
Evaluation of our class
18. ● Should be able to change the external
dependencies of the class
● Without change the class internals
● Well we can do this already!
● We used an Interface and injected our
dependencies into the class
Evaluation of our class
19. There are other ways to make the class
extensible:
● Dependency Injection - Inject when container starts
● Decorator and composition - Bound at compile time.
Wrap a class providing before method & after method.
● Dynamic language extensibility - Bound at runtime.
One way is to use a dynamic language or bean to
provide functionality.
Other extensibility mechanisms
20. This one is short because we've already done
the refactoring previously...
In conclusion
23. We write a Duck interface which defines a
method called swim:
public interface Duck {
void swim();
}
We're envisioning all kinds of different
implementations of this.
Consider the following...
24. StandardDuck
We create a class that implements this:
public class StandardDuck implements Duck {
public void swim() {
System.out.println("Off we go...");
}
}
25. ElectricDuck
Soon we need to provide a
new type of duck.
public class ElectricDuck implements Duck {
public void swim() {
if ( isTurnedOn() ) {
System.out.println("Off we go...");
}
}
}
This breaks our principle because of the state.
26. ExceptoDuck
This is also bad...
public class ExceptoDuck implements Duck {
public void swim() {
throw new IllegalStateException("No way");
}
}
This also breaks our principle.
27. From the pond...
Think of this from a client perspective.
If you have a getDuck() method and you call
swim() on that then you should expect it to just
work
This goes in hand with the:
Principle of Least Astonishment
28. ● An object should be substitutable by it's:
oInterface
oBase Class
● This means that if you create a new class
and implement an interface it shouldn't do
anything surprising
● No side effects - throwing exceptions or
doing things contrary to the interface
Liskov Substitution Principle
31. ●Let's add another method to our Duck
interface because we want our duck to swim
and speak:
public interface Duck {
void swim();
void speak();
}
Interfaces...
32. Enter RoboDuck
public class RoboDuck implements Duck {
public void swim() {
System.out.println("Let's move creep");
}
public void speak() {
// I really really don't want to be forced
// to speak...
}
}
33. ●We shouldn't force people to implement
things they don't want to
●We should create a separate interface called
Speakable or something...
●In short Interfaces should also have single
responsibilities as well as classes and
methods
Bringing Back SRP
35. ●YAGNI - You Ain't Gonna Need It. Don't
build what you don't need today !
●Don't over-engineer abstractions, hierarchies
or genericise where you don't need to
●It's called Speculative Generality
●And it's way worse than any of the above
because it makes work harder for us
One other principle - YAGNI
36. ●If you have abstract classes that don't do
anything - Collapse Hierarchy
●Don't delegate when you don't need to - fold
the class back in - Inline the Class
●Above all...
If someone proposes a complex design to a
problem then question it until you understand
Some refactoring advice
37. ●Further reading on this...
●One of the single best articles out there on
bad code or code smells
http://www.codinghorror.com/blog/2006/05/code-smells.html
Coding Horror - Code Smells
38. ●Found out about this last night...
http://sourcemaking.com/
SourceMaking.com
39. ●Refactoring
oHow many do you know?
oHow many people use Eclipse for this?
●Test Driven Development
oDoes it help us here with the principles?
oDo people write their tests first?
oDo people use it when fixing bugs?
Discussion