Professional Documents
Culture Documents
Design Principles
Arnon Rotem-Gal-Oz
Product Line Architect
Preface
Nothing really new here
Just a summary of other people’s work:
D.L. Parnas
M. Fowler
R.C. Martin, B. Meyer, B. Liskov
W.J. Brown, R.C. Malveau, H.W. McCormick,
T.J. Mowbray
GoF
N. Malik
A. Holub
And probably others I forgot
Agenda
7 Deadly Sins of Design
The Rules
Basic Stuff
Evil Stuff
More Stuff
7 Deadly Sins of Design
Rigidity – make it hard to change
Fragility – make it easy to break
Immobility – make it hard to reuse
Viscosity – make it hard to do the right
thing
Needless Complexity – over design
Needless Repetition – error prone
Also Known As
Protected Variation
What Parnas meant when he coined
“Information hiding”
Why OCP
If not followed a single change to a
program results in a cascade of changes
to dependent modules.
The program becomes fragile, rigid,
unpredictable and un-reusable.
OCP Example
Template
Method
OCP implications (examples)
Use private modifier for class members
Use abstractions
Extend by inheritance, delegation
DirectX
Dependency
Algorithm
DirectX
Dependency
Interface Segregation
Principle
Many client specific interfaces are
better than one general purpose
interface
IRectangle IRectangle
Area() Renderer
Draw()
Rectangle Client
Impl. Application
Algorithm
DirectX
Realization
Dependency
Liskov Substitution Principle
“What is wanted here is something like the
following substitution property: If for each
object o1 of type S there is an object o2 of
type T such that for all programs P
defined in terms of T, the behavior of P is
unchanged when o1 is substituted for o2
then S is a subtype of T.” (Barbara Liskov,
1988)
Or in English
Any subclass should always be usable
instead of its parent class.
cd Diagram Examples
Why is that an LSP violation?
Rectangle
+ SetHight() : void
+ SetWidth() : void
Square
+ SetHight() : void
+ SetWidth() : void
Real-Life Example
cd Diagram Examples
cd Diagram Examples
«interface»
IContributeObjectSink
MarshalByRefObject {abstract}
+ GetObjectSink (MarshalByRefObject, IMasshageSink ) : IMessageSink {abstract}
MarshalByRefObject
ServicedComponents
violates LSP:
ContextBoundObject
You cannot add your own sinks
(it only uses its own)
ServicedComponent
Dependency Inversion
Principle
Higher level modules should not
depend on lower level modules
Both should depend on abstractions
Interfaces or Abstract classes
Abstractions should not depend on
details
cd Diagram Examples
:Program
:Program
Separated Interface
put interface in separate package than
implementation
Dependency Injection
Old Way
public class MyApp
{
public MyApp()
{
authenticator = new Authenticator();
database = new Database();
logger = new Logger();
errorHandler = new ErrorHandler();
}
P S
authenticator = new IAuthenticator();
O
O
database = new IDatabase();
logger = new ILogger();
errorHandler = new IErrorHandler();
}
If (type())
Getters
Helper Classes
More Stuff
Package principles
Not the core of this presentation
Smells
Anti-Patterns
Package Principles
Reuse-Release Equivalency Principle
Common Closure Principle
Common Reuse Principle
Acyclic Dependencies Principle
Stable Dependencies Principle
Stable Abstractions Principle
CodeSmells
Something that's quick to spot
Indication for a possible problem
Not always the problem it self
May not be a problem at all