SlideShare ist ein Scribd-Unternehmen logo
www.italiancpp.org
Going native with less
coupling
Dependency Injection in C++
Italian C++ Community
Style 1: [Fake] OO Design
i=2
CONTROLLER /
MANAGER
Dumb
object
Dumb
object
Dumb
object
Dumb
object
Dumb
object
Dumb
object
Dumb
object
Dumb
object
Italian C++ Community
Style 2: [True] OO design
i=3
Smart
Object
Smart
Object
Smart
Object
Smart
Object
Smart
Object
Smart
Object
Smart
Object
Smart
Object
Smart
Object
Smart
Object
Smart
Object
Smart
Object
Smart
Object
Smart
Object
Italian C++ Community
OO Architecture Benefits
i=4
Up Scalability (extension)
Down Scalability
(contraction)
Reusability
Safety (testability)
Italian C++ Community i=5
The Wiring
Issue
In a True Modular Architecture, wiring is critical
Italian C++ Community
The Wiring Issue
When you've got a Good Architecture, you deal with
requirements changes by adding/removing/substituting objects
So, we need a simple way to:
Change the type of the objects
Create new objects
Modify the wiring of the objects
i=6
Italian C++ Community i=7
Life without a
CONTROLLER
Example taken from:
Carlo Pescio's blog – March 2012
Italian C++ Community
First Design
i=8
MinePlant
SumpPump
+Drain()
PumpEngine
+On()
+Off()
DigitalOutput
+Write()
GasSensor
<<interface>>
+IsCritical()
GasAlarm
+Watch()
1..*
Alarm
+On()
+Off()
SafeEngine
Italian C++ Community
Requirements Change
i=9
MinePlant
SumpPump
+Drain()
PumpEngine
+On()
+Off()
DigitalOutput
+Write()
GasSensor
<<interface>>
+IsCritical()
GasAlarm
+Watch()
1..*
Alarm
+On()
+Off()
SafeEngine
Italian C++ Community
Extension
The design is robust: I only need to add a class
But…
Who creates SafeEngine instead of PumpEngine?
How does SafeEngine get the pointer to the
GasSensor (the same used by GasAlarm)?
i=10
Italian C++ Community
Solution #1: Local Creation
Each class creates its own
dependencies
i=11
Italian C++ Community i=12
MinePlant
SumpPump
+Drain()
PumpEngine
+On()
+Off()
DigitalOutput
+Write()
GasSensor
<<interface>>
+IsCritical()
GasAlarm
+Watch()
1..*
Alarm
+On()
+Off()
SafeEngine <<create>>
Italian C++ Community
Solution #1: Consequences
The SumpPump constructor creates a SafeEngine
instead of a PumpEngine.
… but SafeEngine needs a pointer to the GasSensor
instance already used by GasAlarm.
So, we must pass it as a parameter to SumpPump
constructor.
i=13
Italian C++ Community
Solution #1: Properties
If I need to change the concrete
type, I have to modify the client.
It's difficult to reuse the same client
class (even in the same application).
i=14
Italian C++ Community
Solution #1: Summary
SafeEngine class added
SumpPump constructor modified
MinePlant modified
i=15
Italian C++ Community
Solution #2: Factory
(not the GoF factory)
Create objects without exposing
the instantiation logic to the client
i=16
Italian C++ Community i=17
<<create>>
Italian C++ Community
Solution #2: Consequences
The SumpPump constructor takes a Factory as
parameter.
PumpEngineFactory instantiates a PumpEngine.
SafeEngineFactory instantiates a SafeEngine.
SafeEngine still needs a pointer to the GasSensor
instance already used by GasAlarm, so we must pass
it to the SafeEngineFactory constructor.
i=18
Italian C++ Community
Solution #2: Summary
SafeEngine class added
SafeEngineFactory added
MinePlant modified
i=19
Italian C++ Community
Solution #3: Service Locator
It’s a registry containing the
instances to use
i=20
Italian C++ Community
Solution #3: Service Locator
i=21
class ServiceLocator
{
public:
static ServiceLocator& Instance();
shared_ptr< PumpEngine > Engine();
void Engine( const shared_ptr< PumpEngine >& engine );
private:
...
};
Italian C++ Community
Solution #3: Service Locator
i=22
// MinePlant:
auto e =
make_shared< SafeEngine >( engineOutput, gasSensor );
ServiceLocator::Instance().Engine( e );
// SumpPump:
SumpPump::SumpPump() :
engine( ServiceLocator::Instance().Engine() )
{
}
Italian C++ Community
Solution #3: Properties
Clients aware of the locator
Dependencies not explicit / evident
Dependencies not checked by compiler
i=23
Italian C++ Community
Solution #3: Summary
SafeEngine class added
MinePlant modified
i=24
Italian C++ Community
Solution #4: Dependency Injection
Dependency Injection is when
you have something setting the
dependencies for you.
i=25
Italian C++ Community
Solution #4: Dependency Injection
Classes don't create their own dependencies
They're passed from outside
i=26
Italian C++ Community
Dependency Injection
i=27
auto gasSensor = ...
auto alarmOutput = make_shared<DigitalOutput>("/dev/ttyS0");
auto alarm = make_shared<Alarm>(alarmOutput);
auto gasAlarm = make_shared<GasAlarm>(gasSensor,alarm);
auto engineOutput = make_shared<DigitalOutput>("/dev/ttyS1");
auto engine = make_shared<PumpEngine>(engineOutput);
auto pump = make_shared<SumpPump>(engine);
Italian C++ Community
Dependency Injection
i=28
auto gasSensor = ...
auto alarmOutput = make_shared<DigitalOutput>("/dev/ttyS0");
auto alarm = make_shared<Alarm>(alarmOutput);
auto gasAlarm = make_shared<GasAlarm>(gasSensor,alarm);
auto engineOutput = make_shared<DigitalOutput>("/dev/ttyS1");
// auto engine = make_shared<PumpEngine>(engineOutput);
auto engine = make_shared<SafeEngine>(engineOutput,gasSensor);
auto pump = make_shared<SumpPump>(engine);
Italian C++ Community
Solution #4: Properties
Complete separation between:
application logic (classes)
wiring (main/builder)
i=29
Italian C++ Community
Solution #4: Summary
SafeEngine class added
MinePlant modified (one liner)
i=30
Italian C++ Community i=31
Can we do
BETTER
SafeEngine must be added anyway.
… can we remove the one liner in MinePlant?
?
Italian C++ Community i=32
Configuration
DrivenWIRING
moving creation and wiring outside the code,
in a configuration file
Italian C++ Community
Why?
To easily get extensibility/contraction
(without having to touch zillion files and
recompile everything)
i=33
Italian C++ Community
From Identifiers to Strings
Improving Previous Solution:
Objects creation from string
Objects identified by name
Objects connected by name
i=34
Italian C++ Community
Run-time Reflection Missing…
Create("Foo") vs new Foo
Enumerate the dependencies
“Inject” the right object address in a
class dependency
i=35
Italian C++ Community
Solution #5: Dependency Injection +
Dependency Injection is when you
have something setting the
dependencies for you.
…this something is usually a
framework.
i=36
Italian C++ Community
Existing libraries (C++)
i=37
QtIOCContainer
Sauce
DICPP
Hypodermic2
Pococapsule
Main issues:
Compile time injection only
Code generators needed
Italian C++ Community
Enter Wallaroo Library
i=38
wallaroo.googlecode.com
wallarooC++ Dependency Injection
Italian C++ Community
Creating objects
i=39
Catalog catalog;
...
catalog.Create("alarmOutput","DigitalOutput","/dev/ttyS0");
catalog.Create("alarm","Alarm");
catalog.Create("gasAlarm","GasAlarm");
catalog.Create("engineOutput","DigitalOutput","/dev/ttyS1");
catalog.Create("pump","SumpPump");
catalog.Create("engine","SafeEngine");
Italian C++ Community
Creating objects (from cfg)
i=40
<parts>
<part>
<name>pump</name>
<class>SumpPump</class>
</part>
<part>
<name>engine</name>
<class>SafeEngine</class>
</part>
</parts>
...
Catalog catalog;
XmlConfiguration
file("wiring.xml");
file.Fill( catalog );
...
Italian C++ Community
Object lookup by name
i=41
shared_ptr< SumpPump > pump = catalog[ "pump" ];
Italian C++ Community
Connect Things by name (DSL)
i=42
Catalog catalog;
// fill catalog
...
use(catalog["alarmOutput"]).as("out").of(catalog["alarm" ]);
use(catalog["safeEngine"]).as("engine").of(catalog["pump"]);
Italian C++ Community
Connect Things by name (DSL)
i=43
Catalog catalog;
// fill catalog
...
wallaroo_within( catalog )
{
use( "alarmOutput" ).as( "out" ).of( "alarm" );
use( "safeEngine" ).as( "engine" ).of( "pump" );
}
Italian C++ Community
Connect Things by name (from cfg)
i=44
<wiring>
<wire>
<source>alarm</source>
<dest>alarmOutput</dest>
<collaborator>out</collaborator>
</wire>
<wire>
<source>pump</source>
<dest>safeEngine</dest>
<collaborator>engine</collaborator>
</wire>
</wiring>
Catalog catalog;
...
XmlConfiguration
file( "wiring.xml" );
file.Fill( catalog );
catalog.CheckWiring();
...
Italian C++ Community
Class Declaration
i=45
#include "wallaroo/registered.h"
using namespace wallaroo;
class SumpPump : public Part
{
public:
SumpPump( int id );
private:
Collaborator< Engine > engine;
};
Italian C++ Community
Class Registration
i=46
WALLAROO_REGISTER( SumpPump, int )
SumpPump::SumpPump( int id ) :
engine( "engine", RegistrationToken() )
{
...
}
// other methods definition here
...
Italian C++ Community
Shared Libraries – AKA plugins (code)
i=47
Plugin::Load( "safeengine" + Plugin::Suffix() );
// Plugin::Suffix() expands to .dll or .so according
to the OS
Italian C++ Community
Shared Libraries – AKA plugins (cfg)
i=48
<plugins>
<shared>safeengine</shared>
</plugins>
Catalog catalog;
XmlConfiguration file( "wiring.xml" );
// load the shared libraries specified in the configuration file:
file.LoadPlugins();
file.Fill( catalog );
// throws a WiringError exception if any dependency is missing:
catalog.CheckWiring();
Italian C++ Community
Collections
i=49
class Car : public wallaroo::Part
{
...
private:
Collaborator< Engine > engine;
Collaborator< AirConditioning, optional > airConditioning;
Collaborator< Airbag, collection > airbags;
Collaborator< Speaker, collection, std::list > speakers;
Collaborator< Seat, bounded_collection< 2, 6 > > seats;
};
Italian C++ Community
Checks
i=50
if ( !catalog.IsWiringOk() )
{
// error handling
}
catalog.CheckWiring() // throws exception
Italian C++ Community
Initialization
i=51
class Part
{
...
public:
virtual void Init() {}
...
};
catalog.Init() // calls Part::Init for each part in catalog
Italian C++ Community
Wallaroo Internals
WALLAROO_REGISTER declares a static object.
Its constructor creates a factory and puts it in a table, with the class
name as key.
Catalog::Create uses the factory to put a new instance in the catalog.
wallaroo::Part has a table of <name, Collaborator>
i=52
Italian C++ Community
Wallaroo Internals
shared_ptr< Foo > foo = catalog[ “foo” ];
catalog[ “foo” ] returns a class that defines operator
shared_ptr< T >()
Collaborator uses weak_ptr for the dependency
Collaborator defines operator shared_ptr() and operator->()
i=53
Italian C++ Community
Wallaroo Internals
i=54
wallaroo_within( catalog )
{
use("alarmOutput").as("out").of("alarm");
use("safeEngine").as("engine").of("pump");
}
for ( Context c(catalog);c.FirstTime();c.Terminate() )
{
use("alarmOutput").as("out").of("alarm");
use("safeEngine").as("engine").of("pump");
}
Italian C++ Community
Wallaroo Strengths
Lightweight (header file only)
Portable
Type Safe
DSL syntax for object creation and wiring
Configuration driven wiring (xml and json)
Shared library support (plugin)
C++11/14 or boost interface
No code generators
i=55
Italian C++ Community
Design is a balance of forces
Intrusive VS Non Intrusive
Non Intrusive Solutions can manage existing classes but
require code generators for configuration driven wiring
i=56
Italian C++ Community
Design is a balance of forces
Configuration-driven wiring
VS static type checking
By moving the wiring in a configuration file, we give up the
static type checking.
But it’s ok, since you build your system at startup.
i=57
Italian C++ Community
Action Points
Real OOD (no controllers / managers)
Manual Dependency Injection
Wallaroo (configuration-driven wiring)
i=58
Italian C++ Community
References & Credits
Me: @DPallastrelli
Me: it.linkedin.com/in/pallad
Rate me: https://joind.in/12277
Wallaroo: wallaroo.googlecode.com
i=59
MinePlant example from Carlo Pescio's blog (http://www.carlopescio.com/2012/03/life-
without-controller-case-1.html)
Wiring Picture: By Gael Mace (Own work (Personal photograph))
[CC-BY-3.0 (http://creativecommons.org/licenses/by/3.0)], via Wikimedia Commons

Weitere ähnliche Inhalte

Was ist angesagt?

Bowling Game Kata in C# Adapted
Bowling Game Kata in C# AdaptedBowling Game Kata in C# Adapted
Bowling Game Kata in C# Adapted
Mike Clement
 

Was ist angesagt? (20)

Game Design Principle
Game Design PrincipleGame Design Principle
Game Design Principle
 
Intents in Android
Intents in AndroidIntents in Android
Intents in Android
 
Overview of React.JS - Internship Presentation - Week 5
Overview of React.JS - Internship Presentation - Week 5Overview of React.JS - Internship Presentation - Week 5
Overview of React.JS - Internship Presentation - Week 5
 
An Introduction to ReactJS
An Introduction to ReactJSAn Introduction to ReactJS
An Introduction to ReactJS
 
Advanced PHPUnit Testing
Advanced PHPUnit TestingAdvanced PHPUnit Testing
Advanced PHPUnit Testing
 
Java: Exception
Java: ExceptionJava: Exception
Java: Exception
 
CSS Grid Layout for Topconf, Linz
CSS Grid Layout for Topconf, LinzCSS Grid Layout for Topconf, Linz
CSS Grid Layout for Topconf, Linz
 
Bowling Game Kata in C# Adapted
Bowling Game Kata in C# AdaptedBowling Game Kata in C# Adapted
Bowling Game Kata in C# Adapted
 
React and redux
React and reduxReact and redux
React and redux
 
Important React Hooks
Important React HooksImportant React Hooks
Important React Hooks
 
Java awt
Java awtJava awt
Java awt
 
Basics of React Hooks.pptx.pdf
Basics of React Hooks.pptx.pdfBasics of React Hooks.pptx.pdf
Basics of React Hooks.pptx.pdf
 
Java basic
Java basicJava basic
Java basic
 
Java multi threading
Java multi threadingJava multi threading
Java multi threading
 
React JS
React JSReact JS
React JS
 
React js
React jsReact js
React js
 
OOPS IN C++
OOPS IN C++OOPS IN C++
OOPS IN C++
 
Memory Management C++ (Peeling operator new() and delete())
Memory Management C++ (Peeling operator new() and delete())Memory Management C++ (Peeling operator new() and delete())
Memory Management C++ (Peeling operator new() and delete())
 
Program activation records
Program activation recordsProgram activation records
Program activation records
 
First-person Shooters
First-person ShootersFirst-person Shooters
First-person Shooters
 

Andere mochten auch

CMake: Improving Software Quality and Process
CMake: Improving Software Quality and ProcessCMake: Improving Software Quality and Process
CMake: Improving Software Quality and Process
Marcus Hanwell
 
Intelligent well completio nm
Intelligent well completio nmIntelligent well completio nm
Intelligent well completio nm
basil_c
 
Clean Code II - Dependency Injection
Clean Code II - Dependency InjectionClean Code II - Dependency Injection
Clean Code II - Dependency Injection
Theo Jungeblut
 
Interfaces to ubiquitous computing
Interfaces to ubiquitous computingInterfaces to ubiquitous computing
Interfaces to ubiquitous computing
swati sonawane
 

Andere mochten auch (20)

Dependency Injection in C++ (Community Days 2015)
Dependency Injection in C++ (Community Days 2015)Dependency Injection in C++ (Community Days 2015)
Dependency Injection in C++ (Community Days 2015)
 
C++ Dependency Management 2.0
C++ Dependency Management 2.0C++ Dependency Management 2.0
C++ Dependency Management 2.0
 
CMake - Introduction and best practices
CMake - Introduction and best practicesCMake - Introduction and best practices
CMake - Introduction and best practices
 
CMake: Improving Software Quality and Process
CMake: Improving Software Quality and ProcessCMake: Improving Software Quality and Process
CMake: Improving Software Quality and Process
 
Dependencies Managers in C/C++. Using stdcpp 2014
Dependencies Managers in C/C++. Using stdcpp 2014Dependencies Managers in C/C++. Using stdcpp 2014
Dependencies Managers in C/C++. Using stdcpp 2014
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
Multithreading with Boost Thread and Intel TBB
Multithreading with Boost Thread and Intel TBBMultithreading with Boost Thread and Intel TBB
Multithreading with Boost Thread and Intel TBB
 
Long Life Software
Long Life SoftwareLong Life Software
Long Life Software
 
Water alternating gas (WAG) - A Enhanced Oil Recovery technique
Water alternating gas (WAG) - A Enhanced Oil Recovery techniqueWater alternating gas (WAG) - A Enhanced Oil Recovery technique
Water alternating gas (WAG) - A Enhanced Oil Recovery technique
 
Intelligent well completio nm
Intelligent well completio nmIntelligent well completio nm
Intelligent well completio nm
 
Intelligent well completion
Intelligent well completionIntelligent well completion
Intelligent well completion
 
Clean Code II - Dependency Injection
Clean Code II - Dependency InjectionClean Code II - Dependency Injection
Clean Code II - Dependency Injection
 
Agile for Embedded & System Software Development : Presented by Priyank KS
Agile for Embedded & System Software Development : Presented by Priyank KS Agile for Embedded & System Software Development : Presented by Priyank KS
Agile for Embedded & System Software Development : Presented by Priyank KS
 
3.7 heap sort
3.7 heap sort3.7 heap sort
3.7 heap sort
 
Interfaces to ubiquitous computing
Interfaces to ubiquitous computingInterfaces to ubiquitous computing
Interfaces to ubiquitous computing
 
iBeacons: Security and Privacy?
iBeacons: Security and Privacy?iBeacons: Security and Privacy?
iBeacons: Security and Privacy?
 
Intelligent well completions
Intelligent well completionsIntelligent well completions
Intelligent well completions
 
Demystifying dependency Injection: Dagger and Toothpick
Demystifying dependency Injection: Dagger and ToothpickDemystifying dependency Injection: Dagger and Toothpick
Demystifying dependency Injection: Dagger and Toothpick
 
Dependency Injection with Apex
Dependency Injection with ApexDependency Injection with Apex
Dependency Injection with Apex
 
Agile London: Industrial Agility, How to respond to the 4th Industrial Revolu...
Agile London: Industrial Agility, How to respond to the 4th Industrial Revolu...Agile London: Industrial Agility, How to respond to the 4th Industrial Revolu...
Agile London: Industrial Agility, How to respond to the 4th Industrial Revolu...
 

Ähnlich wie Going native with less coupling: Dependency Injection in C++

15LLP108_Demo4_LedBlinking.pdf1. Introduction In D.docx
15LLP108_Demo4_LedBlinking.pdf1. Introduction In D.docx15LLP108_Demo4_LedBlinking.pdf1. Introduction In D.docx
15LLP108_Demo4_LedBlinking.pdf1. Introduction In D.docx
felicidaddinwoodie
 

Ähnlich wie Going native with less coupling: Dependency Injection in C++ (20)

Meetup SkillValue - Angular 6 : Bien démarrer son application
Meetup SkillValue - Angular 6 : Bien démarrer son applicationMeetup SkillValue - Angular 6 : Bien démarrer son application
Meetup SkillValue - Angular 6 : Bien démarrer son application
 
generate IP CORES
generate IP CORESgenerate IP CORES
generate IP CORES
 
Contiki Operating system tutorial
Contiki Operating system tutorialContiki Operating system tutorial
Contiki Operating system tutorial
 
Adding Love to an API (or How to Expose C++ in Unity)
Adding Love to an API (or How to Expose C++ in Unity)Adding Love to an API (or How to Expose C++ in Unity)
Adding Love to an API (or How to Expose C++ in Unity)
 
8.3 program structure (1 hour)
8.3 program structure (1 hour)8.3 program structure (1 hour)
8.3 program structure (1 hour)
 
Angular performance slides
Angular performance slidesAngular performance slides
Angular performance slides
 
Idea to Production - with Gitlab and Kubernetes
Idea to Production  - with Gitlab and KubernetesIdea to Production  - with Gitlab and Kubernetes
Idea to Production - with Gitlab and Kubernetes
 
The Ring programming language version 1.3 book - Part 62 of 88
The Ring programming language version 1.3 book - Part 62 of 88The Ring programming language version 1.3 book - Part 62 of 88
The Ring programming language version 1.3 book - Part 62 of 88
 
Component Object Model (COM, DCOM, COM+)
Component Object Model (COM, DCOM, COM+)Component Object Model (COM, DCOM, COM+)
Component Object Model (COM, DCOM, COM+)
 
Cpp
CppCpp
Cpp
 
Angular 2 in-1
Angular 2 in-1 Angular 2 in-1
Angular 2 in-1
 
The Ring programming language version 1.2 book - Part 59 of 84
The Ring programming language version 1.2 book - Part 59 of 84The Ring programming language version 1.2 book - Part 59 of 84
The Ring programming language version 1.2 book - Part 59 of 84
 
PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerC...
PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerC...PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerC...
PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerC...
 
2621008 - C++ 1
2621008 -  C++ 12621008 -  C++ 1
2621008 - C++ 1
 
High performance web programming with C++14
High performance web programming with C++14High performance web programming with C++14
High performance web programming with C++14
 
The Ring programming language version 1.7 book - Part 82 of 196
The Ring programming language version 1.7 book - Part 82 of 196The Ring programming language version 1.7 book - Part 82 of 196
The Ring programming language version 1.7 book - Part 82 of 196
 
embeddedc-lecture1-160404055102.pptx
embeddedc-lecture1-160404055102.pptxembeddedc-lecture1-160404055102.pptx
embeddedc-lecture1-160404055102.pptx
 
The Ring programming language version 1.4 book - Part 22 of 30
The Ring programming language version 1.4 book - Part 22 of 30The Ring programming language version 1.4 book - Part 22 of 30
The Ring programming language version 1.4 book - Part 22 of 30
 
cscript_controller.pdf
cscript_controller.pdfcscript_controller.pdf
cscript_controller.pdf
 
15LLP108_Demo4_LedBlinking.pdf1. Introduction In D.docx
15LLP108_Demo4_LedBlinking.pdf1. Introduction In D.docx15LLP108_Demo4_LedBlinking.pdf1. Introduction In D.docx
15LLP108_Demo4_LedBlinking.pdf1. Introduction In D.docx
 

Kürzlich hochgeladen

Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdfMastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
mbmh111980
 

Kürzlich hochgeladen (20)

Benefits of Employee Monitoring Software
Benefits of  Employee Monitoring SoftwareBenefits of  Employee Monitoring Software
Benefits of Employee Monitoring Software
 
A Guideline to Zendesk to Re:amaze Data Migration
A Guideline to Zendesk to Re:amaze Data MigrationA Guideline to Zendesk to Re:amaze Data Migration
A Guideline to Zendesk to Re:amaze Data Migration
 
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAGAI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
 
De mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEDe mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FME
 
Agnieszka Andrzejewska - BIM School Course in Kraków
Agnieszka Andrzejewska - BIM School Course in KrakówAgnieszka Andrzejewska - BIM School Course in Kraków
Agnieszka Andrzejewska - BIM School Course in Kraków
 
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdfA Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
 
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
 
Advanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should KnowAdvanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should Know
 
Secure Software Ecosystem Teqnation 2024
Secure Software Ecosystem Teqnation 2024Secure Software Ecosystem Teqnation 2024
Secure Software Ecosystem Teqnation 2024
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
Designing for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web ServicesDesigning for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web Services
 
Using IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandUsing IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New Zealand
 
top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownload
 
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
 
10 Essential Software Testing Tools You Need to Know About.pdf
10 Essential Software Testing Tools You Need to Know About.pdf10 Essential Software Testing Tools You Need to Know About.pdf
10 Essential Software Testing Tools You Need to Know About.pdf
 
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdfMastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdf
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
 
Studiovity film pre-production and screenwriting software
Studiovity film pre-production and screenwriting softwareStudiovity film pre-production and screenwriting software
Studiovity film pre-production and screenwriting software
 

Going native with less coupling: Dependency Injection in C++

  • 1. www.italiancpp.org Going native with less coupling Dependency Injection in C++
  • 2. Italian C++ Community Style 1: [Fake] OO Design i=2 CONTROLLER / MANAGER Dumb object Dumb object Dumb object Dumb object Dumb object Dumb object Dumb object Dumb object
  • 3. Italian C++ Community Style 2: [True] OO design i=3 Smart Object Smart Object Smart Object Smart Object Smart Object Smart Object Smart Object Smart Object Smart Object Smart Object Smart Object Smart Object Smart Object Smart Object
  • 4. Italian C++ Community OO Architecture Benefits i=4 Up Scalability (extension) Down Scalability (contraction) Reusability Safety (testability)
  • 5. Italian C++ Community i=5 The Wiring Issue In a True Modular Architecture, wiring is critical
  • 6. Italian C++ Community The Wiring Issue When you've got a Good Architecture, you deal with requirements changes by adding/removing/substituting objects So, we need a simple way to: Change the type of the objects Create new objects Modify the wiring of the objects i=6
  • 7. Italian C++ Community i=7 Life without a CONTROLLER Example taken from: Carlo Pescio's blog – March 2012
  • 8. Italian C++ Community First Design i=8 MinePlant SumpPump +Drain() PumpEngine +On() +Off() DigitalOutput +Write() GasSensor <<interface>> +IsCritical() GasAlarm +Watch() 1..* Alarm +On() +Off() SafeEngine
  • 9. Italian C++ Community Requirements Change i=9 MinePlant SumpPump +Drain() PumpEngine +On() +Off() DigitalOutput +Write() GasSensor <<interface>> +IsCritical() GasAlarm +Watch() 1..* Alarm +On() +Off() SafeEngine
  • 10. Italian C++ Community Extension The design is robust: I only need to add a class But… Who creates SafeEngine instead of PumpEngine? How does SafeEngine get the pointer to the GasSensor (the same used by GasAlarm)? i=10
  • 11. Italian C++ Community Solution #1: Local Creation Each class creates its own dependencies i=11
  • 12. Italian C++ Community i=12 MinePlant SumpPump +Drain() PumpEngine +On() +Off() DigitalOutput +Write() GasSensor <<interface>> +IsCritical() GasAlarm +Watch() 1..* Alarm +On() +Off() SafeEngine <<create>>
  • 13. Italian C++ Community Solution #1: Consequences The SumpPump constructor creates a SafeEngine instead of a PumpEngine. … but SafeEngine needs a pointer to the GasSensor instance already used by GasAlarm. So, we must pass it as a parameter to SumpPump constructor. i=13
  • 14. Italian C++ Community Solution #1: Properties If I need to change the concrete type, I have to modify the client. It's difficult to reuse the same client class (even in the same application). i=14
  • 15. Italian C++ Community Solution #1: Summary SafeEngine class added SumpPump constructor modified MinePlant modified i=15
  • 16. Italian C++ Community Solution #2: Factory (not the GoF factory) Create objects without exposing the instantiation logic to the client i=16
  • 17. Italian C++ Community i=17 <<create>>
  • 18. Italian C++ Community Solution #2: Consequences The SumpPump constructor takes a Factory as parameter. PumpEngineFactory instantiates a PumpEngine. SafeEngineFactory instantiates a SafeEngine. SafeEngine still needs a pointer to the GasSensor instance already used by GasAlarm, so we must pass it to the SafeEngineFactory constructor. i=18
  • 19. Italian C++ Community Solution #2: Summary SafeEngine class added SafeEngineFactory added MinePlant modified i=19
  • 20. Italian C++ Community Solution #3: Service Locator It’s a registry containing the instances to use i=20
  • 21. Italian C++ Community Solution #3: Service Locator i=21 class ServiceLocator { public: static ServiceLocator& Instance(); shared_ptr< PumpEngine > Engine(); void Engine( const shared_ptr< PumpEngine >& engine ); private: ... };
  • 22. Italian C++ Community Solution #3: Service Locator i=22 // MinePlant: auto e = make_shared< SafeEngine >( engineOutput, gasSensor ); ServiceLocator::Instance().Engine( e ); // SumpPump: SumpPump::SumpPump() : engine( ServiceLocator::Instance().Engine() ) { }
  • 23. Italian C++ Community Solution #3: Properties Clients aware of the locator Dependencies not explicit / evident Dependencies not checked by compiler i=23
  • 24. Italian C++ Community Solution #3: Summary SafeEngine class added MinePlant modified i=24
  • 25. Italian C++ Community Solution #4: Dependency Injection Dependency Injection is when you have something setting the dependencies for you. i=25
  • 26. Italian C++ Community Solution #4: Dependency Injection Classes don't create their own dependencies They're passed from outside i=26
  • 27. Italian C++ Community Dependency Injection i=27 auto gasSensor = ... auto alarmOutput = make_shared<DigitalOutput>("/dev/ttyS0"); auto alarm = make_shared<Alarm>(alarmOutput); auto gasAlarm = make_shared<GasAlarm>(gasSensor,alarm); auto engineOutput = make_shared<DigitalOutput>("/dev/ttyS1"); auto engine = make_shared<PumpEngine>(engineOutput); auto pump = make_shared<SumpPump>(engine);
  • 28. Italian C++ Community Dependency Injection i=28 auto gasSensor = ... auto alarmOutput = make_shared<DigitalOutput>("/dev/ttyS0"); auto alarm = make_shared<Alarm>(alarmOutput); auto gasAlarm = make_shared<GasAlarm>(gasSensor,alarm); auto engineOutput = make_shared<DigitalOutput>("/dev/ttyS1"); // auto engine = make_shared<PumpEngine>(engineOutput); auto engine = make_shared<SafeEngine>(engineOutput,gasSensor); auto pump = make_shared<SumpPump>(engine);
  • 29. Italian C++ Community Solution #4: Properties Complete separation between: application logic (classes) wiring (main/builder) i=29
  • 30. Italian C++ Community Solution #4: Summary SafeEngine class added MinePlant modified (one liner) i=30
  • 31. Italian C++ Community i=31 Can we do BETTER SafeEngine must be added anyway. … can we remove the one liner in MinePlant? ?
  • 32. Italian C++ Community i=32 Configuration DrivenWIRING moving creation and wiring outside the code, in a configuration file
  • 33. Italian C++ Community Why? To easily get extensibility/contraction (without having to touch zillion files and recompile everything) i=33
  • 34. Italian C++ Community From Identifiers to Strings Improving Previous Solution: Objects creation from string Objects identified by name Objects connected by name i=34
  • 35. Italian C++ Community Run-time Reflection Missing… Create("Foo") vs new Foo Enumerate the dependencies “Inject” the right object address in a class dependency i=35
  • 36. Italian C++ Community Solution #5: Dependency Injection + Dependency Injection is when you have something setting the dependencies for you. …this something is usually a framework. i=36
  • 37. Italian C++ Community Existing libraries (C++) i=37 QtIOCContainer Sauce DICPP Hypodermic2 Pococapsule Main issues: Compile time injection only Code generators needed
  • 38. Italian C++ Community Enter Wallaroo Library i=38 wallaroo.googlecode.com wallarooC++ Dependency Injection
  • 39. Italian C++ Community Creating objects i=39 Catalog catalog; ... catalog.Create("alarmOutput","DigitalOutput","/dev/ttyS0"); catalog.Create("alarm","Alarm"); catalog.Create("gasAlarm","GasAlarm"); catalog.Create("engineOutput","DigitalOutput","/dev/ttyS1"); catalog.Create("pump","SumpPump"); catalog.Create("engine","SafeEngine");
  • 40. Italian C++ Community Creating objects (from cfg) i=40 <parts> <part> <name>pump</name> <class>SumpPump</class> </part> <part> <name>engine</name> <class>SafeEngine</class> </part> </parts> ... Catalog catalog; XmlConfiguration file("wiring.xml"); file.Fill( catalog ); ...
  • 41. Italian C++ Community Object lookup by name i=41 shared_ptr< SumpPump > pump = catalog[ "pump" ];
  • 42. Italian C++ Community Connect Things by name (DSL) i=42 Catalog catalog; // fill catalog ... use(catalog["alarmOutput"]).as("out").of(catalog["alarm" ]); use(catalog["safeEngine"]).as("engine").of(catalog["pump"]);
  • 43. Italian C++ Community Connect Things by name (DSL) i=43 Catalog catalog; // fill catalog ... wallaroo_within( catalog ) { use( "alarmOutput" ).as( "out" ).of( "alarm" ); use( "safeEngine" ).as( "engine" ).of( "pump" ); }
  • 44. Italian C++ Community Connect Things by name (from cfg) i=44 <wiring> <wire> <source>alarm</source> <dest>alarmOutput</dest> <collaborator>out</collaborator> </wire> <wire> <source>pump</source> <dest>safeEngine</dest> <collaborator>engine</collaborator> </wire> </wiring> Catalog catalog; ... XmlConfiguration file( "wiring.xml" ); file.Fill( catalog ); catalog.CheckWiring(); ...
  • 45. Italian C++ Community Class Declaration i=45 #include "wallaroo/registered.h" using namespace wallaroo; class SumpPump : public Part { public: SumpPump( int id ); private: Collaborator< Engine > engine; };
  • 46. Italian C++ Community Class Registration i=46 WALLAROO_REGISTER( SumpPump, int ) SumpPump::SumpPump( int id ) : engine( "engine", RegistrationToken() ) { ... } // other methods definition here ...
  • 47. Italian C++ Community Shared Libraries – AKA plugins (code) i=47 Plugin::Load( "safeengine" + Plugin::Suffix() ); // Plugin::Suffix() expands to .dll or .so according to the OS
  • 48. Italian C++ Community Shared Libraries – AKA plugins (cfg) i=48 <plugins> <shared>safeengine</shared> </plugins> Catalog catalog; XmlConfiguration file( "wiring.xml" ); // load the shared libraries specified in the configuration file: file.LoadPlugins(); file.Fill( catalog ); // throws a WiringError exception if any dependency is missing: catalog.CheckWiring();
  • 49. Italian C++ Community Collections i=49 class Car : public wallaroo::Part { ... private: Collaborator< Engine > engine; Collaborator< AirConditioning, optional > airConditioning; Collaborator< Airbag, collection > airbags; Collaborator< Speaker, collection, std::list > speakers; Collaborator< Seat, bounded_collection< 2, 6 > > seats; };
  • 50. Italian C++ Community Checks i=50 if ( !catalog.IsWiringOk() ) { // error handling } catalog.CheckWiring() // throws exception
  • 51. Italian C++ Community Initialization i=51 class Part { ... public: virtual void Init() {} ... }; catalog.Init() // calls Part::Init for each part in catalog
  • 52. Italian C++ Community Wallaroo Internals WALLAROO_REGISTER declares a static object. Its constructor creates a factory and puts it in a table, with the class name as key. Catalog::Create uses the factory to put a new instance in the catalog. wallaroo::Part has a table of <name, Collaborator> i=52
  • 53. Italian C++ Community Wallaroo Internals shared_ptr< Foo > foo = catalog[ “foo” ]; catalog[ “foo” ] returns a class that defines operator shared_ptr< T >() Collaborator uses weak_ptr for the dependency Collaborator defines operator shared_ptr() and operator->() i=53
  • 54. Italian C++ Community Wallaroo Internals i=54 wallaroo_within( catalog ) { use("alarmOutput").as("out").of("alarm"); use("safeEngine").as("engine").of("pump"); } for ( Context c(catalog);c.FirstTime();c.Terminate() ) { use("alarmOutput").as("out").of("alarm"); use("safeEngine").as("engine").of("pump"); }
  • 55. Italian C++ Community Wallaroo Strengths Lightweight (header file only) Portable Type Safe DSL syntax for object creation and wiring Configuration driven wiring (xml and json) Shared library support (plugin) C++11/14 or boost interface No code generators i=55
  • 56. Italian C++ Community Design is a balance of forces Intrusive VS Non Intrusive Non Intrusive Solutions can manage existing classes but require code generators for configuration driven wiring i=56
  • 57. Italian C++ Community Design is a balance of forces Configuration-driven wiring VS static type checking By moving the wiring in a configuration file, we give up the static type checking. But it’s ok, since you build your system at startup. i=57
  • 58. Italian C++ Community Action Points Real OOD (no controllers / managers) Manual Dependency Injection Wallaroo (configuration-driven wiring) i=58
  • 59. Italian C++ Community References & Credits Me: @DPallastrelli Me: it.linkedin.com/in/pallad Rate me: https://joind.in/12277 Wallaroo: wallaroo.googlecode.com i=59 MinePlant example from Carlo Pescio's blog (http://www.carlopescio.com/2012/03/life- without-controller-case-1.html) Wiring Picture: By Gael Mace (Own work (Personal photograph)) [CC-BY-3.0 (http://creativecommons.org/licenses/by/3.0)], via Wikimedia Commons