java jako j¦zyk modularnyrklopotek.blog.uksw.edu.pl/files/2017/02/wyklad_3_2016...projektowanie...
TRANSCRIPT
Java jako j¦zyk modularny
Robert A. Kª[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¦ dopoprawiania 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 iprzyszªej konserwacji
� niekiedy pojawiaj¡ si¦ gªosy przeciwko refaktoryzacji sugeruj¡ce, zekod 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 nieich powstanie a utrzymanie
� kod spaghetti - "termin okre±laj¡cy skomplikowany, trudny dozrozumienia kod ¹ródªowy programu. Z takiego kodu skompilowanowiele programów w starszych j¦zykach proceduralnych, typu Fortranczy BASIC. Byªo to jeszcze przed powstaniem metodyprogramowania strukturalnego."
2 / 25
Kod spaghetti
� kojarzy si¦ gªównie z dªugimi, popl¡tanymi procedurami napisanymibardzo 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 powinnawykracza¢ 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 specy�kacji pakietu? Szczerze mówi¡cniewiele. Jedne co wiemy, to »e procedury generuj¡ jaki± plik. Alektó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» napierwszy rzut oka mamy rozeznanie, jakie zadania wykonuje proces iktóra procedura odpowiada za jak¡ czynno±¢ podczas generowaniapliku.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¢ zawyspecjalizowanymi funkcjami
6 Nale»y unika¢ przerwa« p¦tli � lepiej dostosowa¢ typ p¦tli do typuproblemu
5 / 25
Projektowanie biblioteki (1/2)
� pierwsz¡ spraw¡ bran¡ pod uwag¦ w programowaniu obiektowymjest "oddzielenie rzeczy, które si¦ zamieniaj¡ od rzeczy, które si¦ niezmieniaj¡"
� jest to szczególne istotne w przypadku bibliotek - u»ytkownicybiblioteki musza polega¢ na cz¦±ci, która wykorzystuj¡ i nieobawia¢ si¦, »e b¦d¡ musieli przepisywa¢ kod, je»eli pojawi si¦ nowawersja
� twórca biblioteki - ma swobod¦ w jej mody�kacji i ulepszania przyzachowaniu pewno±ci, »e zamiany nie b¦d¡ miaªy wpªywu na kodu»ytkowników, np. caªkowita zmiana funkcjonalno±ci, zmiana typuzwracanego wyniku itp.
� mo»na to osi¡gn¡¢ poprzez ustalenie konwencji - interfejsprogramistyczny aplikacji/biblioteki (ang. Application ProgrammingInterface, API)
6 / 25
Projektowanie biblioteki (2/2)
� w Javie rozwi¡zaniem s¡ mody�katory dost¦pu, które umo»liwiaj¡twórcom biblioteki zaznaczenie, co ma by¢ dost¦pne a co nie dlau»ytkownika
� projektant biblioteki powinien wszystko, co si¦ da, uczyni¢prywatnym (mody�kator private), a eksponowa¢ jedynie to, copowinno by¢ wykorzystywane przez u»ytkowników
� komponenty aplikacji ª¡czone s¡ w jednostki biblioteczne przezsªowo kluczowe package (pakiet)
� na mody�katory dost¦pu ma wpªyw to czy s¡ w tym samympakiecie czy w ró»nych (np. mody�kator domy±lny - patrzpoprzedni 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 kon�ikt z metod¡ f() klasy Bmimo tej samej sygnatury
� pakiet domy±lny (pakiet nienazwany) - rozwi¡zanie tylko napocz¡tku nauki Javy
� je±li planujemy tworzenie bibliotek, musimy zapobiec kon�iktomnazw!
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 "klasywspieraj¡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, ªadowaniei interpretowanie tych plików
� istniej¡ równie» kompilatory produkuj¡ce plik wykonywalny dladanej 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 wpliku (poza ewentualnymi komentarzami)
� instrukcja package moj_pakiet; oznacza, ze ta jednostkakompilacji 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 pakietumoj_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 pakietupowinna stanowi¢ odwrócona nazwa domeny internatowej twórcy,poniewa» unikatowo±¢ domen internetowych jest gwarantowana iunikniemy kon�iktu nazw
� przykªad: dla mojej domeny rklopotek.blog.uksw.edu.pl przedka»d¡ nawz¡ powinno si¦ znale¹¢ pl.edu.uksw.blog.rklopotek
� interpreter szuka klas z danego pakietu przechodz¡c drzewokatalogów rozdzielone kropkami, dlatego w przykªadzie pakietMojaKlasa z pakietu rak.moj_pakiet znajduje si¦ na ±cie»cerak/moj_pakiet/MojaKlasa.class
14 / 25
Przestrzenie nazw
� aby uruchomi¢ program znajduj¡cy si¦ w klasie MojaKlasa zkonsoli, nale»aªoby przej±¢ do katalogu rodzica i wykona¢ poleceniejava rak.moj_pakiet.MojaKlasa
� co si¦ dzieje, gdy program importuje dwie biblioteki zawieraj¡ce tesame nazwy?� w C/C++ "DLL Hell" - termin na komplikacje, które pojawiaj¡ si¦
przy korzystaniu z bibliotek dynamicznych stosowanych w systemachoperacyjnych Microsoft Windows, szczególnie w odziedziczonej wersji16-bitowej, w której wszystkie aplikacje dziaªaj¡ we wspólnejprzestrzeni adresowej. Obecnie problem nie jest ju» tak dotkliwy dzi¦kiwprowadzeniu .NET Framework, Registration-Free COM ifunkcjonalno±ci zapobiegaj¡cej nadpisaniu plików systemowych.
� w Java ten problem nie istnieje
� je±li nast¡pi kolizja nazw, kompilator zaprotestuje i wymusizastosowanie tzw. peªnej nazwy
15 / 25
Wªasna biblioteka narz¦dziowa
� biblioteki narz¦dziowe zwykle zawieraj¡ klasy z szeregiem metodstatycznych, 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 nauzyskanie innego zachowania za pomoc¡ przeª¡cznika bezzmienienia reszty kodu. Rozwi¡zanie byªo gªównie wykorzystywanedo przenoszenia kodu, np. #if _WIN64 czy #if __GNUC__
� kompilacja warunkowa nie istnieje w j¦zyku Java ze wzgl¦du naprzeno±no±¢ kodu - raz skompilowany kod b¦dzie dziaªa na innychplatformach
16 / 25
Kompilacja warunkowa
� istniej¡ jednak przydatne zastosowania tego podej±cia, np. podczasprojektu dobrzej jest wypisywa¢ informacje debug a w produkcjiklasa nie powinna wypisa¢ takich rzeczy - wystarczy do zmiennejCLASSPATH 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 musiby¢ 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, zpodkre±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"set", musi by¢ publiczna, typu void18 / 25
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 niecaªej hierarchii katalogów
� zapiecz¦towanie pakietu - JAR mo»e wymusi¢ spójno±¢ wersjipakietu, klasy zde�niowane w tym pakiecie musz¡ znajdowa¢ si¦ wtym 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 JARjar xf jar-file archived-file(s)
� uruchamiania aplikacji zapakowanej w archiwum JARjava -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 poleceniajava -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 poleceniemjar 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 wystartujemetoda main w klasie MyClass
23 / 25
Zde�niowanie 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¡ poleceniajar cfm MyJar.jar Manifest.txt MyPackage/*.class
wgramy ten manifest do pliku JAR
24 / 25