Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

Dependency injection Jiří Matula Neruším? Ráda bych vám pomohla

Podobné prezentace


Prezentace na téma: "Dependency injection Jiří Matula Neruším? Ráda bych vám pomohla"— Transkript prezentace:

1 Dependency injection Jiří Matula Neruším? Ráda bych vám pomohla
s Vaší závislostí na ostatních! Jiří Matula

2 Obsah Co je to Dependency Injection (DI) Motivace proč se zabývat DI
Typy DI Problémy DI Container 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!”

4 Vizualizace závislostí
(Cheese) (Vegetable) (Meat) (Friends) (Water) (Alcohol) (Satisfied person)

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 programmer Garry – “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. interface Employee { public void work(); public void pretendWorking(); } public Company(Employee worker, Employee slacker) { this.worker = worker; this.slacker = slacker; } public void setHelper(Employee helper) { this.helper = helper; }

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
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. public function Controller(IHttpRequest request, IHttpResponse response, User user, UserModel userModel, Language language, DataSource dataSource, ....) { // rest of the code } 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. Yess, sir! Hey container, gimme the Application!

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
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 V čem je podstata návrhového vzoru Dependency injection (DI)? Jaké výhody přináší DI? Jaké máme typy DI? Jaké problémy mohou nastat při aplikování vzoru DI? K čemu slouží Dependency Injection Container? Dalo vám to něco?

21 Questions?


Stáhnout ppt "Dependency injection Jiří Matula Neruším? Ráda bych vám pomohla"

Podobné prezentace


Reklamy Google