W065_V46_IoC_III_05_(41)2012.ppt
- Количество слайдов: 41
Патерн (принцип) IOC&DI 2008 -2012 Io. C
Spring Framework Io. C 2
Spring Framework Io. C 3
Spring Framework Io. C 4
Io. C Container – ядро Spring Framework Патерн (принцип) IOC & DI — Inversion of Control (Io. C) and Dependency Injection (DI) • Io. C контейнери • Патерн DI Io. C 5
До залежності класів. . . Динаміка. . . Додається до коду, згенерованого за діаграмою класів public class Class 1 { public Class 2 the. Class 2 = new Class 2() ; public Class 3 the. Class 3 = new Class 3() ; Створення public Class 1() об'єктів { } } Io. C 6
Патерн IOC&DI на прикладі Io. C 7
Патерн IOC&DI на прикладі (1/4) package com. kvf. demo; public interface IGreeting { void print. Greeting(); } package com. kvf. demo; import com. kvf. demo. IGreeting; public class Hi implements IGreeting{ Залежність public void print. Greeting() { System. out. println("Hi!"); “Близькі” класи } package com. kvf. demo; } class Class 1 - ? import com. kvf. demo. IGreeting; public class Hello implements IGreeting{ Задача: передбачити для класу public void print. Greeting() { Class 1 (у якому використовується вітання print. Greeting) можливість System. out. println("Hello!"); заміни об'єкту типу Hi на об'єкт типу } Hello, забезпечуючи при тому Io. C 8 незмінність коду Class 1. } ?
Патерн IOC&DI на прикладі (2/4) Class 1 - звична версія. (Не підходить!) private IGreeting greeting = new Hello (); package com. kvf. demo; Заміна коду!? import com. kvf. demo. *; public class Class 1 { private IGreeting greeting = new Hi(); public void foo() { greeting. print. Greeting(); } } Традиційний прийом із використанням для об'єктів привітання методу print. Greeting() Io. C 9
Патерн IOC&DI на прикладі (3/4) Незмінний java-код Class 1 a ! package com. kvf. demo; import com. kvf. demo. IGreeting; public class Class 1 a { Управління по створенню об'єктів типів Hi чи private IGreeting greeting; Hello “передано” (Inversion of Control ) класу Super (Runner). Запропонований код public void set. Greeting( забезпечує ін'єкцію залежності (Dependency IGreeting greeting) { Injection ) Class 1 a від класу Hi чи від класу this. greeting = greeting; Hello відповідно. } package com. kvf. demo; public void foo() { import com. kvf. demo. *; greeting. print. Greeting(); public class Super { // Runner } public static void main(String[] args) { } Class 1 a c = new Class 1 a(); c. set. Greeting( new Hi () ); c. foo(); } Io. C } Dependency Injection Модифікація при переході від Hi до Hello new Hello () 10
Патерн IOC&DI на прикладі (4/4) Spring Core (Io. C container) виконує роль, подібну. Io. C Super, забезпечуючи створення до 11 об'єктів та їх ін'єкцію
Io. C Container та патерн IOC&DI Патерн (принцип) Inversion of Control (Io. C) and Dependency Injection (DI) Часто один з подібної пари класів є тестовим Засоби тестування! Io. C 12
Spring: Io. C + декларативний стиль. Конфігураційний файл (контексту) beans_ctx. xml Компонентна “(дротяна) проводка” (Component Wiring) Eclipse +Spring Plugin (ПКМ | Open Graph) Дротяна модель Spring Core бере на себе відповідальність за створення об'єктів (бінів) та їх “зв'язування” Io. C на основі ін'єкції 13
Eclipse (проект greeting). Open Graph Io. C 14
Spring-проект. Перероблений основний клас Super. java package com. kvf. demo; import org. springframework. context. Application. Context; import org. springframework. context. support. Class. Path. Xml. Application. Context; public class Super { public static void main(String[] args) { Application. Context ctx = new Class. Path. Xml. Application. Context("beans_ctx. xml"); Class 1 a c = (Class 1 a)ctx. get. Bean("class 1 a"); System. out. println("Greeting: "); c. foo(); } } Io. C 16
Виконання проекту (Run as -> Java Application ) Io. C 17
Виконання проекту при переході від класу Hi до класу Hello • Єдине необхідне виправлення! • Ніяка перекомпіляція не потрібна Io. C 18
Setter Injection or Constructor Injection package com. kvf. demo; Файл Class 2. java public class Class 2 { private IGreeting greeting; public void set. Greeting(IGreeting greeting) { Можна this. greeting = greeting; вилучити } public Class 2 (IGreeting greeting) { Конструктор із this. greeting = greeting; параметром } public void foo() { greeting. print. Greeting(); } } public class Super 2 { public static void main(String[] args) { Application. Context ctx = new Class. Path. Xml. Application. Context("beans_ctx 2. xml"); Class 2 c = (Class 2)ctx. get. Bean("class 2"); System. out. println("Greeting: "); c. foo(); Файл Super 2. java } Io. C 19 (фрагмент)
Constructor Injection. Конфігураційний файл (контексту) beans_ctx 2. xml
Виконання проекту з Constructor Injection Io. C 21
Spring-проект dekor (для патерна «Декоратор» ) Io. C 22
Пригадаємо… Decorator. Приклад public class Client { public static void Main ( string[] args ) { Створення об'єктів Concrete. Component c = new Concrete. Component(); d 2 : CDec. B component= d 1 : CDec. A component= c : CComponent // Link decorators d 1. Set. Component( c ); d 2. Set. Component( d 1 ); Ін'єкції Додаткова гнучкість пов'язана з можливістю задавати композицію об'єктів під час виконання програми Io. C Concrete. Decorator. A d 1 = new Concrete. Decorator. A(); Concrete. Decorator. B d 2 = new Concrete. Decorator. B(); // Link decorators d 1. Set. Component( c ); d 2. Set. Component( d 1 ); d 2. Operation(); } } 23
Версії Java-класів (зі Spring-проекту) public interface IComponent { void operation(); } public class Concrete. Component implements IComponent{ public void operation(){ System. out. println( "Concrete. Component!"); } } public class Decorator implements IComponent{ private IComponent component; public void set. Component(IComponent component) { this. component = component; } public void operation(){ component. operation(); } public class Decorator. A extends Decorator { } public void operation(){ } } super. operation(); System. out. println("Decorator. A"); Io. C Класи Decorator. B, Decorator. C мають аналогічний вигляд 24
Eclipse. Spring-проект dekor з трьома конкретними декораторами. Загальний вигляд проекту Закладка з головним Java-класом проекту Io. C 25
Конфігураційний файл (контексту) beans_ctx. xml та відповідна дротяна модель Spring Декларативний стиль! xml version="1. 0" encoding="UTF-8"? >
Головний Java-клас проекту import org. springframework. context. Application. Context; import org. springframework. context. support. Class. Path. Xml. Application. Context; public class Project { public static void main(String[] args) { Application. Context ctx = new Class. Path. Xml. Application. Context( "beans_ctx. xml"); IComponent component; component = (IComponent)ctx. get. Bean("root. Component"); component. operation(); } } Io. C 27
Виконання проекту public class Decorator implements IComponent{ private IComponent component; public void set. Component(IComponent component) { this. component = component; } public void operation(){ component. operation(); } } public class Decorator. A extends Decorator { public void operation(){ super. operation(); System. out. println("Decorator. A"); } } Задіяна така єдина стратегія використання декораторів: спочатку декорування здійснює внутрішній (ін'єктований) об'єкт, а потім зовнішній. Io. C 28
Композиції об'єктів та виконання проекту Важливо! Варіанти композиції об'єктів задаються виключно конфігураційним файлом (як наслідок, при зміні композицій проект не потребує перекомпіляції). xml version="1. 0" encoding="UTF-8"? >
Приклад. Spring-проект для патерна «Стратегія» Io. C 30
Пригадаємо… Strategy (dofactory. com) Визначає сімейство алгоритмів, в якому інкапсулюється кожен з них і забезпечується їх взаємозаміна. Патерн "Стратегія" дозволяє змінювати алгоритми сімейства незалежно від клієнтів, які використовують ці алгоритми. Io. C 31
Пригадаємо… Strategy (dofactory. com) class Main. App { static void Main() { Context context; context = new Context( new Concrete. Strategy. A()); context. Context. Interface(); context = new Context( new Concrete. Strategy. B()); context. Context. Interface(); } } /// The 'Strategy' abstract class Strategy { public abstract void Algorithm. Interface(); } class Concrete. Strategy. A : Strategy { public override void Algorithm. Interface() { Console. Write. Line( "Called. Concrete. Strategy. A. ”+ ”Algorithm. Interface()"); } } class Concrete. Strategy. B : Strategy { public override void Algorithm. Interface() { Console. Write. Line( "Called. Concrete. Strategy. B. ”+ ”Algorithm. Interface()"); } } class Context { private Strategy _strategy; // Constructor public Context(Strategy strategy) { this. _strategy = strategy; } public void Context. Interface() { _strategy. Algorithm. Interface(); } } Io. C 32
Патерн Strategy. Версії Java-класів public interface IStrategy { void Algorithm. Interface(); } package com. kvf. ttp; import com. kvf. ttp. IStrategy; public class Concrete. Strategy. A implements IStrategy{ public void Algorithm. Interface() { System. out. println("Strategy. A. Algorithm. Interface"); } public class Context { } private IStrategy _strategy; Конструктор з параметром } public Context(IStrategy strategy){ this. _strategy = strategy; } public void Context. Interface(){ _strategy. Algorithm. Interface(); Io. C } 33
Приклад використання Io. C/DI на платформі. NET Io. C 35
Використання DI у проектах ASP. NET MVC 3 (1/2) public class Home. Controller : Controller { private IText. Service service; public Home. Controller(IText. Service s) Конструктор { public interface IText. Service service = s; { } string Get. Text(string text); } public Action. Result Index() { View. Bag. Message = service. Get. Text (name); return View(); } public class First. Text. Service : IText. Service. . . { public string Get. Text(string text) { return String. Format( "{0}, wellcome to ASP. NET MVC!", text); } Io. C 36 }
Використання DI у проектах ASP. NET MVC 3 (2/2) protected void Application_Start() { var kernel = new Standard. Kernel(); Second. Text. Service При потребі скористатись kernel. Bind
Використання Io. C на платформі. NET Деякі відомі IOC контейнери на платформі. NET : • Windsor; • Structure. Map; • Spring. NET; • Object. Builder. Io. C 38
Spring Io. C. Ще один приклад Io. C 39