1 / 68

Czysty Kod

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ść

Download Presentation

Czysty Kod

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Czysty Kod Wprowadzenie Przygotował Adam Zawadzki

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

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

  4. Dług techniczny

  5. Czysty Kod Nazewnictwo

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

  7. 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); } returnlist1; }

  8. 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); return flaggedCells; }

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

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

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

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

  13. 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

  14. 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.

  15. 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.

  16. 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.

  17. 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.

  18. Czysty Kod Metody

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

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

  21. Dana funkcja powinna wykonywać operacje na jednym poziomie abstrakcji publicvoid renderAddressDataTableForPerson(Person p) AddressData[] allAddressData = getAllAddressData(); AddressData personAddresData = getPersonAddresData(p, addressData); rednerAddresDataTable(personAddresData); } private AddressData[] getAllAddressData(){ connectDatabase(); AddressData[] addressData = fetchAllAddressData(); disconnectDatabase(); return addressData; } privatevoid connectDatabase(){ /* Connect database. */ } privatevoid fetchAllAddressData(){ /* Fetch all address data from database. */ } privatevoid 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. */ }

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

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

  24. 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);

  25. Efekty uboczne publicclass UserValidator { private Cryptographer cryptographer; publicbooleancheckPassword(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(); returntrue; } } returnfalse; } }

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

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

  28. 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"); } }else{ logger.log("deleteReference from registry failed"); } }else{ logger.log("delete failed"); return E_ERROR; }

  29. 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()); }

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

  31. 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

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

  33. 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())

  34. 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: publicint 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); } return1;// we are greater because we are the right type. }

  35. Dobre komentarze Wyjaśnienia publicvoidtestCompareTo()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 }

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

  37. Dobre komentarze TODO’s //TODO-MdM these are not needed // We expect this to go away when we do the checkout model protectedVersionInfomakeVersion()throws Exception { returnnull; }

  38. 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. newListItemWidget(this,listItemContent,this.level+1); return buildList(text.substring(match.end()));

  39. Złe komentarze Mamrotanie publicvoid 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 } }

  40. Złe komentarze Zbędne komentarze // Utility method that returns when this.closed is true. Throws an exception // if the timeout is reached. publicsynchronizedvoidwaitForClose(finallongtimeoutMillis)throws Exception { if(!closed){ wait(timeoutMillis); if(!closed) thrownew Exception("MockResponseSender could not be closed"); } } }

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

  42. 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 * @paramdurationInMinutes The duration of the CD in minutes */ publicvoidaddCD(String title, String author,int tracks,intdurationInMinutes){ CD cd =new CD(); cd.title = title; cd.author = author; cd.tracks = tracks; cd.duration = duration; cdList.add(cd); }

  43. 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); */

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

  45. 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; /** The version. */ private String info;privateString info;

  46. 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

  47. 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()));

  48. Złe komentarze Komentarze HTML:

  49. Złe komentarze Informacje nie dotyczące danego fragmentu kodu: /** * Port on which fitnesse would run. Defaults to <b>8082</b>. * * @param fitnessePort */ publicvoid 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=newbyte[((this.width+1)*this.height*3)+200];

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

More Related