Zakład Inżynierii Oprogramowania
Transkrypt
Zakład Inżynierii Oprogramowania
Zakład Inżynierii Oprogramowania Programowanie w języku Java WYKŁAD dr inż. Piotr Zabawa Certyfikowany Konsultant IBM/Rational e-mail: [email protected] www: http://www.pk.edu.pl/~pzabawa 26.05.2014 Zakład Inżynierii Oprogramowania WYKŁAD 13 Refleksja Data Access Object (DAO) dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Refleksja dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Refleksja Refleksja jest jedną z cech charakterystycznych języka Java. Jednak wsparcie ze strony tego języka dla refleksji jest dość ograniczone charakter tych ograniczeń zostanie przedstawiony na kolejnych slajdach na tle cech charakterystycznych refleksji. dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Refleksja Jest to pojęcie z dziedziny informatyki oznaczające proces, dzięki któremu program komputerowy może być modyfikowany w trakcie działania w sposób zależny od własnego kodu oraz od zachowania w trakcie wykonania. Paradygmat programowania ściśle związany z mechanizmem refleksji to programowanie refleksyjne. Refleksja jest więc cechą interfejsu programistycznego i techniką programistyczną posiadającą dwa aspekty: • Możliwość dynamicznego uzyskania podczas wykonywania programu jego meta-danych, np. struktury klas, dostępnych metod w klasie, typów argumentów metod, informacji o nadklasach danego obiektu, interfejsów do obiektów • Możliwość wykorzystania powyższych informacji w programie np. przez utworzenie w czasie wykonania stringu zawierającego kod do wykonania w tym samym programie w czasie tej samej sesji programu dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Refleksja Refleksja jest jednym z mechanizmów wykorzystywanych w dynamicznych językach programowania, takich jak np. • • • • • • • • • • • Groovy Scala Ruby (w tym JRuby) Eiffel Erlang Lisp Perl Prolog Pyton (w tym Jyton) Smalltalk Clojure dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Refleksja W przypadku języka Java należy wziąć pod uwagę ograniczenie polegające na zjawisku zacierania typów (wspomniane na wykładzie o typach uogólnionych i o kontenerach). Zjawisko to osłabia mechanizm refleksji. Kolejne ograniczenie dotyczyło możliwości wstrzykiwania kodu do wersji Java 7. Ograniczenie to zostało jednak w znacznym stopniu zniesione za pomocą wyrażeń Lambda w Java 8. W ten sposób znacznie osłabiono problemy w Java związane z drugim aspektem refleksji. Jest to zarazem znaczący krok w stronę tzw. języków dynamicznych. dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Refleksja Mechanizm refleksji został zaimplementowany w bibliotekach standardowych Java w pakietach: • java.lang.reflect • java.lang dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Refleksja – dynamiczne ładowanie klas Wszystkie klasy Java dziedziczą z klasy Object. Dlatego właśnie możliwe było wprowadzenie mechanizmu refleksji. Każdy obiekt ma metodę getClass() zaimplementowaną w klasie Object. Zwraca ona informację o klasie danego obiektu. Informacja ta znajduje się w obiekcie java.lang.Class, a wspomniana metoda zwraca referencję do tego obiektu. Po uzyskaniu referencji do tego obiektu można na nim wykonywać szereg operacji, np. • getSuperClass() - zwracającą obiekt klasy Class oznaczający klasę bazową danej klasy, • getInterfaces() - zawracającą tablicę obiektów, zawierającą interfejsy danej klasy, • newInstance() - tworzącą nowy obiekt danej klasy. dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Refleksja – dynamiczne ładowanie klas Warto zwrócić uwagę na metodę newInstance() – jedyną, za pomocą której możemy tworzyć nowe obiekty w ramach mechanizmu refleksji. Nie możemy korzystać z operatora new(). dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Refleksja Podstawową metodą umożliwiającą realizowanie wywołań metod w ramach mechanizmu refleksji jest invokeMethod(), której argumentami są obiekt, na którym ma zostać wywołana metoda oraz argumenty wywoływanej metody. Przykład. Statyczne wywołanie: o.getData(); Dynamiczne wywołanie: o.invokeMethod("getData"); dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Refleksja Klasy pakietu java.lang.reflect • Array • Constructor – uzyskiwanie informacji i dostęp do konstruktora danej klasy – przydatne przy dynamicznym tworzeniu obiektu • Field – informacja i dostęp do wartości pola • Method – informacja o metodzie danej klasy i dynamiczne jej wywołanie na rzecz wskazanego obiektu • Modifier – infomacja o modyfikatorach składowej obiektu lub klasy dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Refleksja Przydatne metody klasy java.lang.Class • getClasses()/getDeclaredClasses() – zwracają tablicę obiektów klasy Class, które są składowymi danej klasy • getConstructors()/getDeclaredConstructors() – zwracają tablicę obiektów klasy Constructor; są to konstruktory danej klasy • getConstructor(Class[])/getDeclaredConstructor(Class[]) - zwracają obiekt konstruktor (obiekt klasy konstruktor), który ma podane typy argumentów • getMethods()/getDeclaredMethods() - zwracają tablicę, zawierającą odnośniki do metod klasy. Metody są obiektami klasy Method. • getMethod(String, Class[])/getDeclaredMethod(String, Class[]) zwracają metodę o podanej nazwie i podanych argumentach jako obiekt klsy Method. dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Refleksja Uwaga: • Metody z „Declared” – zwracają wszystkie metody zadeklarowane w danej klasie (wraz z prywatnymi) ale bez dziedziczonych • Metody bez „Declared” – zwracają wszystkie metody publiczne wraz z publicznymi dziedziczonymi dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Refleksja Przykład zastosowania mechanizmu refleksji – podany na stronie internetowej wykładu. dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO Dalej wykorzystano w znacznym stopniu: http://tutorials.jenkov.com/java-persistence/index.html oraz: http://www.eti.pg.gda.pl/katedry/kask/pracownicy/Jarosl aw.Kuchta/PAI/Laboratorium_nr_6.pdf dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO Jest to wzorzec architektoniczny wspierający operacje na warstwie danych. Wprowadza do oprogramowania dodatkową warstwę odpowiedzialną za dostęp do danych. Został wprowadzony najpierw do Java EE przez firmę Sun, jest jednak dostępny w większości technologii. dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO Wzorzec DAO służy do odseparowania informacji o danych aplikacji od sposobu, w jaki zapewniany jest dla nich mechanizm trwałości. Innymi słowy, aplikacja (jej warstwa logiki biznesowej) odwołuje się do danych w sposób niezależny od tego jak ani czy zapewniono ich trwałość. Zastosowanie takiego wzorca pozwala w konsekwencji na zmianę technologii zapewniania trwałości. W przypadku zastosowania technologii Hibernate wraz z DAO warstwa logiki biznesowej nie wie o fakcie zastosowania Hibernate do zapewnienia trwałości. Zmiana technologii trwałości dzięki użyciu DAO zawęża obszar zmian w kodzie do klas warstwy DAO i nie ma wpływu na warstwę logiki biznesowej. W praktyce zapewnienie aż tak daleko idącego uniezależnienia warstwy logiki biznesowej od mechanizmu trwałości może okazać się trudne do osiągnięcia. Dalej scharakteryzowano trudności. dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO Zakresy połączeń DAO (DAO connection scope) Jakie są możliwe relacje pomiędzy elementami DAO i połączeniami z bazą danych: • Zakres metody – każda metoda zarządza swoim połączeniem • Zakres instancji – każdy obiekt DAO zarządza swoim połączeniem • Zakres wątku – cała grupa obiektów DAO używanych przez dany wątek dla danej sesji z bazą danych zarządza swoim wątkiem dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO Zakres metody public class PersonDao{ protected DataSource dataSource = null; public PersonDao(DataSource dataSource){ this.dataSource = dataSource; } public Person readPerson(long personId){ Connection connection = this.dataSource.getConnection(); try{ Person person = ... return person; } finally { connection.close(); } } } dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO Problemy: • Wywołanie jednej metody DAO w drugiej – marnowanie połączeń • Jeśli dwie metody mają być wykonane w tej samej transakcji, to muszą używać tego samego połączenia – jak to zapewnić w tym podjściu? dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO Zakres instancji public class PersonDao{ protected Connection connection = null; public PersonDao(Connection connection){ this.connection = connection; } public Person readPerson(long personId){ Person person = ... return person; } } dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO Problemy: • Warstwa DAO nie wie jak zarządzać otwieraniem/zamykaniem połączeń • Warstwa logiki biznesowej nie powinna zajmować się otwieraniem/zamykaniem połączeń, ponieważ ma być od nich niezależna • Możliwość zastosowania wzorca projektowego Metody Wytwórczej do otwierania połączeń, ale każdy obiekt DAO zamyka połączenie: PersonDao personDao = daoFactory.createPersonDao(); Person person = personDao.readPerson(666); ... personDao.close(); • Co zrobić gdy musimy zapewnić wielu obiektom DAO skorzystanie z tego samego połączenia? dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO Zakres wątku daoFactory.beginConnectionScope(); PersonDao personDao = daoFactory.createPersonDao(); VehicleDao vehicleDao = daoFactory.createVehicleDao(); // ... daoFactory.endConnectionScope(); dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO Transakcje w DAO Obsługę transakcji można w naturalny sposób wpasować w realizację DAO z zakresem wątku. daoFactory.beginConnectionScope(); daoFactory.beginTransaction(); PersonDao personDao = daoFactory.createPersonDao(); VehicleDao vehicleDao = daoFactory.createVehicleDao(); // ... daoFactory.endTransaction(); daoFactory.endConnectionScope(); dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO W ramach jednego połączenia można zrealizować wiele transakcji. Spośród przedstawiony powyżej rozwiązań zarówno zakres wątku jak i zakres transakcji pozwalają ukryć przed warstwą logiki biznesowej sposób realizacji warstwy trwałości. Jednak nadal pozostają nierozwiązane dwa problemy: • Demarcation of the connection • Zakresy transakcji Ich rozwiązanie zostanie przedstawione w ramach DAOManager. dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO Obsługa wyjątków DAO W rozwiązaniach podanych wyżej jako zakres wątku lub zakres transakcji zgłoszenie wyjątku w jednej z metod DAO powoduje nieprawidłowe zachowanie aplikacji. Prawidłowy sposób obsługi wyjątków podano na następnym slajdzie. dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO try{ daoFactory.beginConnectionScope(); try{ daoFactory.beginTransaction(); PersonDao personDao = daoFactory.createPersonDao(); VehicleDao vehicleDao = daoFactory.createVehicleDao(); daoFactory.endTransaction(); } catch(Exception e){ daoFactory.abortTransaction(e); } } finally { daoFactory.endConnectionScope(); } dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO DAOManager Pozwala rozwiązać problemy nie rozwiązane wcześniej z wykorzystaniem fabryk. dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO public class DaoManager{ protected Connection connection = null; protected PersonDao personDao = null; public DaoManager(Connection connection){ this.connection = connection; } public PersonDao getPersonDao(){ if(this.personDao == null){ this.personDao = new PersonDao(this.connection); } return this.personDao; } } dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO Zakres połączenia DAOManager Sposób użycia w warstwie logiki biznesowej: DaoManager daoManager = daoFactory.createDaoManager(); Person person = daoManager.getPersonDao().readPerson(666); Jak widać nie wykonano operacji close(). Aby ją zaimplementować warto zastosować wzorzec projektowy Metoda szablonowa. Jego realizację przedstawiono dalej. dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO public class DaoManager{ ... public Object executeAndClose(DaoCommand command){ try{ return command.execute(this); } finally { this.connection.close(); } } } dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO public interface DaoCommand { public Object execute(DaoManager daoManager); } Sposób korzystania: DaoManager daoManager = daoFactory.createDaoManager(); Person person = (Person) daoManager.executeAndClose(new DaoCommand(){ public Object execute(DaoManager manager){ return manager.getPersonDao().readPerson(666); } }); dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO Zakres transakcji DAOManager Podobnie jak dodano do DAOManager’a metodę zarządzania połączeniami, można dodać metodę zarządzania transakcjami i ponownie wykorzystać – tym razem dla transakcyjności – wzorzec projektowy metoda szablonowa. Dodanie tej metody pokazano na następnym slajdzie, jednak z obsługą wyjątków bardzo uproszczoną i nie działającą poprawnie w niektórych sytuacjach. dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO public class DaoManager{ ... public Object transaction(DaoCommand command){ try{ this.connection.setAutoCommit(false); Object returnValue = command.execute(this); this.connection.commit(); return returnValue; } catch(Exception e){ this.connection.rollback(); throw e; //or wrap it before rethrowing it } finally { this.connection.setAutoCommit(true); } } } dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO Sposób wykorzystania tej metody: DaoManager daoManager = daoFactory.createDaoManager(); daoManager.transaction(new DaoCommand(){ public Object execute(DaoManager manager){ Person person = manager.getPersonDao().readPerson(666); person.setLastName("Nick"); manager.getPersonDao().updatePerson(person); } }); dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO Zamknięcie połączenia można zrealizować przez analogię do poprzedniego rozwiązania: public class DaoManager{ // ... public Object transactionAndClose(DaoCommand command){ executeAndClose(new DaoCommand(){ public Object execute(DaoManager manager){ manager.transaction(command); } }); } } dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO Podsumowanie DaoManager daoManager = daoFactory.createDaoManager(); daoManager.transaction(new DaoCommand(){ public Object execute(DaoManager manager){ Person person = manager.getPersonDao().readPerson(666); person.setLastName("Nick"); manager.getPersonDao().updatePerson(person); } }); dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO Problemy rozwiązane za pomocą DAOManager’a: • Zaznaczenie zakresu życia połączenia • Zaznaczenia zakresu transakcji • Automatyzacja otwierania/zamykania połaczenia • Automatyzacja zatwierdzania/odrzucania transakcji • Centralizacja obsługi wyjątków • Centralizacja dostępu do DAO – ułatwienie identyfikacji wszystkich DAO lub ułatwienie ich ponownego użycia dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO • Wykorzystanie DAO we frameworkach Javy: Hibernate • Spring http://docs.spring.io/spring/docs/3.0.x/api/org/springframework/dao/su pport/DaoSupport.html • Apache Hibernate Generic DAO: https://code.google.com/p/hibernate-generic-dao/ dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Data Access Object – DAO Generalizacje DAO. Wiele implementacji DAO opiera się na typach generycznych parametryzowanych klasą DAO. Podejście takie uważane jest za dobrą praktykę. dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Wzorce danych dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Wzorce danych Istnieje wiele wzorców związanych ze współpracą warstwy logiki biznesowej z warstwą danych. Są to wzorce architektoniczne lub architektoniczne wzorce korporacyjne. Warto zwrócić uwagę na dużo mniejsze uporządkowanie i usystematyzowanie tych wzorców w porównania z wzorcami projektowymi. dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Wzorce danych • Martin Fowler [http://martinfowler.com/eaaCatalog/]: – Data Transfer Object (DTO) http://martinfowler.com/eaaCatalog/dataTransferObject.html – Active Record http://martinfowler.com/eaaCatalog/activeRecord.html – Data Mapper http://martinfowler.com/eaaCatalog/dataMapper.html – Table Data Gateway http://martinfowler.com/eaaCatalog/tableDataGateway.html – Row Data Gateway http://martinfowler.com/eaaCatalog/rowDataGateway.html dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Wzorce danych • • Core J2EE patterns – Data Access Objects (DAO) – Transfer Object – Value List Handler – Domain Store http://www.corej2eepatterns.com/DomainStore.htm Eneterprise Integration Patterns http://www.eaipatterns.com/ dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki Zakład Inżynierii Oprogramowania Koniec dr inż. Piotr Zabawa Instytut Informatyki Wydział Fizyki, Matematyki i Informatyki