Wprowadzenie Przygotował Adam Zawadzki

Slides:



Advertisements
Podobne prezentacje
Session 6 Case Study – Elektrim SA Saturday, January 15, 2011 SAL Wroclaw Lectures on Corporate Governance Geoffrey Mazullo Principal Emerging Markets.
Advertisements

G.Broda Helsinki 20-22, September 2010
Java Data Objects.
Projekt Do kariery na skrzydłach – studiuj Aviation Management Projekt współfinansowany ze ś rodków Europejskiego Funduszu Społecznego. Biuro projektu:
Introduction to SystemC
Usługi sieciowe Wykład 9 VPN
Statistics – what is that? Statystyka dla gimnazjalistów.
Projekt Do kariery na skrzydłach – studiuj Aviation Management Projekt współfinansowany ze ś rodków Europejskiego Funduszu Społecznego. Biuro projektu:
Analiza wywołania i przebiegu przerwań w systemie Linux


Java Server Faces Tomasz Nowak.
Projekt Do kariery na skrzydłach – studiuj Aviation Management Projekt współfinansowany ze ś rodków Europejskiego Funduszu Społecznego. Biuro projektu:
Projekt Do kariery na skrzydłach – studiuj Aviation Management Projekt współfinansowany ze ś rodków Europejskiego Funduszu Społecznego. Biuro projektu:
Projekt Do kariery na skrzydłach – studiuj Aviation Management Projekt współfinansowany ze ś rodków Europejskiego Funduszu Społecznego. Biuro projektu:
C++ w Objectivity Marcin Michalak s1744. Pomocne pakiety: Data Definition Language (DDL). Standard Template Library (STL). Active Schema.
Saint Nicolaus.
Copyright for librarians - a presentation of new education offer for librarians Agenda: The idea of the project Course content How to use an e-learning.
Materiały pochodzą z Platformy Edukacyjnej Portalu Wszelkie treści i zasoby edukacyjne publikowane na łamach Portalu
Java vs C# Michał Prządka Tomasz Nowak
OOPC++ - operatory1 Operatory class complex { private: double re, im; public: complex (double r, double i = 0) { re = r; im = i; } friend complex operator+
GUI Struktury Spotkanie integracyjne Nazwa wydziału: EAIiE Nazwa katedry: Informatyka Miejsce i data prezentacji: Kraków,
Mirosław Ochodek Sponsorzy: JFace Jak jeszcze szybciej tworzyć interfejsy? ECESIS Eclipse Community Education Project An.
Team Building Copyright, 2003 © Jerzy R. Nawrocki Requirements Engineering Lecture.
Dzielenie relacyjne / Relational Division
Łukasz Monkiewicz.
Współprogramy Plan: Motywacja Składnia Scenariusz obiektu współprogramu Przykłady Producent – konsument ( instrukcja attach ) Czytelnik -pisarze ( instukcja.
Creating Public Value Lazarski School of Commerce and Law May, 2011 Edward T. Jennings, Jr. University of Kentucky Martin School of Public Policy and Administration.
142 JAVA – sterowanie i wątki public class A20 extends javax.swing.JApplet implements ActionListener { private int licznik = 0; private JTextField t =
Aplikacje sieciowe Obiekty typu Socket. ServerSocket ClientSocket Socket ClientSocket Socket.
„Tworzenie aplikacji sieciowych w języku Java”
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego Tworzenie aplikacji sieciowych w języku Java Networking Prezentacja.
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego Tworzenie aplikacji sieciowych w języku Java Objects classes,
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego Tworzenie aplikacji sieciowych w języku Java Exceptions Prezentacja.
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego Tworzenie aplikacji sieciowych w języku Java Threads Prezentacja.
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego Tworzenie aplikacji sieciowych w języku Java Java – overview.
POLSKA SZKOŁA PODSTAWOWA IM. LECHA BĄDKOWSKIEGO W LUZINIE
Język C# Copyright, 2004 © Adam Czajka.
Przestrzeń System podstawowe klasy i klasy bazowe.
1 Building Integration System - Training Internal | ST-IST/PRM1 | 02/2008 | © Robert Bosch GmbH All rights reserved, also regarding any disposal,
Tadeusz Janasiewicz IT Group, Tadeusz Janasiewicz, WSUS, IT Group, r.
Do you know who I am? Czy wiesz kim ja jestem Soy alguien con quien convives a diario Im somebody you live with every day.. Jestem kims z kim żyjesz.
REKURENCJA.
PRZELICZNIK DŁUGOŚCI w programie NetBeans IDE autorzy: Michał Mrozek i Marcin Mrugała 2012.
Krzysztof Manuszewski
BLOOD DONATION.
Click to show the screen.
db4o Kacper Skory Marcin Talarek
PIO 2_2, Zofia Kruczkiewicz1 Wykład 2 – część druga Iteracyjno-rozwojowy cykl oprogramowania 2.
The Grumpy Test If at least one of these pictures does not make you smile, then you are grumpy and need to go back to bed. Test na ponuraka Jak nie usmiechniesz.
Podstawy licencjonowania Exchange, SharePoint oraz Lync.
Cz.8 Zdarzenia. Refleksja – przypomnienie Event Programowanie zdarzeniowe Do dzieła!
Warsztaty C# Część 2 Grzegorz Piotrowski Grupa.NET PO
Warsztaty C# Część 3 Grzegorz Piotrowski Grupa.NET PO
HTML cz.3 Tabele cd. oraz ramki
Temat 5: Elementy meta.
Teksty prymarne (original texts) to teksty autentyczne, nie są przeznaczone dla celów dydaktycznych; teksty adaptowane (simplified/adapted texts)są przystosowane.
Rozdział 3: Bezpieczeństwo w sieci opartej na systemie Windows 2000.
TROCHĘ HISTORII Marek Zając PO CO UŻYWAĆ OPENCL? Marek Zając.
Polish cadastral system Land Administration Domain Model
1.
I am sorry, but I can’t go out with you
Piotr Czapiewski Wydział Informatyki ZUT.  Extensible Markup Language  Język znaczników  Human-readable and machine-readable  Niezależny od platformy.
Struktura przedsiębiorstwa SAP Best Practices. ©2014 SAP SE or an SAP affiliate company. All rights reserved.2 Obszar rachunku kosztów 1000 Dane te są.
Poznań, , Artur Otrzonsek
POLISH FOR BEGINNERS.
2 Review What is bionomial nomenclature Explain What is a genus
Wydział Elektroniki Kierunek: AiR Zaawansowane metody programowania Wykład 6.
Wydział Elektroniki Kierunek: AiR Zaawansowane metody programowania Wykład 5.
Previously discusses: different kinds of variables
Zapis prezentacji:

Wprowadzenie Przygotował Adam Zawadzki Czysty Kod Wprowadzenie Przygotował Adam Zawadzki

Agenda Dlaczego warto dbać o na jakość kodu? Dług techniczny Nazewnictwo Metody Komentarze Formatowanie Obsługa wyjątków Klasy Zewnętrzne biblioteki

Dlaczego warto dbać o na jakość kodu? Jakosć kodu ma wpływ na prodkuktywność Jakość kodu wpływa na nasze nastawienie do pracy

Dług techniczny

Czysty Kod Nazewnictwo

Używanie innego języka niż angielski w nazewnictwie

Używaj nazw odzwierciedlających Twoje intencje public List<int[]> getThem() { List<int[]> list1 = new ArrayList<int[]>(); for (int[] x : theList) { if (x[0] == 4) list1.add(x); } return list1;

Używaj nazw odzwierciedlających Twoje intencje public List<int[]> getFlaggedCells() { List<int[]> flaggedCells = new ArrayList<int[]>(); for (int[] cell : gameBoard) if (cell[STATUS_VALUE] == FLAGGED) flaggedCells.add(cell); return flaggedCells; } public List<Cell> getFlaggedCells() { List<Cell> flaggedCells = new ArrayList<Cell>(); for (Cell cell : gameBoard) if (cell.isFlagged()) flaggedCells.add(cell);

Unikaj dezinformacji w nazewnictwie String hp; Integer aix; accountList; XYZControllerForEfficientHandlingOfStrings XYZControllerForEfficientStorageOfStrings

Znaczące rozróżnienia public static void copyChars(char a1[], char a2[]) { for (int i = 0; i < a1.length; i++) { a2[i] = a1[i]; }

Używaj nazw które da się wymówić class DtaRcrd102 { private Date genymdhms; private Date modymdhms; private final String pszqint = "102"; /* ... */ }; class Customer { private Date generationTimestamp; private Date modificationTimestamp;; private final String recordId = "102";

Unikaj prefixów public class Part { private String m_dsc; // The textual description void setName(String name) { m_dsc = name; } String description; void setDescription(String description) { this.description = description;

Nazwy klas Nazwa klasy powinna być rzeczownikiem: Customer, WikiPage, Account, AddressParser Unikaj nazw takich jak Manager, Processor, Data, or Info Nie używaj czaswoników w nazwach klas

Nazwy metod Nazwy metod wykonujacych operacje powinnt być czasownikami: deletePage, savePersistable, addToList. Metody będąco akcesorami, mutatorami lub predykatami powinny być nazywane zgodnie z konwencją java beans: get, set, is. Nie próbuj demnonstrować swojego poczucia humoru w kodzie. Jest to nieakceptowalne.

Używaj zawsze tego samego słowa dla danej koncepcji Jeżeli w danym projekcie dla akcesorów przyjęto nadawać nazwy z jednym przedrostkiem(get, fetch, retrieve) trzymaj się tej konwencji. Unikajmy mieszania koncepcji: Używając wzorca MVC nie nazywajmy klasy kontrolera: CustomerManager Nie zastępujmy końcówki Manager używając Driver Należy pamiętać że spójny słownik to ważny element czytelnego kodu.

Używaj nazw w domenie rozwiązania Czytającym Twój kod będzie inny programista Rozwiązania techniczne opisuj przy pomocy terminów technicznych: AccountVisitor, CustomerFactory, JobQueue.

Używaj nazw w domenie problemu Jeżeli projektujemy system obsługujący lotnisko to zamiast używać słowa: vehicle użyjmy słowa airplane, zamiast zlepku aSubstanceWhichKeepsAirplaneFlying użyjmy fuel Keep it simple.

Czysty Kod Metody

Funkcje muszą być małe Im dłuższa funkcja tym mniej czytelna public static String renderPageWithSetupsAndTeardowns( PageData pageData, boolean isSuite) throws Exception { if (isTestPage(pageData)) includeSetupAndTeardownPages(pageData, isSuite); return pageData.getHtml(); }

Jedna funkcja robi wyłącznie jedną rzecz w danym kontekście

Dana funkcja powinna wykonywać operacje na jednym poziomie abstrakcji public void renderAddressDataTableForPerson(Person p) AddressData[] allAddressData = getAllAddressData(); AddressData personAddresData = getPersonAddresData(p, addressData); rednerAddresDataTable(personAddresData); } private AddressData[] getAllAddressData(){ connectDatabase(); AddressData[] addressData = fetchAllAddressData(); disconnectDatabase(); return addressData; private void connectDatabase(){ /* Connect database. */ private void fetchAllAddressData(){ /* Fetch all address data from database. */ private void disconnectDatabase(){ /* Disconnect database. */ private AddressData getPersonAddresData(Person p, AddressData[] addressData){ /* Iterate over array and return address of selected person. */ private AddressData rednerAddressDataTable(AddressData addressData){ /* Render address table. */

Zasada Stepdown public void doSomething(String input){ try { doSomethingWell(input); } catch(Exception ex) { LOGGER.error(ex.getMessage(), ex); } private void doSomethingWell(String input){ /* * Do something well. */ doSomethingVeryWell(input); private void doSomethingVeryWell(String input){ * Do something very well.

Używaj opisowych nazw funkcji Nazwy muszą być jednoznaczne w danym kontekscie Nazwy muszą być spójne między sobą

Argumenty funkcji Funkcje bezargumentowe są świetne: record.remove(); Funkcje z jednym argumentem są bardzo dobre: file.save(„output”); Funkcje z dwoma argumentami są dobre: file.open(„input”, „r”); Funkcje z trzema są akceptowalne: assertEquals(message, expected, actual); Funkcje z więcej niż trzema argumentami są wstrętne i należy ich unikać. Funkje z argumentami flagowymi powinny być unikane. Łamią zasadę SPR. Listy argumentów: void monad(Integer... args); void dyad(String name, Integer... args); void triad(String name, int count, Integer... args);

Efekty uboczne public class UserValidator { private Cryptographer cryptographer; public boolean checkPassword(String userName, String password) { User user = UserGateway.findByName(userName); if (user != User.NULL) { String codedPhrase = user.getPhraseEncodedByPassword(); String phrase = cryptographer.decrypt(codedPhrase, password); if ("Valid Password".equals(phrase)) { Session.initialize(); return true; } return false;

Argumenty wyjściowe appendFooter(s); report.appendFooter();

Separuj komendy od zapytań public boolean set(String attribute, String value); if (set("username", "unclebob")){ /* ... */ } if (attributeExists("username")) { setAttribute("username", "unclebob"); //... }

Używaj wyjątków, nie kodów błędów. if (deletePage(page) == E_OK) { if (registry.deleteReference(page.name) == E_OK) { if (configKeys.deleteKey(page.name.makeKey()) == E_OK){ logger.log("page deleted"); } else { logger.log("configKey not deleted"); } logger.log("deleteReference from registry failed"); logger.log("delete failed"); return E_ERROR;

Używaj wyjątków, nie kodów błędów. try { deletePage(page); registry.deleteReference(page.name); configKeys.deleteKey(page.name.makeKey()); }catch (Exception e) { logger.log(e.getMessage()); }

Bloki try/catch public void delete(Page page) { try { deletePageAndAllReferences(page); }catch (Exception e) { logError(e); } private void deletePageAndAllReferences(Page page) throws Exception { deletePage(page); registry.deleteReference(page.name); configKeys.deleteKey(page.name.makeKey()); private void logError(Exception e) { logger.log(e.getMessage());

Dodatkowo Wydzielaj obsługę błędów. Nie duplikuj kodu. Jeżeli coś powtarza się dwa razy można z tego zrobić oddzielną funkcję. Refaktoryzuj

Komentarze. Nie sprawiają, że zły kod staje się lepszy. Czysty Kod Komentarze. Nie sprawiają, że zły kod staje się lepszy.

Wyjaśniaj za pomocą kodu // Check to see if the employee is eligible for full benefits if ((employee.flags & HOURLY_FLAG) && (employee.age > 65)) if (employee.isEligibleForFullBenefits())

Dobre komentarze Licencje Informacje: // format matched kk:mm:ss EEE, MMM dd, yyyy Pattern timeMatcher = Pattern.compile(„\\d*:\\d*:\\d* \\w*, \\w* \\d*, \\d*"); Wyjaśnienie intencji: public int compareTo(Object o) { if(o instanceof WikiPagePath) WikiPagePath p = (WikiPagePath) o; String compressedName = StringUtil.join(names, ""); String compressedArgumentName = StringUtil.join(p.names, ""); return compressedName.compareTo(compressedArgumentName); } return 1; // we are greater because we are the right type.

Dobre komentarze Wyjaśnienia public void testCompareTo() throws Exception { WikiPagePath a = PathParser.parse("PageA"); WikiPagePath ab = PathParser.parse("PageA.PageB"); WikiPagePath b = PathParser.parse("PageB"); WikiPagePath aa = PathParser.parse("PageA.PageA"); WikiPagePath bb = PathParser.parse("PageB.PageB"); WikiPagePath ba = PathParser.parse("PageB.PageA"); assertTrue(a.compareTo(a) == 0); // a == a assertTrue(a.compareTo(b) != 0); // a != b assertTrue(ab.compareTo(ab) == 0); // ab == ab assertTrue(a.compareTo(b) == -1); // a < b assertTrue(aa.compareTo(ab) == -1); // aa < ab assertTrue(ba.compareTo(bb) == -1); // ba < bb assertTrue(b.compareTo(a) == 1); // b > a assertTrue(ab.compareTo(aa) == 1); // ab > aa assertTrue(bb.compareTo(ba) == 1); // bb > ba }

Dobre komentarze Ostrzeżenia o konsekwencjach // Don't run unless you // have some time to kill. public void _testWithReallyBigFile() { writeLinesToFile(10000000); response.setBody(testFile); response.readyToSend(this); String responseString = output.toString(); assertSubString("Content-Length: 1000000000", responseString); assertTrue(bytesSent > 1000000000); }

Dobre komentarze TODO’s //TODO-MdM these are not needed // We expect this to go away when we do the checkout model protected VersionInfo makeVersion() throws Exception { return null; }

Dobre komentarze Wzmocnienia Java Docs w publicznym API String listItemContent = match.group(3).trim(); // the trim is real important. It removes the starting // spaces that could cause the item to be recognized // as another list. new ListItemWidget(this, listItemContent, this.level + 1); return buildList(text.substring(match.end()));

Złe komentarze Mamrotanie public void loadProperties() { try String propertiesPath = propertiesLocation + "/" + PROPERTIES_FILE; FileInputStream propertiesStream = new FileInputStream(propertiesPath); loadedProperties.load(propertiesStream); }catch(IOException e){ // No properties files means all defaults are loaded }

Złe komentarze Zbędne komentarze // Utility method that returns when this.closed is true. Throws an exception // if the timeout is reached. public synchronized void waitForClose(final long timeoutMillis) throws Exception { if(!closed){ wait(timeoutMillis); if(!closed) throw new Exception("MockResponseSender could not be closed"); }

Złe komentarze Zbędne komentarze public abstract class ContainerBase implements Container, Lifecycle, Pipeline, MBeanRegistration, Serializable { /** * The processor delay for this component. */ protected int backgroundProcessorDelay = -1; * The container event listeners for this Container. protected ArrayList listeners = new ArrayList(); * The Loader implementation with which this Container is * associated. protected Loader loader = null; * The Logger implementation with which this Container is protected Log logger = null; }

Złe komentarze Obowiązkowe komentarze /** * * @param title The title of the CD * @param author The author of the CD * @param tracks The number of tracks on the CD * @param durationInMinutes The duration of the CD in minutes */ public void addCD(String title, String author,int tracks, int durationInMinutes) { CD cd = new CD(); cd.title = title; cd.author = author; cd.tracks = tracks; cd.duration = duration; cdList.add(cd); }

Złe komentarze Dzienniki zmian /* * Changes (from 11-Oct-2001) * -------------------------- * 11-Oct-2001 : Re-organised the class and moved it to new package * com.jrefinery.date (DG); * 05-Nov-2001 : Added a getDescription() method, and eliminated NotableDate * class (DG); * 12-Nov-2001 : IBD requires setDescription() method, now that NotableDate * class is gone (DG); Changed getPreviousDayOfWeek(), * getFollowingDayOfWeek() and getNearestDayOfWeek() to correct bugs (DG); * 05-Dec-2001 : Fixed bug in SpreadsheetDate class (DG); * 29-May-2002 : Moved the month constants into a separate interface (MonthConstants) (DG); */

Złe komentarze Komentarze robiące zbędny szum

Złe komentarze Przerażający szum JavaDoc /** The name. */ private String name; private String name; /** The version. */ private String version; private String version; /** The licenceName. */ private String licenceName; private String licenceName; private String info; private String info;

Złe komentarze Markery pozycji : /// Actions ////////////////////////////////// Komentarze zamykające: try{ while ((line = in.readLine()) != null) { lineCount++; charCount += line.length(); String words[] = line.split("\\W"); wordCount += words.length; } //while System.out.println("wordCount = " + wordCount); System.out.println("lineCount = " + lineCount); System.out.println("charCount = " + charCount); } // try catch (IOException e) { System.err.println("Error:" + e.getMessage()); } //catch

Złe komentarze Komentarze na temat autora: // By KowalskiK@company.com Wykomentowany kod: InputStreamResponse response = new InputStreamResponse(); response.setBody(formatter.getResultStream(), formatter.getByteCount()); // InputStream resultsStream = formatter.getResultStream(); // StreamReader reader = new StreamReader(resultsStream); // response.setContent(reader.read(formatter.getByteCount()));

Złe komentarze Komentarze HTML:

Złe komentarze Informacje nie dotyczące danego fragmentu kodu: /** * Port on which fitnesse would run. Defaults to <b>8082</b>. * * @param fitnessePort */ public void setFitnessePort(int fitnessePort) { this.fitnessePort = fitnessePort; } Nie jasne komentarze: /* * start with an array that is big enough to hold all the pixels * (plus filter bytes), and an extra 200 bytes for header info this.pngBytes = new byte[((this.width + 1) * this.height * 3) + 200];

Złe komentarze JavaDoc’s w niepublicznym kodzie: /** * Method foo which is doing something; * @return int */ private int foo(String s);

Czysty Kod Formatowanie

Ogólne zasady formatowania Na danym projekcie wszyscy powinni się stosować do tych samych zasad formatowania Zawsze należy usuwać trailing spaces z kodu.

Formatowanie pionowe Im plik jest krótszy tm bardziej czytelny Kod w pliku powinien być tak ułożony, aby wspierać czytanie go z góry do dołu. Przestrzenie w pionie powinny rozdzielać różne koncepcje:

Formatowanie pionowe Zmienne powinny być deklarowane jak najbliżej miejsca w którym będą używane Funkcje zależne powinny być ułożone obok siebie Funkcje obejmujące jedna koncepcję powinny być ułożone blisko siebie

Formatowanie poziome Unikajmy ściskania kodu w poziomie Wstawiajmy spacje żeby zwiększyć czytelność kodu: public class Quadratic { public static double root1(double a, double b, double c) { double determinant = determinant(a, b, c); return (-b + Math.sqrt(determinant)) / (2*a); } public static double root2(int a, int b, int c) { return (-b - Math.sqrt(determinant)) / (2*a); private static double determinant(double a, double b, double c) { return b*b - 4*a*c;

Formatowanie poziome Unikajmy wyrównywania w poziomie:

Formatowanie poziome Wcięcia w kodzie zwiększają jego czytelność: Długość linii nie powinna przekraczać około 120 znaków

Czysty Kod Obsługa wyjątków

Jedna funkcja = jeden blok try/catch public List<RecordedGrip> retrieveSection(String sectionName) { try { FileInputStream stream = new FileInputStream(sectionName) } catch (Exception e) { throw new StorageException("retrieval error", e); } return new ArrayList<RecordedGrip>();

Z wyjątkiem dostarczaj kontekst

Nie zwracaj NULL public void registerItem(Item item) { if (item != null) { ItemRegistry registry = peristentStore.getItemRegistry(); if (registry != null) { Item existing = registry.getItem(item.getID()); if (existing.getBillingPeriod().hasRetailOwner()) { existing.register(item); }

Nie przekazuj NULL public double xProjection(Point p1, Point p2) { if (p1 == null || p2 == null) { throw InvalidArgumentException( "Invalid argument for MetricsCalculator.xProjection"); } return (p2.x – p1.x) * 1.5;

Praca z zewnętrznymi bibliotekami Czysty Kod Praca z zewnętrznymi bibliotekami

Zewnętrzne biblioteki Opakowuj zewnętrzny kod Napisz testy dla wykorzystywanych zewnętrznych funkcjonalności

Czysty Kod Klasy

Organizacja klasy Zgodnie ze standardami, na samym początku zawsze umieszczamy pola klasy. Klasa powinna udostępniać na zewnątrz tylko funkcje odpowiedzialne za realizację konkretnych zadań. Nie istotnie jest to jak je realizuje. Mechanika powinna być ukryta.

Klasy powinny być małe The Single Responsibility Principle. Nigdy nie powinien istnieć więcej niż jeden powód do zmiany klasy. Spójność. Klasy powinny mieć małą liczbę zmiennych instancyjnych. Każda metoda klasy powinna manipulować przynajmniej jedną zmienną.

Bibliografia Clean Code: A Handbook of Agile Software Craftsmanship By Robert C. Martin