solid oo & clean coding is essential to successful agile development
TRANSCRIPT
Simon Says
“SOLID OO Design
and Clean Coding
is essential for
successful Agile
development”
Introduction
Characterisics of
a Good Agile
Codebase
Or what we need to
develop to meet the
needs of an Agile
environment.
SOLID OO Design
Principles
What they are and
how a Clean Coder
can use them to
develop robust
maintainable
software.
Summary
Some guidelines
for the Clean Coder
to live by.
1. Characteristics of
a Good Agile
Codebase
Or what we need to develop to
meet the needs of an Agile
environment.
“
No plan survives contact with the enemy
- Field Marshall Helmuth Karl Bernhard
Graf von Moltke
Change is the only constant in life.
― Heraclitus
Agile development requires:
◎The speedy delivery of working code.
◎The management of technical debt.
◎The ability to incorporate new features
and changes to existing features quickly
This requires us to be disciplined in our
development of software, ensuring that it
has the required characteristics. Beyond
it simply “working”.
Agile software should be:
◎ Loosely coupled.
◎ Cohesive.
◎ Appropriately encapsulated.
◎ Robust
◎ Easily maintained
◎ Easy to change.
This list are not exhustive, but I believe these are the
most important structural characteristics and
qualities that our software should have.
2. SOLID OO Design
Principles
What they are and how a Clean
Coder can use them to develop
robust maintainable software.
SOLID OO design principles:
◎Single Responsibility Principle.
◎Open Closed Principle.
◎Liskov Substitution Principle
◎ Interface Segregation Principle
◎Dependency Inversion Principle
Originally compiled by “Uncle Bob” martin in the 90s.
Applying these principles to our software development
“bakes in” the characteristics we require for agile
development.
Single Responsibility Principle– Do Just One Thing Well
Definition
◎ Modules should only exist
to serve one responsibility and
may only change if that
responsibility is modified
◎ A responsibility is a reason
to change, and therefore a
class or module should have
one, and only one, reason to
change.
◎A single responsibility is
dependant on the level of
abstraction at which the
software module exists.
Single Responsibility Principle– Do Just One Thing Well
Advantages
◎ Improves cohesion of
the software modules.
◎Improve maintainability
and individual modules are
simplified and so easier to
change and extend.
◎Reduces risk of making
changes, due to removing
GOD objects.
Perils
◎You mix your levels of
abstraction, leading to
confusing code that
performs high level and low
level operations. It may still
have one responsibility but
it hasn’t delegated this
appropriately to sub
modules and components.
Single Responsibility Principle– Do Just One Thing Well
◎ Provides tests to ensure
that responsibilities of the
software module are met.
The Clean Coder
◎Focuses software modules
on a simple cohesive
responsibility.
◎Avoids mixing levels of
abstraction
Open Closed Principle – Allow for interchangable parts
Definition
◎ Software entities (classes,
modules, functions, etc.) should
be open for extension, but
closed for modification
◎ Tends to refer to the use
of abstracted interfaces, where
the implementations can be
changed and multiple
implementations could be
created
and polymorphically substituted
for each other.
Open Closed Principle – Allow for interchangable parts
Advantages
◎ Functionality can be
added by creating a new
subclass, minimising the
impact on the existing
codebase and so
minimising risk.
Perils
◎You have to modify the
interface and therefore the
client code and ALL the
implementations.
Open Closed Principle – Allow for interchangable parts
◎Uses the Interface
Segregation Principle to
extend or add abstractions
rather than changing existing
ones.
◎Provides tests for each
implementation and extension.
The Clean Coder
◎Creates abstractions to hide
what varies between
implementations from the
client code. Pushing
complexity down to the lower
levels of abstraction.
◎Spends time simplifying
their abstractions, because
once they become ubiquitous,
they become difficult to
change.
Liskov Substitution Principle - Be What They Expect You to Be
Definition
◎ An object of type T (an
abstraction) may substitute objects
derived from T without altering any
of the properties of that program.
◎ Sub types must: ○Maintain the Semantic correctness of
the abstraction.
○Maintain Contravariance of
arguments in the subtype (only be
made more abstract)
○Maintain Covariance of return types
in the subtype (only be made less
abstract)
○Not throw new types of exception
unless these are derived from the
exceptions thrown in T
Liskov Substitution Principle - Be What They Expect You to Be
Advantages
◎ Client code can work
with new implementations
that adhere to the Liskov
substitution Principle
Without needing to
change. Making it much
easier to extend.
◎Once again leading to
loosely coupled code.
Perils
◎Violations of Semantic
correctness are not always
obvious.
◎ The client code needs to
change because your
abstraction leaks
implementation details (a
LSP violation).
Liskov Substitution Principle - Be What They Expect You to Be
◎When in doubt, makes their
interfaces more abstract and
simple, reducing the likelihood
of a Liskov Substitution
violation in the client code.
The Clean Coder
◎Implements abstractions so
that the implementation
conforms with the semantics
(meaning )of the interface.
◎Implementations of the
interfaces should conform to
the Open Closed Principle
◎Provides common tests that
confirm substitutability of sub
classes and semantic
conformance to the interface.
Interface Segregation Principle - Don't Make Me Specify Things I
Don't Care About
Definition
◎ No client should be
forced to depend on
methods it does not use
◎Many small interfaces is
preferred to One all
encompassing one.
◎Keep interfaces Small
and Cohesive
Interface Segregation Principle - Don't Make Me Specify Things I
Don't Care About
Advantages
◎ Promotes loose coupling
as client code only
depends on the
abstractions that they use.
◎Makes the code easier to
refactor and extend as
each interface should be
minimal but complete.
Perils
◎The law of Leaky
Abstractions – “All non
trivial abstractions, to some
degree, are leaky”
Interface Segregation Principle - Don't Make Me Specify Things I
Don't Care About
◎Keeps interfaces separate
and cohesive. Don’t repeat
Yourself
The Clean Coder
◎Uses the Liskov
Substitution Principle to
define semantically consistent
abstractions, minimising the
law of leaky abstractions.
◎Uses the Single
Responsibility Principle to
determine the scope of
Abstractions
Dependancy Inversion Principle - I Don't Care How, Just Give Me
What I Want
Definition
◎ 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.
Dependancy Inversion Principle - I Don't Care How, Just Give Me
What I Want
Advantages
◎ Promotes loose coupling
as all interactions are
through defined interfaces
or “contracts”.
◎Allows top down Test
Driven Design, where
abstractions are defined by
client need and mocked for
testing in isolation.
◎Maximises the amount of
work not done – “Your not
going to need it”
Perils
◎ One interface to rule
them all… the “GOD”
interface.
Dependancy Inversion Principle - I Don't Care How, Just Give Me
What I Want
◎Gives Meaningful Names
to abstractions and the
methods that define the
“contract” of the abstraction.
The Clean Coder
◎ Uses the Interface
Segregation Principle and
the Single Responsibility
Principle to define the
Abstractions the Client code
requires.
◎Writes tests first, defining
and mocking abstractions as
the Need is identified. Making
appropriate use of Design
Patterns and maximising the
amount of work Not done.
3. Summary
Some guidelines for the Clean
Coder to live by.
The Clean Coder
Is mindful of the
SOLID OO Design
Principles.
There is no good
reason not to apply
these to your day to
day work. Look them
up, practice them,
learn.
Writes tests first
as part of your
design process.
Start with the test at
the highest level of
abstraction. Identify
the client code needs
and behaviour.
Create tests for these
and create interfaces
that meet the client
codes needs. Then
move to the lower
level abstractions and
repeat. Practice,
practice, practice.
Manages
Technical Debt
with refactoring.
Unit testing MUST be
in place to reduce risk
and is the corner
stone of refactoring.
Technical debt
always exists, if it is
isolated and
managed
appropriately it wont
kill your code base.
The Clean Coder
Doesn’t repeat
themself
Minimises knowledge
duplication in the
code
Keeps things
simple
Remember Simple is
NOT the same as
quick and easy (dirty).
Simplify interatively.
Something is simple if
the dependencies are
minimised (loose
coupling),
abstractions are not
mixed and it has a
clear purpose
(Cohesive)
Uses Meanigful
names
Code is intended to
convey meaning to
the programmer and
their team. This is
why we don’t look at
zeros and ones
anymore. If the
naming is meaningful
and the methods
simple and small
there is no need to
explain it with
comments.
The Clean Coder
Minimises Scope
of Methods and
Variables
Helps reduce
complexity and the
risk of side effects /
action at a distance.
Works as part of a
team
Help your collegues
to deliver the most
important features.
You succeed and fail
as a group.
Uses the right
tools for the Job
Appropriate IDEs with
refactoring
capabilities (allows
you to work faster
and cleaner).
Technologies and
frameworks that
provide functionality
required.
The Clean Coder
Practice
Practice
Practice
You have to be doing
these things regularly
and refresh them
regularly. Never stop
learning and
improving.
Its no good knowing
what to do if you don’t
do it.