3. Agenda
1. Interfejsy – wprowadzenie
2. Interfejsy w języku C#
3. Kompozycja czy dziedziczenie?
4. Inversion of Control
1. Dependency Injection
2. DEMO – AutoFac
5. Testy jednostkowe
1. Biblioteka Moq
6. Podsumowanie
4. Interfejsy - wprowadzenie
W programowaniu obiektowym interfejs jest
definicją abstrakcyjnego typu posiadającego
jedynie operacje, a nie dane. Kiedy w
konkretnej klasie zdefiniowane są wszystkie
metody interfejsu mówimy, że klasa
implementuje dany interfejs.
~Wikipedia
5. Interfejsy w języku C#
IEnumerable
IDisposable
INotifyPropertyChanged
ICollection
ICommand
I wiele innych…
6. Kompozycja czy dziedziczenie?
Dziedziczeniem (ang. inheritance) w programowaniu
obiektowym nazywamy mechanizm współdzielenia
funkcjonalności między klasami. Klasa może dziedziczyć
po innej klasie, co oznacza, że oprócz swoich własnych
atrybutów oraz zachowań, uzyskuje także te pochodzące z
klasy, z której dziedziczy.
~Wikipedia
13. Kompozycja czy dziedziczenie?
Problemy wynikające z dziedziczenia:
Mnóstwo sztywno skonfigurowanych klas pochodnych
Zmiana w metodzie klasy bazowej wymusza zmianę wszystkich metod w
klasach pochodnych (np. zmiana zwracanego typu)
Brak możliwości zmiany zachowania w trakcie działania programu
Powielanie kodu
Źle zaprojektowana struktura klas prowadzi do omijania „na siłę” problemów
dziedziczenia
14. Zastosowanie kompozycji
Kompozycja to sytuacja, w której dana klasa zawiera
obiekty innych, już istniejących klas. Kompozycja to
relacja typu „x zawiera y”.
19. Zalety zastosowania kompozycji
+ Naturalne podejście do budowy obiektu danej klasy
+ SRP – klasy odpowiadają tylko za najważniejsze operacje, pozostałe
są delegowane do odpowiednich komponentów
+ Możliwość zmian obiektu w locie, mechanizm „upgrade’owania”
+ DRY
22. Inversion of Control – odwrócenie
sterowania
Inversion of Control (odwrócenie sterowania) – to paradygmat programowania
(czasami uznawany za wzorzec architektury) polegający na tym, że niezbędne
dla danej klasy komponenty otrzymywane są z zewnątrz.
Szczególny nacisk w tym podejściu kładzie się na reużywalne komponenty, co
osiągniemy wykorzystując interfejsy.
23. Inversion of Control – wykorzystanie
Dependency Injection
Dependency Injection (DI, wstrzykiwanie zależności) to podstawowa,
poza wzorcem Strategia, realizacja Inversion of Control.
Niezbędne dla danej klasy zależności są „wstrzykiwane” w zależności od
potrzeby poprzez konstruktor, metodę lub do konkretnego pola
(constructor injection, method injection, property injection).
Gwarantuje to tworzenie luźno powiązanego kodu.
26. IoC Container
Przy wykorzystaniu Dependency Injection dla
zachowania porządku w kodzie wykorzystuje się tzw.
kontenery.
Zadaniem kontenerów IoC jest grupowanie wybranych
komponentów oraz interfejsów które implementują po
to, aby w razie potrzeby móc „rozwiązać” daną
zależność.
29. IoC – korzyści
zwolnienie klasy z odpowiedzialności tworzenia
niezbędnych komponentów
tworzenie (małych) klas o ściśle określonych zadaniach
kod możliwy do testowania – klasa może otrzymać
dowolny komponent o ile implementuje on niezbędny
interfejs
30. Korzyści ze stosowania interfejsów
Tworzenie luźno powiązanego kodu gdzie poszczególne komponenty
mogą być w dowolnej chwili wymienione
Szersze spojrzenie na tworzony system, kwestia implementacji danej
klasy może być odłożona w czasie
Ułatwienie pracy programistów – brak konieczności oczekiwania na
zaimplementowanie danej metody, wystarczy „trzymać się”
określonej przez interfejs konwencji
Tworzenie kodu możliwego do testowania