W bardzo popularnych ostatnio dyskusjach na temat frameworków, które można także wykorzystać programując w ActionScript 3, bardzo często padają określenia “wstrzykiwanie zależności” (Dependency Injection – DI) oraz “odwrócenie sterowania” (Inversion of Control – IoC). Terminy te wywodzą się z obiektowego świata Javy i zostały zaadoptowane przez programistów innych języków, w tym programistów ActionScript 3. Większość współcześnie wykorzystywanych frameworków (np.: Robotlegs, Swiz, Parsley, Spring Actionscript) implementuje DI oraz IoC.
Czym jest Dependency Injection (DI)?
Praktycznie w każdej aplikacji korzystamy z DI. Niezależnie od tego czy korzystamy z frameworków, czy też nie. DI to po prostu konfigurowanie obiektu, jego właściwości (czyli zależności od innych obiektów) “z zewnątrz”. Możemy wyróżnić trzy główne, podstawowe metody wstrzykiwania zależności poprzez:
- parametr metody konstruktora obiektu (constructor injection),
- przypisywanie nowej wartości za pomocą metody publicznej (setter injection),
- przypisywanie nowej wartości do właściwości obiektu (property injection).
Zobaczmy jak to wygląda na kilku przykładach.
Constructor Injection
Załóżmy, że mamy klasę jak w przykładzie poniżej:
package
{
public class MyTestObject
{
private var _name:String;
public function MyTestObject(name:String)
{
this._name = name;
}
}
}
Obiekt tej klasy o nazwie “Obiekt nr 1″ tworzymy w następujący sposób:
var myTestObject:MyTestObject = new MyTestObject("Obiekt nr 1");
W tym przypadku wstrzyknęliśmy zależność podając w parametrze konstruktora wartość “Obiekt nr 1″.
Czy poniższy przykład jest wstrzykiwaniem zależności?
package
{
public class MyTestObject2
{
private var _name:String;
public function MyTestObject2()
{
this._name = "Obiekt nr 1";
}
}
}
// Tworzymy obiekt
var myTestObject2:MyTestObject2 = new MyTestObject2();
Oczywiście, że nie. Konstruktor klasy MyTestObject2 nie przyjmuje żadnych parametrów, a więc obiekt myTestObject2 nie jest konfigurowany z zewnątrz.
Setter Injection
W kolejnym przykładzie możemy konfigurować obiekt klasy MyTestObject3 za pomocą metody publicznej. Wstrzykujemy w ten sposób zależność dla tego obiektu. Można powiedzieć, że obiekt zależy od tego, jaka wartość zostanie wstrzyknięta.
package
{
public class MyTestObject3
{
private var _name:String;
public function MyTestObject3()
{
}
public function setName(value:String):void
{
this._name = value;
}
}
}
Z wstrzykiwania zależności dla klasy powyżej korzystamy w następujący sposób:
var myTestObject3:MyTestObject3 = new MyTestObject3()
myTestObject3.setName("Obiekt nr 1");
Property Injection
Ostatni przykład obrazuje wstrzykiwanie zależności poprzez przypisywanie wartości do właściwości obiektu. W języku ActionScript 3 możemy to zrobić na dwa sposoby. Albo tworząc właściwość z modyfikatorem dostępu “public” lub za pomocą metody “set”, tak jak na przykładzie poniżej.
package
{
public class MyTestObject4
{
private var _name:String;
public var name2:String;
public function MyTestObject4()
{
}
// Setter
public function set name(value:String):void
{
this._name = value;
}
}
}
Z settera i z przypisywania nowej wartości do właściwości obiektu korzystamy tak samo:
var myTestObject4:MyTestObject4 = new MyTestObject4() myTestObject4.name = "Obiekt nr 1"; myTestObject4.name2 = "Obiekt nr 1";
Dlaczego warto korzystać z dependency injection?
Dzięki stosowaniu wstrzykiwania zależności możemy wykorzystywać obiekty w różnych sytuacjach, wielokrotnie zmieniając ich stan oraz wykorzystując ich funkcjonalność w oparciu o inne stany. DI ułatwia też tworzenie obiektów powiązanych luźno ze sobą, co oprócz lepszej architektury aplikacji, ponownego wykorzystania kodu pozwala na testowanie odizolowanych klas za pomocą testów jednostkowych (unit testing). W trakcie wykonywania takich testów, np. zamiast produkcyjnej, dostępnej z odległego serwera bazy danych, możemy podpiąć jej lokalną, specjalnie spreparowaną wersję (mock, stub) służącą do testowania obiektu danej klasy.
Czym jest Inversion of Control (IoC)?
Korzystając z frameworków korzystamy z odwrócenia sterowania. Na początku konfigurujemy (przystosowujemy) framework do pracy z naszą aplikacją, a następnie pozwalamy frameworkowi zrobić resztę. To framework przejmuje kontrolę nad aplikacją, nad przepływem zdarzeń i danych. To logika zaszyta wewnątrz frameworka napędza nasz program. Przynajmniej część kontroli nad aplikacją zostaje zabrana poszczególnym komponentom aplikacji i przekazana frameworkowi – jest to właśnie odwrócenie sterowania (Inversion of Control – IoC). Programista nie definiuje szkieletu funkcjonalnego aplikacji (architekturę zwykle w mniejszym lub większym stopniu zapewnia framework). Framework jest głównym modułem sterującym aplikacji odpowiedzialnym za koordynowanie i zarządzanie jej działaniem.
Odwrócenie sterowania możemy osiągnąć na kilka sposobów. W frameworkach takich jak PureMVC oraz Cairngorm, IoC zapewniamy poprzez rozszerzanie klas frameworka. Dzięki temu uzyskujemy dostęp do jego funkcjonalności. W frameworkach takich jak Parsley lub Swiz powiązanie elementów aplikacji z frameworkiem następuje za pomocą rozumianego przez framework meta opisu.
Kontenery IoC
Kontenery odwrócenia sterowania (Inversion of Control Containers) pozwalają na tworzenie i zarządzanie obiektami wykorzystywanymi w aplikacji. Kontenerami IoC są najczęściej frameworki aplikacji, takie jak Parsley czy Swiz. Więcej na temat wykorzystywania frameworków (za i przeciw) można znaleźć w Frameworki architektoniczne (dla Flexa) – moda, czy konieczność?
One Comment
Przykład IoC poprzez zastosowanie mechanizmu injekcji ( metatagi ) można zobaczyć również w Fabrication (http://code.google.com/p/fabrication/)
One Trackback
[...] Polish Adobe Flex User Group Polska grupa użytkowników Adobe Flex Skip to content StartO nasDołącz do nasRecenzjeSponsorzyKontakt « Dependency Injection (DI) oraz Inversion of Control (IoC) w ActionScript 3 [...]