The goal of the SOLID design principles is to improve the Separation of Concerns, through weaker Coupling and stronger Cohesion. The main consequence should be software systems that are easier to maintain and to extend. However the definition of the SOLID principles is quite abstract, and some developers find it difficult to apply them in practice. In my talk I will show how well-known Design Patterns illustrate the application of the SOLID principles, and also show examples of how to follow these principles to Refactor and improve existing designs.
About the speaker:
Hayim Makabee was born in Rio de Janeiro. He immigrated to Israel in 1992 and completed his M.Sc. studies on Computer Sciences at the Technion. Since then he worked for several hi-tech companies, including also some start-ups. Currently he is a co-founder of the International Association of Software Architects (IASA) in Israel. Hayim is the author of a book about Object-Oriented Programming and has published papers in the fields of Software Engineering, Distributed Systems and Genetic Algorithms.
5. Single Responsibility Principle
Each class should have a single
responsibility. Only one potential
change in the system's specification
should affect the implementation of
the class.
6. Single Responsibility @
Strategy
The responsibility for
the implementation
of a concrete
strategy is decoupled
from the context that
uses this strategy.
7. Open/Closed Principle
“Software entities (classes, modules,
functions, etc.) should be open for
extension, but closed for modification.”
- Bertrand Meyer
8. Open/Closed @ Strategy
The context is open
for extensions and
closed for
modifications since it
does not need to be
changed to use new
types of strategies.
9. Liskov Substitution Principle
Objects in a program should be
replaceable with instances of their
subtypes without altering the
correctness of that program.
10. Liskov Substitution @
Strategy
All concrete
strategies implement
the same interface
and should be
substitutable without
affecting the
system’s
correctness.
11. Interface Segregation
Principle
No client should be forced to depend
on methods it does not use. Many
client-specific interfaces are better
than one general-purpose interface.
13. Dependency Inversion
Principle
High-level modules should not depend
on low-level modules. Both should
depend on abstractions.
Abstractions should not depend on
details. Details should depend on
abstractions.
17. Is Visitor SOLID?
Visitor violates the Single-
Responsibility principle. Consequence
= weak cohesion.
Visitor
V1 V2 V3
Element
E1 E2 E3
18. The Problem with Visitor
When a new Element is added, all
Visitors must be changed to add a
new method.
Visitor
V1 V2 V3
Element
E1 E2 E3 E4
19. Single Responsibility
Ideally: Dynamic binding by both type
of Visitor and Element (Double
Dispatch).
Visitor X
Element
E1 E2 E3
V1 m11(v,e) m12(v,e) m13(v,e)
V2 m21(v,e) m22(v,e) m23(v,e)
V3 m31(v,e) m32(v,e) m33(v,e)
20. Limitation of Single Dispatch
In practice: Dynamic binding only by
type of Visitor, the Element is not
polymorphic.
Visitor X
Element
E1 E2 E3
V1 v.m11(e1) v.m12(e2) v.m13(e3)
V2 v.m21(e1) v.m22(e2) v.m23(e3)
V3 v.m31(e1) v.m32(e2) v.m33(e3)
21. Singleton Design Pattern
public class Singleton {
private static final Singleton
INSTANCE = new Singleton();
private Singleton() {}
public static Singleton
getInstance() {
return INSTANCE;
}
}
22. The Problem with Singleton
Singleton causes strong coupling:
S
m1 m2 m3 m4
XS
XO
XL
XI
XD
23. Refactoring the Singleton – Step
1
Pass the Singleton object as a
parameter:
S
m1 m2 m3 m4
S S S
VS
XO
XL
XI
XD
24. Refactoring the Singleton – Step
2
Derive the Singleton from an Interface:
S
m1 m2 m3 m4
I I I
I VS
XO
XL
VI
VD
25. Refactoring the Singleton – Step
3
Several concrete Singleton classes:
S1
m1 m2 m3 m4
I I I
I
S2
VS
XO
VL
VI
VD
26. Refactoring the Singleton – Step
4
Parameter-based Singleton “selector”:
S1
m1 m2 m3 m4
I I I
I
S2
Selector VS
VO
VL
VI
VD
28. Pattern Metamorphosis
Through the application of the SOLID
principles, we moved from Singleton
to the Factory Design Pattern.
Singleton is actually a degenerate kind
of Factory that always returns the
same object of the same type…
The interface of the Factory
(getInstance) is mixed with the
interface of the object itself…
29. Conclusions
To understand how to apply the
SOLID principles in practice:
1. Choose a Design Pattern.
2. Analyze how this pattern makes use of
the SOLID principles to reduce coupling
and increase cohesion.
Be aware that some patterns may
violate some of the SOLID
principles.