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

Podobne dokumenty