SlideShare a Scribd company logo
1 of 21
Dependency injection
Jiří Matula
Neruším? Ráda bych vám pomohla
sVaší závislostí na ostatních!
Obsah
1. Co je to Dependency Injection (DI)
2. Motivace proč se zabývat DI
3. Typy DI
4. Problémy
5. DI Container
6. Závěr - testík
Dependency injection (DI)
• Návrhový vzor z rodiny IoC (Inversion of Control).
• Problém : Skryté závislosti třídy (skryté = těžce kontrolovatelné).
• Řešení: zřejmé předávání závislostí = odebrání třídám zodpovědnosti za
získávání objektů, které potřebují ke své činnosti.
• Uplatňuje se princip popisu závislostí pomocíAPI třídy.
• Lze si jej představit pod mottem - “Když něco chceš, tak si o to řekni!”
Vizualizace závislostí
(Satisfied person)
(Water)
(Alcohol)
(Friends)
(Vegetable)
(Meat)
(Cheese)
Proč se obtěžovat s DI?
Zvolnění vazeb mezi objekty,
jednodušší testovatelnost,
nutí programátora řešit vazby mezi objekty = čistější přehlednější kód,
pomáhá dodržovat správný objektový návrh,
pravdivé API tříd.
Junior programmerGarry –
“Whatever, I love my spaghetti !”
Constructor Injection
• Hlášení závislosti přímo v konstruktoru třídy.
• Problémy:
• Lazy loading (vytváření objektů v momentě, kdy jsou opravdu potřeba),
• Constructor hell (příliš mnoho závislostí v konstruktoru třídy).
public void Company() {
this.worker = new Worker();
this.slacker = new Slacker();
}
// constructor injection
public void Company(Worker worker, Slacker slacker) {
this.worker = worker;
this.slacker = slacker;
}
Setter Injection
• Hlášení závislostí přímo při volání setter funkce.
• Lze dobře uplatnit pro inicializaci objektu mimo konstruktor třídy.
@Inject
public void setHelper(Helper helper) {
this.helper = helper;
}
Property injection
• Je velmi podobné constructor injection. K hlášení závislostí se používá
anotací přímo u deklarace proměnné.Výhodou je stručnost.
• Nutností je DI container, který bude umět s touto anotací pracovat a
nastavit odkazující proměnnou na již inicializovaný objekt.
public class ClientsController {
// Property injection
@Inject
private final UserDAO userDAO;
public ClientsController() {
}
}
public class ClientsController {
private UserDAO userDAO;
public ClientsController(UserDAO userDao) {
this.userDao = userDao;
// constructor injection
}
}
Interface Injection
• Nehlásíme závislost na konkrétní třídu, hlásíme závislost pouze na interface,
• jedná se o velmi silný nástroj – zvyšuje úroveň abstrakce v kódu.
public void setHelper(Employee helper) {
this.helper = helper;
}
public Company(Employee worker, Employee slacker) {
this.worker = worker;
this.slacker = slacker;
}
interface Employee {
public void work();
public void pretendWorking();
}
Spaghetti code, je v souladu s DI?
public class Company{
protected Worker worker;
protected Slacker slacker;
public Companz() {
this.worker = new Worker();
this.slacker = new Slacker();
}
public void open(){
this.worker.work();
this.slacker.pretendWorking();
customer = new Customer();
System.out.println(“<h1> Welcome! How can I help you?</h1>”);
this.worker.serverCustomer();
System.out.println(“<p>” + customer.wish + ”</p>”);
}
}
Senior programmer John - “Garry, you are fired!”
Problémy - Constructor hell
public function Controller(IHttpRequest request, IHttpResponse response,
User user, UserModel userModel, Language language,
DataSource dataSource, ....) {
// rest of the code
}
• Přílišné množství parametrů již přímo v konstruktoru třídy,
• odhaluje tak nesprávné rozvržení tříd,
• řešit lze za pomocí refaktoringu tříd.
Jesus Christ, so many dependencies!!
Problémy - DI vs. Lazy loading
• Lazy loading – návrhový vzor, kdy se vytváření instance objektu se odkladá
do doby než je opravdu potřeba,
• z důvodu optimilizace je přínosné tento návrhový vzor používat,
• naopak DI požaduje pro své třídy již vytvořené instance (závislosti).
Junior Garry – No way, they troll me all the time!
Service Locator – zlé dvojče DI
• Jedná se také o návrhový vzor, nicméně jde proti smyslu DI (antipattern)
• Třída se totiž nehlásí k jednotlivým závislostem.Všechny závislosti získává
skrze globální objekt (service locator).
• Nicméně lze přejít pak jednoduše k DI.
public class ClientsController {
private final UserDAO userDAO;
public ClientsController(ServiceContainer $services) {
this.userDao = (UserDao)$services->getService("UserDAO");
}
}
Hell yeah, your classes are liars again!
DI Container (DIC)
• Příliš mnoho závislostí (závislé třídy) => potřebujeme je spravovat, k těmto
účelům slouží právě DI kontejner,
• DI kontejner dává již připravené instance tříd vždy jeho žadateli,
• pravidlem je, že o existencí DI kontejneru by mělo vědet minimální množství
kódu,
• příklad: Google Guice Cointainer (není jediný).
Pohled na aplikaci jako stavbu tříd
Application
Database
Connection DaoServices
Resources
DataSource
GUI
Other
Clasess…
Na co teda DI container?
• Pokud svou aplikaci popíšete jako strom závislostí. Není nic jednoduššího
než si ji nechat sestavit právě DI Containerem.
• Ten drží konfiguraci tříd celé aplikace, nahrazuje pokoutné Environment
objekty.
Hey container, gimme the Application!
Yess, sir!
Konfigurace DI containeru
• Slouží k správné inicializaci prostředí aplikace, resp. jejich tříd.To, jakým
způsobem se konfigurace provádí, záleží na konkrétní implementaci
containeru (anotace, třídní objekt, xml soubor...)
import com.google.inject.Binder;
import com.google.inject.Module;
import com.google.inject.Scopes;
public class DependencyConfig implements Module {
@Override
public void configure(Binder binder) {
binder.bind(Storage.class).to(DatabaseStorage.class).in(Scopes.SINGLETON);
}
//example of Google Guice Container configuration
}
DIC a persistence objektů
• DI kontejnery nám umožňují řídit životnost objektů => obrovský potenciál DI
• Problém návrhového vzoru Singleton:
• Nikdy nemůžeme dopředu vědět zda třída bude opravdu Singletonem či nikoli.
• Není přímou zodpovědností třídy se starat zda bude jedináčkem či nikoli.
• Za pomocí DI kontejneru se tyto problémy dají vyřešit.
DIC – není Singleton jako Singleton
@Singleton
public class Company {
protected Worker worker;
protected Slacker slacker;
public Firma() {
this.worker = new Worker();
this.slacker = new Slacker();
}
}
public class Company {
private static Company instance = null;
private Company() {}
public static Company getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
Kontrolní otázky
1. V čem je podstata návrhového vzoru Dependency injection (DI)?
2. Jaké výhody přináší DI?
3. Jaké máme typy DI?
4. Jaké problémy mohou nastat při aplikování vzoru DI?
5. K čemu slouží Dependency Injection Container?
6. Dalo vám to něco?
Questions?

More Related Content

Similar to Dependency injection

Závislosti, injekce a vůbec
Závislosti, injekce a vůbecZávislosti, injekce a vůbec
Závislosti, injekce a vůbecDavid Grudl
 
Úvod do analýzy - 2 část
Úvod do analýzy -  2 částÚvod do analýzy -  2 část
Úvod do analýzy - 2 částMartin Paták
 
Solid principy v oop návrhu
Solid principy v oop návrhuSolid principy v oop návrhu
Solid principy v oop návrhuProfinit
 
Entity Framework v enterprise aplikacích
Entity Framework v enterprise aplikacíchEntity Framework v enterprise aplikacích
Entity Framework v enterprise aplikacíchProfinit
 
Programování pro Android - úvod, FI MUNI, 2013
Programování pro Android - úvod, FI MUNI, 2013Programování pro Android - úvod, FI MUNI, 2013
Programování pro Android - úvod, FI MUNI, 2013Tomáš Kypta
 
Dark Side of iOS [mDevCamp 2013]
Dark Side of iOS [mDevCamp 2013]Dark Side of iOS [mDevCamp 2013]
Dark Side of iOS [mDevCamp 2013]Kuba Břečka
 
KeePass: Základy, pokročilé využití a KeePass Enterprise (čtvrtek, 14.4.2022)
KeePass: Základy, pokročilé využití a KeePass Enterprise (čtvrtek, 14.4.2022)KeePass: Základy, pokročilé využití a KeePass Enterprise (čtvrtek, 14.4.2022)
KeePass: Základy, pokročilé využití a KeePass Enterprise (čtvrtek, 14.4.2022)Michal ZOBEC
 
Enterprise 3.0: Podnik chycený v sociální siti vyznamů
Enterprise 3.0: Podnik chycený v sociální siti vyznamůEnterprise 3.0: Podnik chycený v sociální siti vyznamů
Enterprise 3.0: Podnik chycený v sociální siti vyznamůJosef Holy
 
Doctrine: co dělat, když entity nestačí
Doctrine: co dělat, když entity nestačíDoctrine: co dělat, když entity nestačí
Doctrine: co dělat, když entity nestačíFilip Procházka
 
Nette framework - How to compile an extensible di container
Nette framework - How to compile an extensible di containerNette framework - How to compile an extensible di container
Nette framework - How to compile an extensible di containerFilip Procházka
 
UX monday - uživatelské testování
UX monday - uživatelské testováníUX monday - uživatelské testování
UX monday - uživatelské testováníDesingdev
 
4308 uzivatele site_os_net_ware_2
4308 uzivatele site_os_net_ware_24308 uzivatele site_os_net_ware_2
4308 uzivatele site_os_net_ware_2pisaceku
 
Milan Oulehla: Bezpečnost mobilních aplikací na Androidu
Milan Oulehla: Bezpečnost mobilních aplikací na AndroiduMilan Oulehla: Bezpečnost mobilních aplikací na Androidu
Milan Oulehla: Bezpečnost mobilních aplikací na Androidumdevtalk
 
Nástroje pro vizualizaci a analýzu dat (nejen) ve fyzikální praktiku
Nástroje pro vizualizaci a analýzu dat (nejen) ve fyzikální praktiku Nástroje pro vizualizaci a analýzu dat (nejen) ve fyzikální praktiku
Nástroje pro vizualizaci a analýzu dat (nejen) ve fyzikální praktiku Michal Černý
 
ITSM - Jira Service Desk a spřátelené aplikace z rodiny Atlassian
ITSM - Jira Service Desk a spřátelené aplikace z rodiny AtlassianITSM - Jira Service Desk a spřátelené aplikace z rodiny Atlassian
ITSM - Jira Service Desk a spřátelené aplikace z rodiny AtlassianOnlio
 
Krev net a_slzy
Krev net a_slzyKrev net a_slzy
Krev net a_slzyEtnetera
 
Pořídit hotové řešení nebo si nechat vyrobit vlastní?
Pořídit hotové řešení nebo si nechat vyrobit vlastní? Pořídit hotové řešení nebo si nechat vyrobit vlastní?
Pořídit hotové řešení nebo si nechat vyrobit vlastní? Ondrej Kucera
 
Deployment PHP aplikací | WebExpo 2011
Deployment PHP aplikací | WebExpo 2011Deployment PHP aplikací | WebExpo 2011
Deployment PHP aplikací | WebExpo 2011Jan Mittner
 
Práce v Atlassian cloudu
Práce v Atlassian clouduPráce v Atlassian cloudu
Práce v Atlassian clouduOnlio
 

Similar to Dependency injection (20)

Závislosti, injekce a vůbec
Závislosti, injekce a vůbecZávislosti, injekce a vůbec
Závislosti, injekce a vůbec
 
Úvod do analýzy - 2 část
Úvod do analýzy -  2 částÚvod do analýzy -  2 část
Úvod do analýzy - 2 část
 
Solid principy v oop návrhu
Solid principy v oop návrhuSolid principy v oop návrhu
Solid principy v oop návrhu
 
Entity Framework v enterprise aplikacích
Entity Framework v enterprise aplikacíchEntity Framework v enterprise aplikacích
Entity Framework v enterprise aplikacích
 
Programování pro Android - úvod, FI MUNI, 2013
Programování pro Android - úvod, FI MUNI, 2013Programování pro Android - úvod, FI MUNI, 2013
Programování pro Android - úvod, FI MUNI, 2013
 
Dark Side of iOS [mDevCamp 2013]
Dark Side of iOS [mDevCamp 2013]Dark Side of iOS [mDevCamp 2013]
Dark Side of iOS [mDevCamp 2013]
 
KeePass: Základy, pokročilé využití a KeePass Enterprise (čtvrtek, 14.4.2022)
KeePass: Základy, pokročilé využití a KeePass Enterprise (čtvrtek, 14.4.2022)KeePass: Základy, pokročilé využití a KeePass Enterprise (čtvrtek, 14.4.2022)
KeePass: Základy, pokročilé využití a KeePass Enterprise (čtvrtek, 14.4.2022)
 
Enterprise 3.0: Podnik chycený v sociální siti vyznamů
Enterprise 3.0: Podnik chycený v sociální siti vyznamůEnterprise 3.0: Podnik chycený v sociální siti vyznamů
Enterprise 3.0: Podnik chycený v sociální siti vyznamů
 
Doctrine: co dělat, když entity nestačí
Doctrine: co dělat, když entity nestačíDoctrine: co dělat, když entity nestačí
Doctrine: co dělat, když entity nestačí
 
Nette framework - How to compile an extensible di container
Nette framework - How to compile an extensible di containerNette framework - How to compile an extensible di container
Nette framework - How to compile an extensible di container
 
UX monday - uživatelské testování
UX monday - uživatelské testováníUX monday - uživatelské testování
UX monday - uživatelské testování
 
4308 uzivatele site_os_net_ware_2
4308 uzivatele site_os_net_ware_24308 uzivatele site_os_net_ware_2
4308 uzivatele site_os_net_ware_2
 
Milan Oulehla: Bezpečnost mobilních aplikací na Androidu
Milan Oulehla: Bezpečnost mobilních aplikací na AndroiduMilan Oulehla: Bezpečnost mobilních aplikací na Androidu
Milan Oulehla: Bezpečnost mobilních aplikací na Androidu
 
Nástroje pro vizualizaci a analýzu dat (nejen) ve fyzikální praktiku
Nástroje pro vizualizaci a analýzu dat (nejen) ve fyzikální praktiku Nástroje pro vizualizaci a analýzu dat (nejen) ve fyzikální praktiku
Nástroje pro vizualizaci a analýzu dat (nejen) ve fyzikální praktiku
 
ITSM - Jira Service Desk a spřátelené aplikace z rodiny Atlassian
ITSM - Jira Service Desk a spřátelené aplikace z rodiny AtlassianITSM - Jira Service Desk a spřátelené aplikace z rodiny Atlassian
ITSM - Jira Service Desk a spřátelené aplikace z rodiny Atlassian
 
Krev net a_slzy
Krev net a_slzyKrev net a_slzy
Krev net a_slzy
 
Pořídit hotové řešení nebo si nechat vyrobit vlastní?
Pořídit hotové řešení nebo si nechat vyrobit vlastní? Pořídit hotové řešení nebo si nechat vyrobit vlastní?
Pořídit hotové řešení nebo si nechat vyrobit vlastní?
 
Deployment PHP aplikací | WebExpo 2011
Deployment PHP aplikací | WebExpo 2011Deployment PHP aplikací | WebExpo 2011
Deployment PHP aplikací | WebExpo 2011
 
7 omylu v IT bezpečnosti
7 omylu v IT bezpečnosti7 omylu v IT bezpečnosti
7 omylu v IT bezpečnosti
 
Práce v Atlassian cloudu
Práce v Atlassian clouduPráce v Atlassian cloudu
Práce v Atlassian cloudu
 

Dependency injection

