340 likes | 499 Views
Style Kodowania. Robert Strack. strack@ciapek.uci.agh.edu.pl. Style Kodowania. formatowanie kodu. konwencje nazewnicze. konwencje programistyczne. dokumentowanie kodu. struktura projektu. używanie pakietów. logowanie. pliki JAR. Formatowanie kodu. Uwagi ogólne.
E N D
Style Kodowania Robert Strack strack@ciapek.uci.agh.edu.pl
StyleKodowania formatowanie kodu konwencje nazewnicze konwencje programistyczne dokumentowanie kodu struktura projektu używanie pakietów logowanie pliki JAR
Formatowanie kodu Uwagi ogólne pliki źródłowe nie powinny zawierać więcej niż 2000 linii kodu • zwiększa to przejrzystość struktury programu i przyspiesza • wyszukiwanie interesujących nas fragmentów każda linia powinna się mieścić w oknie edytora (standardowo 80 znaków) - łatwiej zrozumieć wyrażenia, które da się objąć w całości wzrokiem - przełamany fragment linii należy poprzedzić szerokim wcięciem public static void copyFile(String source, String destination) { /* do something */ } robiąc wcięcia, sugerowane jest, aby nie używać znaków spacji (zamiast tego lepiej użyć tabulatora) • dzięki temu osoba pracująca z naszym kodem w innym edytorze może dostosować • szerokość odstępów nie ingerując w nasz kod, ale jedynie poprzez zmianę • domyślnej szerokości tabulacji - większe wcięcia zwiększają czytelność kodu
Formatowanie kodu Białe znaki mile widziana jest spacja po przecinkach w liście parametrów funkcji • zwiększa to czytelność deklaracji umieszczanie spacji pomiędzy nazwą funkcji i okrągłymi nawiasami zmniejsza czytelność public static int addNumbers(int first, int second) { return first + second; } podczas wykonywania działań należy rozdzielać zmienne od operatorów result = (variable1 + variable2) / variable3; odstęp powinien się również znaleźć w instrukcji rzutowania BaseClass myClass = (BaseClass) yourClass;
Formatowanie kodu Instrukcje sterujące konstrukcja instrukcji „if” if (condition) { statements; } • mile widziane jest używanie nawiasów klamrowych po „if”, nawet jeśli nie są one • wymagane if (condition) { statements; } else { statements; }
Formatowanie kodu Instrukcje sterujące konstrukcja pętli „do” i „do-while” while (condition) { statements; } do { statements; } while (condition); konstrukcja pętli „for” for (initialization; condition; update) { statements; }
Formatowanie kodu Instrukcje sterujące konstrukcja instrukcji „switch” • jeżeli po „case” nie zamierzamy wstawić instrukcji „break” należy to zaakcentować • komentarzem • wewnątrz każdej instrukcji „switch” powinna się znaleźć opcja „default” (może być pusta) switch (condition) { case ONE: statements; /* falls through */ case TWO: statements; break; default: statements; break; }
Formatowanie kodu Instrukcje sterujące przechwytywanie wyjątków - nie należy pozostawiać nie obsłużonych wyjątków try { statements; } catch (Exception ex) { statements; } finally { statements; } „return” nie jest funkcją, więc nie należy stawiać po nim nawiasów • użycie nawiasów jest wskazane, jeśli wyrażenie zwracane przez funkcje jest skomplikowane return value; return ((a > b) ? a : b);
Formatowanie kodu Deklaracje każda zmienna powinna być deklarowana w nowej linii - długie deklaracje nie są przejrzyste MyClass myObject1; MyClass myObject2; deklaracje metod powinny zawierać informacje o rzucanych wyjątkach - w języku JAVA wymusza to kompilator! public void doSomething() throws Exception { statements; } liczba argumentów funkcji nie powinna być zbyt duża - funkcje takie są niewygodne w użyciu
Formatowanie kodu Nazwy nazwy klas i interfejsów powinny się rozpoczynać wielką literą tak samo każde słowo składające się na nazwę; niewskazane jest używanie separatorów class MyClass extends YourClass { /* body */ } nazwy metod i zmiennych rozpoczyna się mała literą, występujące dalej słowa pisze się już wielką literą - wyjątkiem są konstruktory, które mają nazwę identyczną z nazwą klasy public int getDifference(int a, int b) { int value = a – b; return value; } dla stałych używa się wyłącznie wielkich liter i separatorów (podobnie jak w C) final int CONST_VALUE = 100;
Formatowanie kodu Nazwy do tworzenia nazw pakietów używa się wyłącznie małych liter, bez separatora „_” - przypominają odwrócony adres internetowy package domain.company.project.module; - duże litery mogą wystąpić tylko w nazwach klas import java.applet.Applet;
Formatowanie kodu Dodatkowe konwencje nie powinno się używać zmiennych zadeklarowanych jako public (chyba, że public static final) zamiast tego można (trzeba) deklarować metody typu get/set • metody te nie powinny nic robić poza zwracaniem i ustawianiem wartości public void setName(String name) { this.name = name; } public String getName() { return name; } public bool isActive() { return active; }
Formatowanie kodu Dodatkowe konwencje wszelkie „gotowe” wartości liczbowe powinny być umieszczane w kodzie jako stałe • pozwoli nam to w przyszłości szybko wprowadzać modyfikacje oraz • zwiększy czytelność kodu wewnątrz konstruktorów (i funkcji typu set) dobrze jest używać konstrukcji w stylu „this.variable = variable” public MyClass(String name) { this.name = name; } w dobrym stylu jest przeładowywać metody dziedziczone z klasy Object (np. toString(), equals()) public String toString() { return („My name is: ” + name + surname); } importując pakiety powinno się użyć nazwy konkretnej klasy (zamiast „*”) import java.applet.Applet
Dokumentowanie kodu Dokumentacja tworzenie dokumentacji jest niezbędne w każdym większymprojekcie informatycznym • dzięki temu możemy sobie szybciej przypomnieć, w jaki sposób zachowują się naszeklasy oraz umożliwić analizę kodu osobom trzecim dokumentacja powinna być pisana w języku angielskim • zapewni to spójność z istniejącymi standardami (np. javadoc) komentarze powinny dotyczyć klas, interfejsów, zmiennych i metod dobrze jeśli komentarze są tworzone na bieżąco składnia komentarzy /* comment */ • komentarz mogący się rozciągać na wiele wierszy // comment • komentarz w jednym wierszu /** comment */ • komentarz javadoc (javadoc pomija każdy inny komentarz!)
Dokumentowanie kodu Dokumentacja najważniejsze znaczniki dokumentacyjne • są umieszczane wewnątrz komentarzy, na ich podstawie tworzona jest • dokumentacja przez program javadoc w dokumentacji wygenerowanej przez javadoc w tym miejscu zostaną umieszczone odnośniki do „MyClass” i metody „methodFromMyClass” @see MyClass @see MyClass#methodFromMyClass @version description opis wersji @author my-name autor @param paramether description parametry @return description wartość zwracana @throws what description typy rzucanych wyjątków @deprecated Sugeruje by nie używać danej właściwości (w przyszłości może zostać usunięta)
Dokumentowanie kodu Dokumentacja komentowanie klas • powinien się znaleźć komentarz o relacjach klasy z innymi klasami (@see),informacje o autorach (@author) i wersji (@version) komentowanie metod • opisany powinien być sposób działania metody, odwołania do innych metod (@see), • przyjmowane parametry (@param),rzucane wyjątki (@throws) • i wartość zwracana (@return) nagłówki plików • każdy plik projektu powinien zaczynać się informacją o swojej zawartości dodatkowe komentarze • jeżeli instrukcjom języka JAVA będą towarzyszyć słowne informacje o działaniuzastosowanych algorytmów, przyszła analiza budowy • metod i klas będzie łatwiejsza
Dokumentowanie kodu Dokumentacja przykład dokumentowania // HelloWorld.java // Writes „Hello World!” onto screen import java.lang.System; /** My first class in JAVA * @author Robert Strack * @author strack@ciapek.uci.agh.edu.pl * @version 1.0 */ public class HelloWorld { /** Function only says „Hello World!” * @param args String used for holding parameters * @return Nothing */ public static void main(String[] args) { System.out.println(„Hello World!”); } }
Dokumentowanie kodu Dokumentacja przykład dokumentowania (gotowa dokumentacja przy użyciu javadoc)
Struktura projektu Struktura katalogów struktura katalogów powinna wyglądać następująco:
Pakiety Wykorzystywanie pakietów pakiet – jest to zbiór klas i interfejsów z kontrolą dostępu do nich i własną przestrzenią nazw (odpowiednik biblioteki w C) zamieszczając klasy w pakiecie: • możemy zaznaczyć, że są one ze sobą powiązane • ich nazwy nie wchodzą w konflikt z nazwami innych klas - pakiet posiada własną • przestrzeń nazw • możemy pozwolić, aby klasy z naszego pakietu miały nieograniczony dostęp do siebienawzajem i jednocześnie były niewidoczne dla klas spoza pakietu(ukrywanie implementacji) • poprzez pakiety budujemy logiczną strukturę projektu
Pakiety Tworzenie pakietów w celu dołączenia klasy (klas) do pakietu używamy konstrukcji package name.of.this.package; • instrukcja powinna być podana przed definicjami klas (na początku pliku) aby użyć klas lub interfejsów wchodzących w skład pakietuposługujemy się konstrukcją import name.of.this.package; • instrukcja powinna być podana przed definicjami klas (na początku pliku) jeden plik może zawierać dowolną ilość klas, ale tylko jedna z nichmoże być zadeklarowana jako „public” klasy nie zadeklarowane jako publiczne nie są widocznepoza pakietem
Pakiety Tworzenie pakietów do klasy znajdującej się w zaimportowanym pakiecie możemy się odwołać przez jej nazwę, lub podając pełną nazwę pakietu z któregoklasa pochodzi + nazwę klasy String name; java.lang.String name; • dzięki temu pojawienie się dwóch klas o identycznych nazwach, ale zawartych w innychpakietach nie jest problemem (klasy te są rozróżnialne)
Logowanie Rejestracja rejestracja polega na tworzeniu i gromadzeniu informacji owykonującym się programie (najczęściej w celu usunięcia błędów lub zwiększenia wydajności) • informacje można wypisywać wstawiając w kod programu wywołania procedurSystem.out.println(), ale taki sposób rejestracji nie jest wygodny • zamiast tego można użyć klasy java.util.logging.Logger przewaga „logowania” nad zwykłym wypisywaniem informacji dopliku, czy na ekran: • jeżeli program już działa poprawnie nie potrzebujemy usuwać linii w którychrejestrowaliśmy komunikaty o przebiegu jego działania... wystarczy, żewyłączymy Logger’a (występowanie wywołań metod klasy Logger niespowolni pracy programu) • możemy w łatwy sposób zmieniać sposób rejestrowania (wypisanie na ekran, do plikua nawet wysłanie mailem!) • istnieje możliwość filtrowania komunikatów ze względu na ich wagę
Logowanie Rejestracja każda wiadomość ma przypisaną wagę (poziom): • SEVERE • WARNING • INFO • CONFIG • FINE • FINER • FINEST • dodatkowo poziomy OFF i ALL (do włączania i wyłączania rejestracji) ustawiając poziom logowania dla konkretnego obiektu klasy Loggermożemy przefiltrować wiadomości jakie dla nas rejestruje Logger logger = Logger.getLogger(„logger name”); logger.setLevel(Level.INFO); logger.warning(„warning”); logger.info(„information”); logger.fine(„other information”); • w powyższym przykładzie wypisana zostanie informacja „information” i „warning”(wypisywane są informacje o poziomie równym lub wyższym od ustalonego)
Logowanie Rejestracja aby zmienić sposób rejestracji (np. skierować informacje do pliku)należy się posłużyć klasą Handler (i klasami po niej dziedziczącymi) Logger logger = Logger.getLogger(„logger name”); logger.addHandler(new FileHandler(„file.xml”)); logger.info(„information”); • informacja zostanie zapisana do pliku file.xml • inne klasy pochodne od klasy Handler: ConsoleHandler, MemoryHandler... jeżeli chcemy zapisywać wyniki w zwykłym pliku tekstowym,dodatkowo trzeba się posłużyć obiektem klasy Formatter (lub poniej dziedziczącym) Logger logger = Logger.getLogger(„logger name”); logger.setFormatter(new SimpleFormatter()); logger.addHandler(new FileHandler(„file.txt”)); logger.info(„information”);
Logowanie Rejestracja możliwe jest oczywiście rozbudowywanie funkcji klas Formatter(klasy formatującej dane), Handler (klasy obsługującej magazynowaniedanych) i Filter (klasy zajmującej się filtrowaniem informacji)poprzez dziedziczenie – stworzenie tym samym w pełni odpowiadającego nam systemu rejestracji pakiet java.util.logging zawiera jeszcze wiele przydatnych funkcji – są one opisane w dokumentacji
Logowanie Rejestracja podobne możliwości daje nam pakiet org.apache.log4j • używa się go podobnie jak pakietu java.util.logging Logger logger = Logger.getLogger(„logger name”); logger.setLevel(Level.INFO); logger.info(„information”); log4j daje nam duże możliwości konfiguracji • wewnątrz kodu programu automatyczna konfiguracja(poziomy logowania są ustawianena domyślne wartości) BasicConfigurator.configure(); • za pomocą pliku konfiguracyjnego PropertyConfigurator.configure(„configuration.conf”); zostanie użyty plik konfiguracyjny„configuration.conf”
Logowanie Rejestracja przykład budowy pliku konfiguracyjnego # ustawiamy poziomu logowania na DEBUG# chcemy, aby rejestrowane wiadomości były wyświetlane# na ekranie i zapisywane do plikulog4j.rootLogger = DEBUG, screen, file# „screen” służy do wypisywania wiadomości na ekranlog4j.appender.screen = org.apache.log4j.ConsoleAppender # ustalamy sposób wypisywania (data, priorytet i wiadomość) log4j.appender.screen.layout = org.apache.log4j.PatternLayout log4j.appender.screen.layout.ConversationPattern = „[%d] %p: %m”
Logowanie Rejestracja przykład budowy pliku konfiguracyjnego (cd.) # identycznie konfigurujemy sposób zapisywania do pliku log4j.appender.file = org.apache.log4j.RollingFileAppender log4j.appender.file.layout = org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversationPattern = „[%d] %p: %m” # zapisywać informacje będziemy w „file.log” log4j.appender.file.File = file.log # maksymalna wielkość pliku log4j.appender.file.MaxFileSize = 10KB # niech zapisuje tylko do jednego pliku log4j.appender.file.MaxBackupIndex = 1
Archiwa JAR Użytkowanie JAVA Archive archiwa JAR zawierają skompresowane pliki niezbędne doprawidłowej pracy programu • są to nie tylko pliki „*.class”, ale również pliki zawierające grafikę lub dźwięk • dzięki temu cały program mieści się w jednym archiwum tworzenie archiwów JAR: jar cvf file.jar input_files c – stwórz archiwumf – z pliku (nie z wiersza poleceń!)v – wyświetl dokładny opis0 – (zero) bez kompresji przeglądanie archiwów JAR: jar tvf file.jar t – lista zawartościf – z pliku (nie z wiersza poleceń!)v – wyświetl dokładny opis
Archiwa JAR Użytkowanie JAVA Archive wypakowywanie archiwów JAR: jar xvf file.jar [what] x – wypakujf – z pliku (nie z wiersza poleceń!)v – wyświetl dokładny opis uaktualnianie archiwów JAR: jar uvf file.jar new_files u – uaktualnijm – przy okazji uaktualnia „manifest” (są w nim przechowywane informacje o zawartości archiwum)f – z pliku (nie z wiersza poleceń!)v – wyświetl dokładny opis
Archiwa JAR Użytkowanie JAVA Archive uruchamianie archiwów JAR: jre -cp file.jar ClassName - uruchamia metodę „main” z klasy „ClassName” java -jar file.jar - wcześniej należy jednak dodać do archiwum informację o tym z której klasy będziepobierana metoda „main” np.: jar cvmf MainClassFile.conf HelloWorld.jar HelloWorld.class - gdzie plik MainClassFile.conf zawiera linijkę „Main-Class: HelloWorld.class” - stworzy to archiwum JAR o nazwie HelloWorld.jar, zawierające klasęHelloWorld.class, które można uruchomić poleceniem „java –jar”
Archiwa JAR Użytkowanie JAVA Archive istnieje możliwość użycia archiwów JAR na stronach internetowych(jako applety) - przyspieszamy tym czas pobierania plików z serwera <applet code=„HelloWorld.class” archive=„HelloWorld.jar” width=100 height=100> </applet>