SOLID Principles of Object Oriented Design
D
What will we cover
- Who the hell is this guy
- A quick introduction
- Summary of SOLID
- with a bit of history
- A close look at Dependency Inversion
- An overview of OOP
- A contrived example
- Some Pros and Cons
- Related concepts
SHAMELESS plug
Hello, we’re Deloitte Digital.
Here’s a little bit about us.
We bring global perspectives.
Melbourne Technology team breakdown.
Around half of our national technology team of over 120 are based in Melbourne
Aaron
Gravypower
- https://blog.gravypower.net
- @gravypower
- https://github.com/gravypower
UNCLE BOB
High-level policy should not depend on low-level detail, low-level detail should depend on high-level policy
SOLID principles
- Single Responsibility
- Open Closed
- Liskov Substitution
- Interface Segregation
- Dependency Inversion
DEPENDENCY INVERSION
Depend upon abstractions, not concretions.
- 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.
DEPENDENCY INVERSION
object orientation
Class
Interface
polymorphism
dependencies
Compile-time dependencies
Class B
+ f()
Class A
Compiling Code
x : int
Run-time dependencies
Class B
+ f()
Class A
Running Code
x : int
turtles all the way down
Compiler
https://xkcd.com/303/
COMPILE-TIME => Run-time
Interface
+ f()
Class A
Class B
+ f()
Class B
+ f()
x : int
x : int
Your living room
Class B
+ f()
Class A
x : int
"Abstractions should not depend on details. Details should depend on abstractions"
Painting
+ show()
LivingRoom
Your living room
YOUR LIVING ROOM
public class LivingRoom
{
public LivingRoom()
{
}
public void EnterRoom()
{
//Painting is always there.
}
}
YOUR LIVING ROOM
public class LivingRoom
{
public LivingRoom()
{
}
public void EnterRoom()
{
//Video is always there.
}
}
YOUR LIVING ROOM
public class LivingRoom
{
public bool ShowVideo {get; set;}
public LivingRoom()
{
}
public void EnterRoom()
{
if(ShowVideo)
{
//Show Video.
}
{
//Show Painting.
}
}
}
public class LivingRoom
{
public bool ShowVideo {get; set;}
public bool ShowPoster {get; set;}
public bool ShowWeddingPicture {get; set;}
public LivingRoom()
{
}
public void EnterRoom()
{
if(ShowVideo)
{
//Show Video.
}
else if(ShowPoster)
{
//Show Poster
}
else if(ShowWeddingPicture)
{
//Show Wedding Picture
}
el
else
{
//Show Painting.
}
}
}
Your living room
YOUR LIVING ROOM
IScreen
+ show()
Living Room
YOUR LIVING ROOM
public class LivingRoom
{
private IScreen screen;
public LivingRoom(IScreen screen)
{
this.screen = screen;
}
public void EnterRoom()
{
this.screen.Show();
}
}
public class LivingRoom
{
private ILcd lcd;
public LivingRoom(ILcd lcd)
{
this.lcd = lcd;
}
public void EnterRoom()
{
lcd.Show();
}
}
dependency injection
Question:
Is Dependency Injection different to Dependency Inversion?
Answer:
Dependency Injection is used when applying the Dependency Inversion Principle.
ISCREEN
+ show()
LivingRoom
Painting
+ show()
the contract
the contract
public interface IScreen
{
void Show();
}
public class Painting : IScreen
{
public void Show()
{
//Display Painting
}
}
the contract
public interface IScreen
{
void Show();
}
public class Video : IScreen
{
public void Show()
{
//Display Video
}
}
The system
public class House
{
public LivingRoom livingRoom;
public void LivingRoom()
{
var video = new Video();
livingRoom = new LivingRoom(video);
livingRoom.EnterRoom();
}
}
public class House
{
public LivingRoom livingRoom;
public void LivingRoom()
{
var painting = new Painting();
livingRoom = new LivingRoom(painting);
livingRoom.EnterRoom();
}
}
Benefits
-
Loosely coupled code
-
Increased Testability
-
Independent Developability
-
Allows for Pluggable architecture
-
Independent Deployability
disadvantages
You may never see the benefits
Can Increase Complexity
Don't call us we'll call you
Inversion of Control
Composition Root
Mark Seemann
Where should we compose object graphs?
As close as possible to the application's entry point.
A Composition Root is a (preferably) unique location in an application where modules are composed together.
public class House
{
public LivingRoom livingRoom;
public void LivingRoom()
{
var painting = new Painting();
livingRoom = new LivingRoom(painting);
livingRoom.EnterRoom();
}
}
public interface IScreen
{
void Show();
}
public class Painting: IScreen
{
public void Show()
{
//Display Painting
}
}
Where in our example?
Where in our example?
public class Program
{
public static void Main(string[] args)
{
var painting = new Painting();
var livingRoom = new LivingRoom(painting);
var house = new House(livingRoom);
house.LivingRoom();
}
}
public class House
{
public LivingRoom livingRoom;
public House(LivingRoom livingRoom)
{
this.livingRoom = livingRoom;
}
public void LivingRoom()
{
livingRoom.EnterRoom();
}
}
dependency graph
Where in our example?
public class Program
{
public static void Main(string[] args)
{
var painting = new Painting();
var livingRoom = new LivingRoom(painting);
var house = new House(livingRoom);
house.LivingRoom();
}
}
public class House
{
public LivingRoom livingRoom;
public House(LivingRoom livingRoom)
{
this.livingRoom = livingRoom;
}
public void LivingRoom()
{
livingRoom.EnterRoom();
}
}
Ioc/DI CONTAINER
Where To From here?
Presentations on other four Principle
-
Come have a chat with me.
I love this shit.
-
Keybase
https://keybase.io/gravypower
-
Have a read of my blog.
https://blog.gravypower.net
Much ranting, you have been warned
The Clean Coder book
Link to my Blog
SOLID Principles of Object Oriented Design - D is for Dependency inversion
By Aaron Job
SOLID Principles of Object Oriented Design - D is for Dependency inversion
A summary of SOLID with a deep dive into Dependency Inversion
- 1,162