Interfaces 101

31
101 sposobów na… Interfejsy Przemysław Smyrdek

Transcript of Interfaces 101

101 sposobów na…

Interfejsy

Przemysław Smyrdek

O mnie

Przemysław Smyrdek

[email protected]

github.com/psmyrdek

@psmyrdek

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

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

Interfejsy w języku C#

IEnumerable

IDisposable

INotifyPropertyChanged

ICollection

ICommand

I wiele innych…

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

Kompozycja czy dziedziczenie?

Kompozycja czy

dziedziczenie?

Kompozycja czy dziedziczenie?

Kompozycja czy dziedziczenie?

Kompozycja czy dziedziczenie?

Kompozycja czy dziedziczenie?

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

Zastosowanie kompozycji

Kompozycja to sytuacja, w której dana klasa zawiera

obiekty innych, już istniejących klas. Kompozycja to

relacja typu „x zawiera y”.

Zastosowanie

kompozycji

Zastosowanie

kompozycji

Zastosowanie kompozycji

Zastosowanie kompozycji

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

Ale można jeszcze lepiej…

Ale można jeszcze lepiej…

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.

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.

Inversion of Control – wykorzystanie

Dependency Injection

Inversion of Control – wykorzystanie

Dependency Injection

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ść.

AutoFac

https://github.com/autofac/Autofac

Symulacja wypłaty z bankomatu

1. włóż kartę

2. sprawdź poprawność karty

2. wybierz pin

3. sprawdź pin

4. podaj kwotę

5. sprawdź możliwość pobrania pieniędzy

6. wypłać pieniądze

7. wydrukuj paragon

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

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

Dziękuję za uwagę.