Java jako j¦zyk modularny

advertisement
Java jako j¦zyk modularny
Robert A. Kªopotek
[email protected]
Wydziaª Matematyczno-Przyrodniczy. Szkoªa Nauk ‘cisªych, UKSW
10.03.2017
Kontrola dost¦pu
"Kontrola dost¦pu (tudzie» ukrywanie informacji) sprowadza si¦ do
poprawiania tego, co nie udaªo si¦ za pierwszym razem"
refaktoryzacja kodu - polega na jego przepisywaniu tak, aby byª
czytelniejszy, bardziej zrozumiaªy, ªatwiejszy do ogarni¦cia i
przyszªej konserwacji
niekiedy pojawiaj¡ si¦ gªosy przeciwko refaktoryzacji sugeruj¡ce, ze
kod dziaªaj¡cy to kod dobry i dªubanie w nim to strata czasu
lwia cz¦±¢ nakªadów czasowych i nansowych w projektach to nie
ich powstanie a utrzymanie
kod spaghetti - "termin okre±laj¡cy skomplikowany, trudny do
zrozumienia kod ¹ródªowy programu. Z takiego kodu skompilowano
wiele programów w starszych j¦zykach proceduralnych, typu Fortran
czy BASIC. Byªo to jeszcze przed powstaniem metody
programowania strukturalnego."
2 / 25
Kod spaghetti
kojarzy si¦ gªównie z dªugimi, popl¡tanymi procedurami napisanymi
bardzo dawno temu
pierwszym symptomem kodu spaghetti jest sama dªugo±¢ kodu,
kilkana±cie, kilkadziesi¡t tysi¦cy linii kodu, ogromna ilo±¢
rozgaª¦zie« utrudnia poruszanie si¦ po takim kodzie.
standardowo dªugo±¢ jednej jednostki programowej nie powinna
wykracza¢ poza ekran monitora (zalecane maksymalnie 50-80 linii)
nie tylko dªugi kod to spaghetti - np. metoda, która podbija licznik,
a potem usuwa dane z tablicy niezwi¡zanej z licznikiem
dzielenie kodu na mniejsze jednostki programowe
3 / 25
Kod spaghetti - przykªady
Pakiet 1: generate _le
Procedury: Main_le , Start _le , Run_le , Gen_le
Ile wiemy po przejrzeniu specykacji pakietu? Szczerze mówi¡c
niewiele. Jedne co wiemy, to »e procedury generuj¡ jaki± plik. Ale
która procedura odpowiada za jak¡ funkcjonalno±¢ w procesie?
Pakiet 2: generate _le
Procedury: Main, Get _lename , Get _data, Open_le , Create _line ,
Save _line , Close _le
W powy»szym pakiecie b¦dzie du»o ªatwiej si¦ porusza¢. Ju» na
pierwszy rzut oka mamy rozeznanie, jakie zadania wykonuje proces i
która procedura odpowiada za jak¡ czynno±¢ podczas generowania
pliku.
4 / 25
Dobre praktyki
1
Nazwy jednostek programowych powinny by¢ precyzyjne,
odzwierciedlaj¡ce funkcjonalno±¢ procedury
2
Kod powinien mie±ci¢ si¦ na ekranie
3
Podziaª programu na mniejsze jednostki powinien odbywa¢ si¦
wedªug zasady "od ogóªu do szczegóªu" a nie na chybiª traª
4
Ilo±¢ wyj±¢ z programu powinna wynosi¢ 1.
5
Skomplikowane algorytmy, warunki if nale»y schowa¢ za
wyspecjalizowanymi funkcjami
6
Nale»y unika¢ przerwa« p¦tli lepiej dostosowa¢ typ p¦tli do typu
problemu
5 / 25
Projektowanie biblioteki (1/2)
pierwsz¡ spraw¡ bran¡ pod uwag¦ w programowaniu obiektowym
jest "oddzielenie rzeczy, które si¦ zamieniaj¡ od rzeczy, które si¦ nie
zmieniaj¡"
jest to szczególne istotne w przypadku bibliotek - u»ytkownicy
biblioteki musza polega¢ na cz¦±ci, która wykorzystuj¡ i nie
obawia¢ si¦, »e b¦d¡ musieli przepisywa¢ kod, je»eli pojawi si¦ nowa
wersja
twórca biblioteki - ma swobod¦ w jej modykacji i ulepszania przy
zachowaniu pewno±ci, »e zamiany nie b¦d¡ miaªy wpªywu na kod
u»ytkowników, np. caªkowita zmiana funkcjonalno±ci, zmiana typu
zwracanego wyniku itp.
mo»na to osi¡gn¡¢ poprzez ustalenie konwencji - interfejs
programistyczny aplikacji/biblioteki (ang. Application Programming
Interface, API)
6 / 25
Projektowanie biblioteki (2/2)
w Javie rozwi¡zaniem s¡ modykatory dost¦pu, które umo»liwiaj¡
twórcom biblioteki zaznaczenie, co ma by¢ dost¦pne a co nie dla
u»ytkownika
projektant biblioteki powinien wszystko, co si¦ da, uczyni¢
prywatnym (modykator private), a eksponowa¢ jedynie to, co
powinno by¢ wykorzystywane przez u»ytkowników
komponenty aplikacji ª¡czone s¡ w jednostki biblioteczne przez
sªowo kluczowe package (pakiet)
na modykatory dost¦pu ma wpªyw to czy s¡ w tym samym
pakiecie czy w ró»nych (np. modykator domy±lny - patrz
poprzedni wykªad)
7 / 25
Pakiet - jednostka biblioteczna
Pakiet - grupa klas zebranych razem we wspólnej przestrzeni nazw
biblioteka narz¦dziowa Javy: java.util
// plik PelnaNazwa . java
class PelnaNazwa
{
public static void main ( String [] args ){
java . util . ArrayList list = new java . util . ArrayList ();
}
}
// plik Importowanie . java
import java . util . ArrayList ;
class Importowanie
{
public static void main ( String [] args ){
ArrayList list = new ArrayList ();
}
}8 / 25
Dlaczego importowanie?
dostarczenie mechanizmu zarz¡dzaniem przestrzeniami nazw
nazwy skªadników s¡ od siebie odizolowane
metoda f() klasy A nie wejdzie w konikt z metod¡ f() klasy B
mimo tej samej sygnatury
pakiet domy±lny (pakiet nienazwany) - rozwi¡zanie tylko na
pocz¡tku nauki Javy
je±li planujemy tworzenie bibliotek, musimy zapobiec koniktom
nazw!
9 / 25
Jednostka kompilacji
jednostka kompilacji (jednostka translacji) - plik z kodem
¹ródªowym Java
nazwa ka»dej jednostki kompilacji musi mie¢ rozszerzenie .java
wewn¡trz jednostki kompilacji mo»e znajdowa¢ si¦ klasa publiczna,
której nazwa musi by¢ taka sama jak nazwa pliku
w ka»dej jednostce mo»e znajdowa¢ si¦ tylko jedna klasa publiczna
ewentualne inne klasy wchodz¡ce w skªad jednostki kompilacji s¡
ukryte przed ±wiatem zewn¦trznym, stanowi¡ one "klasy
wspieraj¡ce" zamieszczonej gªównej klasy publicznej
10 / 25
Organizacja kodu
po kompilacji pliku .java, otrzymujemy dla ka»dej klasy z pliku plik o takiej samej nazwie ale z rozszerzeniem .class
w ogólno±ci z jedno pliku .java mo»emy otrzyma¢ kilka plików
.class
dziaªaj¡cy program to zbiór plików typu .class, które mog¡ zosta¢
spakowane programem archiwizuj¡cym do typu .jar
interpreter Javy (java.exe) odpowiada za znajdowanie, ªadowanie
i interpretowanie tych plików
istniej¡ równie» kompilatory produkuj¡ce plik wykonywalny dla
danej platformy sprz¦towej (kompilacja podobna do C/C++)
11 / 25
Budowanie biblioteki
Biblioteka stanowi zespóª plików zawieraj¡cych klasy
je±li chcemy zaznaczy¢, »e komponenty (.java i .class) stanowi¡
jedn¡ caªo±¢, u»ywamy sªowa kluczowego package
je±li stosujemy instrukcj¦ package to musi by¢ ona jako pierwsza w
pliku (poza ewentualnymi komentarzami)
instrukcja package moj_pakiet; oznacza, ze ta jednostka
kompilacji znajduje si¦ w przestrzeni nazw moj_pakiet, wi¦c ka»dy,
kto chciaªby wykorzysta¢ zawarte w niej nazwy, musi albo u»y¢
peªnej nazwy, albo u»y¢ instrukcji import z nazwa pakietu
moj_pakiet
12 / 25
Budowanie biblioteki - przykªad
// plik rak / moj_pakiet / MojaKlasa . java
package rak . moj_pakiet ;
public class MojaKlasa {
// ...
}
// plik rak / PelnaNazwa . java
public class PelnaNazwa {
public static void main ( String [] args ){
rak . moj_pakiet . MojaKlasa m =
new rak . moj_pakiet . MojaKlasa ();
}
}
// plik rak / Importowanie . java
import rak . moj_pakiet .*;
public class Importowanie {
public static void main ( String [] args ){
MojaKlasa m = new MojaKlasa ();
}
}13 / 25
Tworzenie unikatowych nazw pakietów
aby organizowa¢ wiele plików wynikowych .class skªadaj¡cych si¦
na dany pakiet, mo»na umie±ci¢ je w jednym katalogu
je±li mamy wiele pakietów to otrzymujemy hierarchi¦ katalogów
zgodnie z konwencja przyjmuje si¦, »e pierwsza cz¦±¢ nazwy pakietu
powinna stanowi¢ odwrócona nazwa domeny internatowej twórcy,
poniewa» unikatowo±¢ domen internetowych jest gwarantowana i
unikniemy koniktu nazw
przykªad: dla mojej domeny rklopotek.blog.uksw.edu.pl przed
ka»d¡ nawz¡ powinno si¦ znale¹¢ pl.edu.uksw.blog.rklopotek
interpreter szuka klas z danego pakietu przechodz¡c drzewo
katalogów rozdzielone kropkami, dlatego w przykªadzie pakiet
MojaKlasa z pakietu rak.moj_pakiet znajduje si¦ na ±cie»ce
rak/moj_pakiet/MojaKlasa.class
14 / 25
Przestrzenie nazw
aby uruchomi¢ program znajduj¡cy si¦ w klasie MojaKlasa z
konsoli, nale»aªoby przej±¢ do katalogu rodzica i wykona¢ polecenie
java rak.moj_pakiet.MojaKlasa
co si¦ dzieje, gdy program importuje dwie biblioteki zawieraj¡ce te
same nazwy?
w C/C++ "DLL Hell" - termin na komplikacje, które pojawiaj¡ si¦
przy korzystaniu z bibliotek dynamicznych stosowanych w systemach
operacyjnych Microsoft Windows, szczególnie w odziedziczonej wersji
16-bitowej, w której wszystkie aplikacje dziaªaj¡ we wspólnej
przestrzeni adresowej. Obecnie problem nie jest ju» tak dotkliwy dzi¦ki
wprowadzeniu .NET Framework, Registration-Free COM i
funkcjonalno±ci zapobiegaj¡cej nadpisaniu plików systemowych.
w Java ten problem nie istnieje
je±li nast¡pi kolizja nazw, kompilator zaprotestuje i wymusi
zastosowanie tzw. peªnej nazwy
15 / 25
Wªasna biblioteka narz¦dziowa
biblioteki narz¦dziowe zwykle zawieraj¡ klasy z szeregiem metod
statycznych, np. java.io.* (System.out.printl) czy java.util.*
(klasy zwi¡zane z kolekcjami, takimi jak listy, mapy, zbiory,
iteratory, komparatory, itp.)
w j¦zyku C/C++ istnieje kompilacja warunkowa pozwalaj¡ca na
uzyskanie innego zachowania za pomoc¡ przeª¡cznika bez
zmienienia reszty kodu. Rozwi¡zanie byªo gªównie wykorzystywane
do przenoszenia kodu, np. #if _WIN64 czy #if __GNUC__
kompilacja warunkowa nie istnieje w j¦zyku Java ze wzgl¦du na
przeno±no±¢ kodu - raz skompilowany kod b¦dzie dziaªa na innych
platformach
16 / 25
Kompilacja warunkowa
istniej¡ jednak przydatne zastosowania tego podej±cia, np. podczas
projektu dobrzej jest wypisywa¢ informacje debug a w produkcji
klasa nie powinna wypisa¢ takich rzeczy - wystarczy do zmiennej
CLASSPATH doda¢ odpowiedni¡ wersj¦, która ró»ni si¦ np.
wypisywaniem komunikatów
je±li chodzi o sam kod to kompilator optymalizuje nieu»ywany kod,
aby wymusi¢ usuni¦cie danego fragmentu wystarczy wstawi¢
zmienn¡ steruj¡c¡ static final, np.:
static final boolean DEBUG = false ;
if ( DEBUG ) {
// some code ....
}
17 / 25
Konwencje nazewnictwa
Klasy i interfejsy - pierwsza litera nazwy klasy, lub interfejsu musi
by¢ du»a, a pozostaªe litery maªe
Metody - metody zaczyna maªa litera, nast¦pne zgodnie z
"camelCase"
Zmienne - pierwsza litera maªa, a kolejne zgodnie z "camelCase"
Staªe - staªe w Javie oznaczane s¡ poprzez "static" oraz "nal".
Nazwy staªych powinny by¢ pisane wielkimi literami, z
podkre±leniem "_", je»eli nazwa skªada si¦ z wielu czªonów
Pola klas
je±li pole klasy nie jest typu logicznego (boolean), metoda zwracaj¡ca
jej warto±¢ powinna zaczyna¢ si¦ od sªowa "get", musi by¢ publiczna,
bezparametrowa
je±li pole klasy jest typu logicznego, metoda zwracaj¡ca jej warto±¢,
powinna zaczyna¢ si¦ od sªowa "is"
metoda ustawiaj¡ca warto±¢ pola klasy powinna zaczyna¢ si¦ od sªowa
18 / 25 "set", musi by¢ publiczna, typu void
Pakowanie bibliotek - zalety JAR
bezpiecze«stwo - istnieje mo»liwo±¢ podpisania cyfrowego pliku JAR
zmniejszony czas pobierania - je±li biblioteka JAR jest cz¦±ci¡
aplikacji webowej
kompresja danych - kompresja JAR wykorzystuje algorytm ZIP
opakowanie do rozszerzania - w prosty sposób mo»na dodawa¢
funkcjonalno±¢ przez skopiowanie do projektu jednego pliku a nie
caªej hierarchii katalogów
zapiecz¦towanie pakietu - JAR mo»e wymusi¢ spójno±¢ wersji
pakietu, klasy zdeniowane w tym pakiecie musz¡ znajdowa¢ si¦ w
tym samym pliku JAR
wersjonowanie pakietów
przeno±no±¢ - biblioteka lub aplikacja prosta do uruchomienia, np.
H2 SQL server
19 / 25
Podstawy JAR
tworzenie pliku JAR jar cf jar-file input-file(s)
ogl¡danie zawarto±ci JAR jar tf jar-file
wypakowywanie caªej zawarto±ci JAR jar xf jar-file
wypakowywanie niektórych plików w archiwum JAR
jar xf jar-file archived-file(s)
uruchamiania aplikacji zapakowanej w archiwum JAR
java -jar app.jar
20 / 25
Podstawy JAR
pakowanie struktury:
jar cvf TicTacToe.jar TicTacToe.class audio images
pakowanie bez kompresji:
jar cvf0 TicTacToe.jar TicTacToe.class audio images
pakowanie zawarto±ci katalogu: jar cvf TicTacToe.jar *
plik META-INF/MANIFEST.MF zawiera Main-Class: classname nazw¦ klasy, któr¡ nale»y uruchomi¢ z polecenia
java -jar app.jar
21 / 25
Plik manifestu
zawiera informacje o pliku JAR: klas¦ do uruchomienia, wersj¦,
kompilator, podpis cyfrowi, itp.
znajduje si¦ w zawsze w META-INF/MANIFEST.MF
domy±lna warto±¢ (dla wersji JDK 1.7.0_06):
Manifest - Version : 1.0
Created - By : 1.7.0 _06 ( Oracle Corporation )
zmiana pliku manifestu:
jar cfm jar-file manifest-addition input-file(s)
zawarto±¢ manifestu musi mie¢ kodowanie UTF-8
22 / 25
Plik manifestu - przykªad
niech plik manifestu ma nazw¦ Manifest.txt i zawiera lini¦
Main-Class: MyPackage.MyClass
wtedy mo»emy utworzy¢ plik JAR z tym manifestem poleceniem
jar cfm MyJar.jar Manifest.txt MyPackage/*.class
to utworzy plik o zawarto±ci:
Manifest - Version : 1.0
Created - By : 1.7.0 _06 ( Oracle Corporation )
Main - Class : MyPackage . MyClass
wtedy po uruchomieniu JAR java -jar MyJar.jar wystartuje
metoda main w klasie MyClass
23 / 25
Zdeniowanie wersji - przykªad
niech plik manifestu ma nazw¦ Manifest.txt i zawiera:
Name : java / util /
Specification - Title : Java Utility Classes
Specification - Version : 1.2
Specification - Vendor : Example Tech , Inc .
Implementation - Title : java . util
Implementation - Version : build57
Implementation - Vendor : Example Tech , Inc .
wtedy za pomoc¡ polecenia
jar cfm MyJar.jar Manifest.txt MyPackage/*.class
wgramy ten manifest do pliku JAR
24 / 25
Pytania?
25 / 25
Download