SlideShare a Scribd company logo
1	of	6
InvertingDependencies
photo credit: Stéfan	(http://www.flickr.com/photos/st3f4n/4085958000/)	()	via
photopin	(http://photopin.com)	cc	(http://creativecommons.org/licenses/by-nc-sa/2.0/)
Polymorphism is the super power of the OO designer. However, many designers don't exploit
this power, they use inheritance for structural purposes. In a language like Java, this results in
an abuse of the instanceof statement	(http://www.javapractices.com/topic/TopicAction.do?Id=31)	.
Maybe Polymorphism is not the right word; maybe we should use multiple personality
disorder (not as sexy as polymorphism when you're trying to sell your OO suite...). Depending
on the runtime context, the object does not change form, it does not morph, it changes
behavior, it behaves as another object.
But the interesting part of this mechanism is how the dependencies align. Looking at the
dependencies from a UML Class diagram viewpoint, inheritance goes in the opposite
direction as composition or aggregation.
The next example shows two different ways for the print method of Object to invoke the
myFunction method of Child. The first case, Child inherites from Object (Template Method
Pattern	(http://sourcemaking.com/design_patterns/template_method)	) this require the myFunction
method to be present in Object. In the second case, Object depends on Child and invokes it.
2	of	6
Object
void	print()
Child
int	myFunction()
Object
int	myFunction()
void	print()
Child
int	myFunction()
However looking at it from a UML sequence diagram viewpoint, the direction of the method
invocation is not reversed.
o:Object c:Child
print()
myFunction()
Concretely, inheritance is a tool that offers the possibility to inverse dependencies arrows
while preserving the direction of behavioral arrows! This super power can be extremely
powerful in light of architectural styles that impose constraints on the direction of
dependencies.
Examples of constraints imposed on the direction of dependencies are Robert C. Martin's
"The Dependency Rule"	(http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html)	and the
layers architectural style. The later imposes a downward "can use" relationship between
layers. By using inheritance, one can respect this structural constraint of downward
dependencies yet allow behavior to invoke upwards.
Let see how all this works, but to do so, let's use a programming language that is not object
oriented. This way the details will not be hidden away by syntactic sugar or by compiler magic.
Let's start by defining Object with a simple struct (Object.h
(https://github.com/luctrudeau/InvertingDependencies/blob/master/Object.h)	)
struct	Object;
struct	Object	build(int	a,	int	b);
struct	Object	{
				int	a;
				int	b;

3	of	6
The first line is a forward declaration, it's required because the Object structure is used inside
the definition of the Object structure. Next, there's the build function that is the equivalent of
a constructor/factory. Finally the Object structure is defined. Notice that the last two
declarations are function pointers. These two function pointers are myFunction that expects
an Object structure as parameter and print that also expects an Object structure as parameter.
Notice that all the implementation details are hidden in Object.c (this is encapsulation). The
idea behind this header file is to expose only the structure but not the behavior. No one
knows, how build work, or even what's in myFunction or print, but they know that these
functions exist. This separation is key in flipping the direction of the dependency without
flipping the direction of invocation.
To find out what the behavior is, we can look at the Object.c
(https://github.com/luctrudeau/InvertingDependencies/blob/master/Object.c)	file.
Now we know that myFunction points to an add function, and that print simply does a printf.
Even if not all languages use the same keyword, the concept of an abstract method is
generally available. We can match this concept to the functions pointers. If these pointers are
not assigned then the method is abstract. This is why you can't instantiate classes with
abstract methods.
Notice that the parameter of the functions inside the Object structure are structures of type
Object. For now, we can think of this as a solution to the problem of accessing the values of
the instance of the Object structure, but we will see shortly that there's another more
				int	(*myFunction)(struct	Object);
				void	(*print)(struct	Object);	
};
#include	"Object.h"
int	add(struct	Object	o)
{
				return	o.a	+	o.b;
}
void	print(struct	Object	o)
{
				printf("Result	=	%dn",	o.myFunction(o));
}
struct	Object	build(int	a,	int	b)
{
				struct	Object	o;
				o.a	=	a;
				o.b	=	b;
				o.myFunction	=	&add;
				o.print	=	&print;
				return	o;
}

4	of	6
profound mechanism at work here. Some programming languages hide this detail behind the
"this" keyword, others like python will make the instance parameter visible to developer and
define it as the first parameter of every method.
Let's say main.c wants to use the Object structure, it only need to include "Object.h", it does
not need to care about Object.c. If we look at the dependencies we can see the inversion effect.
The main.c file depends on Object.h but Object.h does not depend upon Object.c, it's the other
way around Object.c depends upon Object.h. The header file is an abstraction.
main.c
Object.h
struct	Object
struct	Object	build(int	a,	int	b)
Object.c
int	add(struct	Object	o){...}
void	print(struct	Object	o){...}
struct	Object	build(int	a,	int	b)	{...}
<<includes>>
<<includes>>
Now let's try inheritance, I'm not interested in structural inheritance, I don't want to add a
third variable to Object. I'm interested in polymorphism; I want to change the behavior of
Object.
This is the content of Child.h	(https://github.com/luctrudeau/InvertingDependencies/blob/master/Child.h)
The Child depends on Object.h and defines a new constructor/factory buildChild. Let's look at
its behavior (Child.c	(https://github.com/luctrudeau/InvertingDependencies/blob/master/Child.c)	)
#include	"Object.h"
struct	Object	buildChild(int	a,	int	b);

#include	"Child.h"
int	sub(struct	Object	o)
{
				return	o.a	-	o.b;
}
struct	Object	buildChild(int	a,	int	b)
{
				struct	Object	o	=	build(a,b);
				o.myFunction	=	&sub;
				return	o;
}

5	of	6
Instead of invoking the add function, the Child version of the Object structure will invoke the
sub function. Notice how the buildChild function invokes build of Object and then overrides
the myFunction function pointer.
Now we have an Object that acts like a Child, yet almost no one needs to know. The only
entity that needs to know is the one calling buildChild function instead of the build function.
This switch can be executed dynamically at runtime. Looking at main.c we can see that the
choice between the build or the buildChild functions is performed dynamically based on a
random variable.
Dependency injection	(http://martinfowler.com/articles/injection.html)	is exactly what is going on
inside the print function. At runtime, when the buildChild function is selected, the Child
variant of Object is being injected into the print function. This is interesting because the type
of the parameter is mandatory (aka closed	(http://en.wikipedia.org/wiki/Open/closed_principle)	) but its
behavior is not (aka open	(http://en.wikipedia.org/wiki/Open/closed_principle)	).
The Child variant of Object can be developed years after Object was written, by completely
different developers, yet it will still work inside print function without requiring modifications
to the print function.
#include	<stdio.h>
#include	<stdlib.h>
#include	<time.h>
#include	"Object.h"
#include	"Child.h"
int	main()
{
				struct	Object	o;
				srand(time(0));
				if	(rand()	%	2)
				{
								o	=	buildChild(5,	3);
				}	else	{
								o	=	build(2,	3);
				}
				o.print(o);
}

6	of	6
main.c
Object.h
struct	Object
struct	Object	build(int	a,	int	b)
Object.c
int	add(struct	Object	o){...}
void	print(struct	Object	o){...}
struct	Object	build(int	a,	int	b)	{...}
Child.h
struct	Object	buildChild(int	a,	int	b)
Child.c
int	sub(struct	Object	o){...}
struct	Object	buildChild(int	a,	int	b)	{...}
<<includes>><<includes>>
<<includes>>
<<includes>>
<<includes>>
Not only does this allows the Object's print function to invoke the Child's sub function
without depending on it, but to do so Child is the one depending on the Object.

More Related Content

What's hot (20)

PPTX
Javascript Objects Deep Dive
Manish Jangir
 
PPTX
Javascript Prototypal Inheritance - Big Picture
Manish Jangir
 
PDF
Javascript Design Patterns
Subramanyan Murali
 
PPTX
Javascript Design Patterns
Iván Fernández Perea
 
PPTX
Java Static Factory Methods
Ye Win
 
PDF
Prototype
Aditya Gaur
 
PPTX
Introduction to Design Patterns in Javascript
Santhosh Kumar Srinivasan
 
PPTX
Factory Design Pattern
Jaswant Singh
 
PPTX
Avoid creating unncessary objects
Ye Win
 
PDF
Design Patterns Illustrated
Herman Peeren
 
PPT
Patterns In-Javascript
Mindfire Solutions
 
PPT
JavaScript - Programming Languages course
yoavrubin
 
PPTX
Design pattern (Abstract Factory & Singleton)
paramisoft
 
DOCX
25 java tough interview questions
Arun Banotra
 
PDF
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2
Philip Schwarz
 
PDF
Oop Extract
Ganesh Samarthyam
 
PDF
Scalable JavaScript Design Patterns
Addy Osmani
 
DOCX
Angular Interview Questions & Answers
Ratnala Charan kumar
 
PDF
Compositionality and Category Theory - a montage of slides/transcript for sec...
Philip Schwarz
 
PDF
Definitions of Functional Programming
Philip Schwarz
 
Javascript Objects Deep Dive
Manish Jangir
 
Javascript Prototypal Inheritance - Big Picture
Manish Jangir
 
Javascript Design Patterns
Subramanyan Murali
 
Javascript Design Patterns
Iván Fernández Perea
 
Java Static Factory Methods
Ye Win
 
Prototype
Aditya Gaur
 
Introduction to Design Patterns in Javascript
Santhosh Kumar Srinivasan
 
Factory Design Pattern
Jaswant Singh
 
Avoid creating unncessary objects
Ye Win
 
Design Patterns Illustrated
Herman Peeren
 
Patterns In-Javascript
Mindfire Solutions
 
JavaScript - Programming Languages course
yoavrubin
 
Design pattern (Abstract Factory & Singleton)
paramisoft
 
25 java tough interview questions
Arun Banotra
 
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2
Philip Schwarz
 
Oop Extract
Ganesh Samarthyam
 
Scalable JavaScript Design Patterns
Addy Osmani
 
Angular Interview Questions & Answers
Ratnala Charan kumar
 
Compositionality and Category Theory - a montage of slides/transcript for sec...
Philip Schwarz
 
Definitions of Functional Programming
Philip Schwarz
 

Similar to Inverting Dependencies (20)

ODP
Ppt of c++ vs c#
shubhra chauhan
 
DOC
Abstract
snehajyothi
 
PPTX
OOPS Basics With Example
Thooyavan Venkatachalam
 
PPTX
Object Oriented Programming using c++.pptx
olisahchristopher
 
PPTX
Object oriented programming
MH Abid
 
PPTX
Object Oriented Programming using C++(UNIT 1)
Dr. SURBHI SAROHA
 
PPTX
OOPS IN C++
Amritsinghmehra
 
PPTX
Polymorphism.Difference between Inheritance & Polymorphism
huzaifaakram12
 
PPTX
Object Oriented Programming using C++: Ch09 Inheritance.pptx
RashidFaridChishti
 
PPT
Inheritance.ppt
KevinNicolaNatanael
 
PPTX
4-OOPS.pptx
SatyamMishra237306
 
PPTX
Inheritance
sourav verma
 
PPTX
Core idea driving and defining OO: using dynamic polymorphism to invert key a...
Philip Schwarz
 
PPTX
INHERITANCE.pptx
AteeqaKokab1
 
PPT
Visula C# Programming Lecture 7
Abou Bakr Ashraf
 
PPTX
OOP, API Design and MVP
Harshith Keni
 
PPTX
CSharp_03_Inheritance_introduction_with_examples
Ranjithsingh20
 
PDF
C++ Multiple Inheritance
harshaltambe
 
Ppt of c++ vs c#
shubhra chauhan
 
Abstract
snehajyothi
 
OOPS Basics With Example
Thooyavan Venkatachalam
 
Object Oriented Programming using c++.pptx
olisahchristopher
 
Object oriented programming
MH Abid
 
Object Oriented Programming using C++(UNIT 1)
Dr. SURBHI SAROHA
 
OOPS IN C++
Amritsinghmehra
 
Polymorphism.Difference between Inheritance & Polymorphism
huzaifaakram12
 
Object Oriented Programming using C++: Ch09 Inheritance.pptx
RashidFaridChishti
 
Inheritance.ppt
KevinNicolaNatanael
 
4-OOPS.pptx
SatyamMishra237306
 
Inheritance
sourav verma
 
Core idea driving and defining OO: using dynamic polymorphism to invert key a...
Philip Schwarz
 
INHERITANCE.pptx
AteeqaKokab1
 
Visula C# Programming Lecture 7
Abou Bakr Ashraf
 
OOP, API Design and MVP
Harshith Keni
 
CSharp_03_Inheritance_introduction_with_examples
Ranjithsingh20
 
C++ Multiple Inheritance
harshaltambe
 
Ad

More from Luc Trudeau (11)

PDF
Revue de l'année 2019 dans le monde des codecs videos
Luc Trudeau
 
PDF
I don’t care if you have 360 Intra directional predictors
Luc Trudeau
 
PDF
Les technologies actuelles et futures de l'ott
Luc Trudeau
 
PDF
Chroma from Luma Intra Prediction for AV1
Luc Trudeau
 
PDF
Chroma From Luma Status Update
Luc Trudeau
 
PDF
ML2 et le Codetributhon
Luc Trudeau
 
PDF
HTTP Long Polling is awesome
Luc Trudeau
 
PDF
UML Class Diagrams are Awesome
Luc Trudeau
 
PDF
Orchestre de services
Luc Trudeau
 
PPTX
HTTP et REST
Luc Trudeau
 
PPTX
Architecture vs Design
Luc Trudeau
 
Revue de l'année 2019 dans le monde des codecs videos
Luc Trudeau
 
I don’t care if you have 360 Intra directional predictors
Luc Trudeau
 
Les technologies actuelles et futures de l'ott
Luc Trudeau
 
Chroma from Luma Intra Prediction for AV1
Luc Trudeau
 
Chroma From Luma Status Update
Luc Trudeau
 
ML2 et le Codetributhon
Luc Trudeau
 
HTTP Long Polling is awesome
Luc Trudeau
 
UML Class Diagrams are Awesome
Luc Trudeau
 
Orchestre de services
Luc Trudeau
 
HTTP et REST
Luc Trudeau
 
Architecture vs Design
Luc Trudeau
 
Ad

Recently uploaded (20)

PPTX
Tally software_Introduction_Presentation
AditiBansal54083
 
PDF
Linux Certificate of Completion - LabEx Certificate
VICTOR MAESTRE RAMIREZ
 
PDF
vMix Pro 28.0.0.42 Download vMix Registration key Bundle
kulindacore
 
PPTX
Home Care Tools: Benefits, features and more
Third Rock Techkno
 
PDF
4K Video Downloader Plus Pro Crack for MacOS New Download 2025
bashirkhan333g
 
PPTX
Migrating Millions of Users with Debezium, Apache Kafka, and an Acyclic Synch...
MD Sayem Ahmed
 
PDF
MiniTool Partition Wizard 12.8 Crack License Key LATEST
hashhshs786
 
PDF
Why Businesses Are Switching to Open Source Alternatives to Crystal Reports.pdf
Varsha Nayak
 
PDF
Revenue streams of the Wazirx clone script.pdf
aaronjeffray
 
PDF
Driver Easy Pro 6.1.1 Crack Licensce key 2025 FREE
utfefguu
 
PDF
Digger Solo: Semantic search and maps for your local files
seanpedersen96
 
PPTX
Transforming Mining & Engineering Operations with Odoo ERP | Streamline Proje...
SatishKumar2651
 
PPTX
Homogeneity of Variance Test Options IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
Alarm in Android-Scheduling Timed Tasks Using AlarmManager in Android.pdf
Nabin Dhakal
 
PDF
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
PPTX
Agentic Automation Journey Session 1/5: Context Grounding and Autopilot for E...
klpathrudu
 
PDF
유니티에서 Burst Compiler+ThreadedJobs+SIMD 적용사례
Seongdae Kim
 
PDF
HiHelloHR – Simplify HR Operations for Modern Workplaces
HiHelloHR
 
PDF
Automate Cybersecurity Tasks with Python
VICTOR MAESTRE RAMIREZ
 
PDF
Open Chain Q2 Steering Committee Meeting - 2025-06-25
Shane Coughlan
 
Tally software_Introduction_Presentation
AditiBansal54083
 
Linux Certificate of Completion - LabEx Certificate
VICTOR MAESTRE RAMIREZ
 
vMix Pro 28.0.0.42 Download vMix Registration key Bundle
kulindacore
 
Home Care Tools: Benefits, features and more
Third Rock Techkno
 
4K Video Downloader Plus Pro Crack for MacOS New Download 2025
bashirkhan333g
 
Migrating Millions of Users with Debezium, Apache Kafka, and an Acyclic Synch...
MD Sayem Ahmed
 
MiniTool Partition Wizard 12.8 Crack License Key LATEST
hashhshs786
 
Why Businesses Are Switching to Open Source Alternatives to Crystal Reports.pdf
Varsha Nayak
 
Revenue streams of the Wazirx clone script.pdf
aaronjeffray
 
Driver Easy Pro 6.1.1 Crack Licensce key 2025 FREE
utfefguu
 
Digger Solo: Semantic search and maps for your local files
seanpedersen96
 
Transforming Mining & Engineering Operations with Odoo ERP | Streamline Proje...
SatishKumar2651
 
Homogeneity of Variance Test Options IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
Alarm in Android-Scheduling Timed Tasks Using AlarmManager in Android.pdf
Nabin Dhakal
 
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
Agentic Automation Journey Session 1/5: Context Grounding and Autopilot for E...
klpathrudu
 
유니티에서 Burst Compiler+ThreadedJobs+SIMD 적용사례
Seongdae Kim
 
HiHelloHR – Simplify HR Operations for Modern Workplaces
HiHelloHR
 
Automate Cybersecurity Tasks with Python
VICTOR MAESTRE RAMIREZ
 
Open Chain Q2 Steering Committee Meeting - 2025-06-25
Shane Coughlan
 

Inverting Dependencies

  • 1. 1 of 6 InvertingDependencies photo credit: Stéfan (http://www.flickr.com/photos/st3f4n/4085958000/) () via photopin (http://photopin.com) cc (http://creativecommons.org/licenses/by-nc-sa/2.0/) Polymorphism is the super power of the OO designer. However, many designers don't exploit this power, they use inheritance for structural purposes. In a language like Java, this results in an abuse of the instanceof statement (http://www.javapractices.com/topic/TopicAction.do?Id=31) . Maybe Polymorphism is not the right word; maybe we should use multiple personality disorder (not as sexy as polymorphism when you're trying to sell your OO suite...). Depending on the runtime context, the object does not change form, it does not morph, it changes behavior, it behaves as another object. But the interesting part of this mechanism is how the dependencies align. Looking at the dependencies from a UML Class diagram viewpoint, inheritance goes in the opposite direction as composition or aggregation. The next example shows two different ways for the print method of Object to invoke the myFunction method of Child. The first case, Child inherites from Object (Template Method Pattern (http://sourcemaking.com/design_patterns/template_method) ) this require the myFunction method to be present in Object. In the second case, Object depends on Child and invokes it.
  • 2. 2 of 6 Object void print() Child int myFunction() Object int myFunction() void print() Child int myFunction() However looking at it from a UML sequence diagram viewpoint, the direction of the method invocation is not reversed. o:Object c:Child print() myFunction() Concretely, inheritance is a tool that offers the possibility to inverse dependencies arrows while preserving the direction of behavioral arrows! This super power can be extremely powerful in light of architectural styles that impose constraints on the direction of dependencies. Examples of constraints imposed on the direction of dependencies are Robert C. Martin's "The Dependency Rule" (http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html) and the layers architectural style. The later imposes a downward "can use" relationship between layers. By using inheritance, one can respect this structural constraint of downward dependencies yet allow behavior to invoke upwards. Let see how all this works, but to do so, let's use a programming language that is not object oriented. This way the details will not be hidden away by syntactic sugar or by compiler magic. Let's start by defining Object with a simple struct (Object.h (https://github.com/luctrudeau/InvertingDependencies/blob/master/Object.h) ) struct Object; struct Object build(int a, int b); struct Object { int a; int b; 
  • 3. 3 of 6 The first line is a forward declaration, it's required because the Object structure is used inside the definition of the Object structure. Next, there's the build function that is the equivalent of a constructor/factory. Finally the Object structure is defined. Notice that the last two declarations are function pointers. These two function pointers are myFunction that expects an Object structure as parameter and print that also expects an Object structure as parameter. Notice that all the implementation details are hidden in Object.c (this is encapsulation). The idea behind this header file is to expose only the structure but not the behavior. No one knows, how build work, or even what's in myFunction or print, but they know that these functions exist. This separation is key in flipping the direction of the dependency without flipping the direction of invocation. To find out what the behavior is, we can look at the Object.c (https://github.com/luctrudeau/InvertingDependencies/blob/master/Object.c) file. Now we know that myFunction points to an add function, and that print simply does a printf. Even if not all languages use the same keyword, the concept of an abstract method is generally available. We can match this concept to the functions pointers. If these pointers are not assigned then the method is abstract. This is why you can't instantiate classes with abstract methods. Notice that the parameter of the functions inside the Object structure are structures of type Object. For now, we can think of this as a solution to the problem of accessing the values of the instance of the Object structure, but we will see shortly that there's another more int (*myFunction)(struct Object); void (*print)(struct Object); }; #include "Object.h" int add(struct Object o) { return o.a + o.b; } void print(struct Object o) { printf("Result = %dn", o.myFunction(o)); } struct Object build(int a, int b) { struct Object o; o.a = a; o.b = b; o.myFunction = &add; o.print = &print; return o; } 
  • 4. 4 of 6 profound mechanism at work here. Some programming languages hide this detail behind the "this" keyword, others like python will make the instance parameter visible to developer and define it as the first parameter of every method. Let's say main.c wants to use the Object structure, it only need to include "Object.h", it does not need to care about Object.c. If we look at the dependencies we can see the inversion effect. The main.c file depends on Object.h but Object.h does not depend upon Object.c, it's the other way around Object.c depends upon Object.h. The header file is an abstraction. main.c Object.h struct Object struct Object build(int a, int b) Object.c int add(struct Object o){...} void print(struct Object o){...} struct Object build(int a, int b) {...} <<includes>> <<includes>> Now let's try inheritance, I'm not interested in structural inheritance, I don't want to add a third variable to Object. I'm interested in polymorphism; I want to change the behavior of Object. This is the content of Child.h (https://github.com/luctrudeau/InvertingDependencies/blob/master/Child.h) The Child depends on Object.h and defines a new constructor/factory buildChild. Let's look at its behavior (Child.c (https://github.com/luctrudeau/InvertingDependencies/blob/master/Child.c) ) #include "Object.h" struct Object buildChild(int a, int b);  #include "Child.h" int sub(struct Object o) { return o.a - o.b; } struct Object buildChild(int a, int b) { struct Object o = build(a,b); o.myFunction = &sub; return o; } 
  • 5. 5 of 6 Instead of invoking the add function, the Child version of the Object structure will invoke the sub function. Notice how the buildChild function invokes build of Object and then overrides the myFunction function pointer. Now we have an Object that acts like a Child, yet almost no one needs to know. The only entity that needs to know is the one calling buildChild function instead of the build function. This switch can be executed dynamically at runtime. Looking at main.c we can see that the choice between the build or the buildChild functions is performed dynamically based on a random variable. Dependency injection (http://martinfowler.com/articles/injection.html) is exactly what is going on inside the print function. At runtime, when the buildChild function is selected, the Child variant of Object is being injected into the print function. This is interesting because the type of the parameter is mandatory (aka closed (http://en.wikipedia.org/wiki/Open/closed_principle) ) but its behavior is not (aka open (http://en.wikipedia.org/wiki/Open/closed_principle) ). The Child variant of Object can be developed years after Object was written, by completely different developers, yet it will still work inside print function without requiring modifications to the print function. #include <stdio.h> #include <stdlib.h> #include <time.h> #include "Object.h" #include "Child.h" int main() { struct Object o; srand(time(0)); if (rand() % 2) { o = buildChild(5, 3); } else { o = build(2, 3); } o.print(o); } 