  • 1. Dependency injection Jiří Matula Neruším? Ráda bych vám pomohla sVaší závislostí na ostatních!
  • 2. Obsah 1. Co je to Dependency Injection (DI) 2. Motivace proč se zabývat DI 3. Typy DI 4. Problémy 5. DI Container 6. Závěr - testík
  • 3. Dependency injection (DI) • Návrhový vzor z rodiny IoC (Inversion of Control). • Problém : Skryté závislosti třídy (skryté = těžce kontrolovatelné). • Řešení: zřejmé předávání závislostí = odebrání třídám zodpovědnosti za získávání objektů, které potřebují ke své činnosti. • Uplatňuje se princip popisu závislostí pomocíAPI třídy. • Lze si jej představit pod mottem - “Když něco chceš, tak si o to řekni!”
  • 5. Proč se obtěžovat s DI? Zvolnění vazeb mezi objekty, jednodušší testovatelnost, nutí programátora řešit vazby mezi objekty = čistější přehlednější kód, pomáhá dodržovat správný objektový návrh, pravdivé API tříd. Junior programmerGarry – “Whatever, I love my spaghetti !”
  • 6. Constructor Injection • Hlášení závislosti přímo v konstruktoru třídy. • Problémy: • Lazy loading (vytváření objektů v momentě, kdy jsou opravdu potřeba), • Constructor hell (příliš mnoho závislostí v konstruktoru třídy). public void Company() { this.worker = new Worker(); this.slacker = new Slacker(); } // constructor injection public void Company(Worker worker, Slacker slacker) { this.worker = worker; this.slacker = slacker; }
  • 7. Setter Injection • Hlášení závislostí přímo při volání setter funkce. • Lze dobře uplatnit pro inicializaci objektu mimo konstruktor třídy. @Inject public void setHelper(Helper helper) { this.helper = helper; }
  • 8. Property injection • Je velmi podobné constructor injection. K hlášení závislostí se používá anotací přímo u deklarace proměnné.Výhodou je stručnost. • Nutností je DI container, který bude umět s touto anotací pracovat a nastavit odkazující proměnnou na již inicializovaný objekt. public class ClientsController { // Property injection @Inject private final UserDAO userDAO; public ClientsController() { } } public class ClientsController { private UserDAO userDAO; public ClientsController(UserDAO userDao) { this.userDao = userDao; // constructor injection } }
  • 9. Interface Injection • Nehlásíme závislost na konkrétní třídu, hlásíme závislost pouze na interface, • jedná se o velmi silný nástroj – zvyšuje úroveň abstrakce v kódu. public void setHelper(Employee helper) { this.helper = helper; } public Company(Employee worker, Employee slacker) { this.worker = worker; this.slacker = slacker; } interface Employee { public void work(); public void pretendWorking(); }
  • 10. Spaghetti code, je v souladu s DI? public class Company{ protected Worker worker; protected Slacker slacker; public Companz() { this.worker = new Worker(); this.slacker = new Slacker(); } public void open(){ this.worker.work(); this.slacker.pretendWorking(); customer = new Customer(); System.out.println(“<h1> Welcome! How can I help you?</h1>”); this.worker.serverCustomer(); System.out.println(“<p>” + customer.wish + ”</p>”); } } Senior programmer John - “Garry, you are fired!”
  • 11. Problémy - Constructor hell public function Controller(IHttpRequest request, IHttpResponse response, User user, UserModel userModel, Language language, DataSource dataSource, ....) { // rest of the code } • Přílišné množství parametrů již přímo v konstruktoru třídy, • odhaluje tak nesprávné rozvržení tříd, • řešit lze za pomocí refaktoringu tříd. Jesus Christ, so many dependencies!!
  • 12. Problémy - DI vs. Lazy loading • Lazy loading – návrhový vzor, kdy se vytváření instance objektu se odkladá do doby než je opravdu potřeba, • z důvodu optimilizace je přínosné tento návrhový vzor používat, • naopak DI požaduje pro své třídy již vytvořené instance (závislosti). Junior Garry – No way, they troll me all the time!
  • 13. Service Locator – zlé dvojče DI • Jedná se také o návrhový vzor, nicméně jde proti smyslu DI (antipattern) • Třída se totiž nehlásí k jednotlivým závislostem.Všechny závislosti získává skrze globální objekt (service locator). • Nicméně lze přejít pak jednoduše k DI. public class ClientsController { private final UserDAO userDAO; public ClientsController(ServiceContainer $services) { this.userDao = (UserDao)$services->getService("UserDAO"); } } Hell yeah, your classes are liars again!
  • 14. DI Container (DIC) • Příliš mnoho závislostí (závislé třídy) => potřebujeme je spravovat, k těmto účelům slouží právě DI kontejner, • DI kontejner dává již připravené instance tříd vždy jeho žadateli, • pravidlem je, že o existencí DI kontejneru by mělo vědet minimální množství kódu, • příklad: Google Guice Cointainer (není jediný).
  • 15. Pohled na aplikaci jako stavbu tříd Application Database Connection DaoServices Resources DataSource GUI Other Clasess…
  • 16. Na co teda DI container? • Pokud svou aplikaci popíšete jako strom závislostí. Není nic jednoduššího než si ji nechat sestavit právě DI Containerem. • Ten drží konfiguraci tříd celé aplikace, nahrazuje pokoutné Environment objekty. Hey container, gimme the Application! Yess, sir!
  • 17. Konfigurace DI containeru • Slouží k správné inicializaci prostředí aplikace, resp. jejich tříd.To, jakým způsobem se konfigurace provádí, záleží na konkrétní implementaci containeru (anotace, třídní objekt, xml soubor...) import com.google.inject.Binder; import com.google.inject.Module; import com.google.inject.Scopes; public class DependencyConfig implements Module { @Override public void configure(Binder binder) { binder.bind(Storage.class).to(DatabaseStorage.class).in(Scopes.SINGLETON); } //example of Google Guice Container configuration }
  • 18. DIC a persistence objektů • DI kontejnery nám umožňují řídit životnost objektů => obrovský potenciál DI • Problém návrhového vzoru Singleton: • Nikdy nemůžeme dopředu vědět zda třída bude opravdu Singletonem či nikoli. • Není přímou zodpovědností třídy se starat zda bude jedináčkem či nikoli. • Za pomocí DI kontejneru se tyto problémy dají vyřešit.
  • 19. DIC – není Singleton jako Singleton @Singleton public class Company { protected Worker worker; protected Slacker slacker; public Firma() { this.worker = new Worker(); this.slacker = new Slacker(); } } public class Company { private static Company instance = null; private Company() {} public static Company getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
  • 20. Kontrolní otázky 1. V čem je podstata návrhového vzoru Dependency injection (DI)? 2. Jaké výhody přináší DI? 3. Jaké máme typy DI? 4. Jaké problémy mohou nastat při aplikování vzoru DI? 5. K čemu slouží Dependency Injection Container? 6. Dalo vám to něco?