WTF Code @ jug.lv

1,472 views

Published on

"WTF Code" talk at jug.lv (Riga, Latvia, May 2011)

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,472
On SlideShare
0
From Embeds
0
Number of Embeds
106
Actions
Shares
0
Downloads
9
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • 1. Про фортран и Яву; можно ещё про «через 20 лет» и Бритни 2.Если будет время – видео про числа Фибоначчи («ну, я... Эээ.... Наверное... Типа того... »)
  • Код может быть: Читаемый/нечитаемый, громоздкий/лаконичный, эффективный/неэффективный, НО НЕ красивый/некрасивый!
  • Спешка – формулировка от Гоблина « Работать быстро - значит делать медленные движения без перерывов »
  • Попить кофе, вернуться и взглянуть ещё разок на своё творение 2. 3. FindBugs, PMD, jlint , встроенные в IDE.
  • WTF Code @ jug.lv

    1. 1. WTF Code Andrei Solntsev jug.lv Riga, Latvia May 2011
    2. 2. Обо мне http://asolntsev.livejournal.com http://asolntsev. blogspot .com
    3. 3. Agenda <ul><li>Классический говнокод </li></ul><ul><li>Моя коллекция </li></ul><ul><li>Кто виноват и что делать </li></ul>
    4. 4. WTFC Весь правильный код похож друг на друга, каждый кривой код крив по-своему. Перефразируя Достоевского
    5. 5. Классика «Лучшие» с сайта govnokod.ru Например, см. исходники EHCache : net.sf.ehcache.store.MemoryStore.findEvictionCandidate()
    6. 6. Классика <ul><li>« true » - 4 символа </li></ul><ul><li>« false » - 5 символов </li></ul>
    7. 7. Классика
    8. 8. Так что же такое говнокод? Говнокод – это код, который явно можно написать проще и быстрее. А.Солнцев
    9. 9. Моя коллекция По колено в коде!
    10. 10. Масло масляное form.set Application Parent Template( form.get Parent Application Template()); ... потому что масло!
    11. 11. Чистый профит try {    Object o = null;    o.foo();    //200 строк кода } catch(NullPointerException e) {    //200 строк кода }
    12. 12. Константы public class Field { private final static String ID_APPLY_FORM_TYPE_ID_5_LABEL = &quot;applyFormTypeID_5&quot; ; private final static String ID_APPLY_FORM_TYPE_ID_22_LABEL = &quot;applyFormTypeID_22&quot; ; }
    13. 13. Ещё константы public class GapsResolver { /** Quantity of milliseconds in day. */ private final static long MILLISECONDS_PER_DAY = (long) 24 * 60 * 60 * 1000; Проблема 2012 года.  /** Quantity of milliseconds in month. */ private final static long MILLISECONDS_PER_MONTH = MILLISECONDS_PER_DAY * 31 ; /** Quantity of milliseconds in year. */ private final static long MILLISECONDS_PER_YEAR = MILLISECONDS_PER_DAY * 365 ; ... }
    14. 14. Be expressive <ul><li>Объясняйте свой код: </li></ul><ul><li>Имя переменной </li></ul><ul><li>Имя метода </li></ul><ul><li>Имя класса </li></ul><ul><li>Имя юнит-теста </li></ul><ul><li>(в последнюю очередь!) комментарий </li></ul>
    15. 15. Обработка ошибок class LoginException extends Exception { static final LoginException PASSWORD_EXPIRED = new LoginException(&quot;Password expired&quot;); static final LoginException INVALID_LOGIN_NAME = new LoginException(&quot;Invalid login name&quot;); static final LoginException INVALID_PASSWORD = new LoginException(&quot;Invalid password&quot;); } Сюрприз №1: Exception ’ы объявлены как константы!
    16. 16. Обработка ошибок public User login(String username , String p assword) { … if (result == AUTH_RESULT. PASSWORD_EXPIRED ) { throw PASSWORD_EXPIRED ; // WTF! } else if (result == AUTH_RESULT. INVALID_PASSWORD ) { throw INVALID_PASSWORD ; // WTF! } else { throw new LoginException (&quot;Unkown …&quot; + result); } } Сюрприз № 2 : У них неправильный stack trace
    17. 17. Обработка ошибок public class Login Controller { … catch (LoginException e)   { if ( e == LoginException. PASSWORD_EXPIRED ) // WTF^2! { return loginNotSucceededExpiredUserPassword (…); } } return loginNotSucceeded(… ); } Сюрприз № 3 : аццкая обработка
    18. 18. XML Builder private final void init() { m_sResponseTemplate = new StringBuilder (&quot;<response>&quot;) .append(&quot;<dttm>&quot; + LBL_TO_REPLACE_DTTM + &quot;</dttm>&quot;) .append(&quot;<status>&quot; + LBL_TO_REPLACE_STATUS + &quot;</status>&quot;) .append(&quot;<reason>&quot; + LBL_TO_REPLACE_REASON + &quot;</reason>&quot;) .append(&quot;<requestID>&quot; + LBL_TO_REPLACE_REQID + &quot;</requestID>&quot;) .append(&quot;</response>&quot;) . toString() ; } Part 1/2 LBL_TO_REPLACE_DTTM = &quot;%DTTM%&quot;; LBL_TO_REPLACE_STATUS = &quot;%STATUS%&quot;; LBL_TO_REPLACE_REASON = &quot;%REASON%&quot;; LBL_TO_REPLACE_REQID = &quot;%REQID%&quot;;
    19. 19. XML Builder public final String initSuccessful(String sReqID) { init(); return StringUtils. replace ( StringUtils. replace ( StringUtils. replace ( StringUtils. replace ( m_sResponseTemplate, LBL_TO_REPLACE_DTTM , nvl(new Date()) ) , LBL_TO_REPLACE_STATUS , STATE_SUCCESS ) , LBL_TO_REPLACE_REQID , nvl(sReqID) ) , LBL_TO_REPLACE_REASON , REASON_NO ) ; } Part 2/2 Красиво!
    20. 20. XML Builder public final String initSuccessful(String sReqID) { return &quot;<response>&quot; + &quot;<dttm>&quot; + new Date() + &quot;</dttm>&quot; + &quot;<status>&quot; + STATE_SUCCESS + &quot;</status>&quot; + &quot;<reason>&quot; + REASON_NO + &quot;</reason>&quot; + &quot;<requestID>&quot; + sReqID + &quot;</requestID>&quot; + &quot;</response>&quot;; } Part 2/2 Просто! Строк кода: 58 -> 15
    21. 21. Искусство программирования заключается в том, чтобы не писать Огюст Роден всё, что только можно не писать. Мессага Спроси себя: Можно ли сделать это проще ?
    22. 22. Динамика развития boolean l icenseIsMandatory = (mvr instanceof MvrDACService) ; if ( l icenseIsMandatory && isEmpty( l icense)) { … } Всё было хорошо, пока девелопер не закоммитил такой фикс:
    23. 23. Динамика развития - boolean l icenseIsMandatory = (mvr instanceof MvrDACService) ; + boolean l icenseIsMandatory = !(mvr instanceof MvrDACService) ; if ( l icenseIsMandatory && isEmpty( l icense)) { … } Всё было хорошо, пока девелопер не закоммитил такой фикс:
    24. 24. Страшные фиксы try { nFFAddress = new Integer(sAddressID); }
    25. 25. Страшные фиксы try { - nFFAddress = new Integer(sAddressID); + nFFAddress = new Integer(sAddressID .substring(8) ); + // remove ADDRESS_ prefix }
    26. 26. Откуда берётся говнокод? <ul><li>(студенты, индусы, спешка, демотивация, …) </li></ul><ul><li>Руки впереди головы </li></ul><ul><li>Привычки </li></ul><ul><li>Стремление написать красиво </li></ul>
    27. 27. Мессага Не бывает красивого или некрасивого кода! От эстетства до педерастии – один шаг. Гоблин
    28. 28. Чем плох говнокод? Написание кода 20% Чтение кода 80% review эволюция отладка Работа программиста
    29. 29. Мессага «Пишем быстро и плохо, чтобы сэкономить время» - это САМООБМАН! * Экономите лишь 20%, а нагружаете 80%
    30. 30. Средства борьбы с говнокодом Self-review Ctrl+K (IDEA) № 1 Юнит-тесты & TDD http://asolntsev.livejournal.com/46049.html № 2 Парное программирование online code review № 4 Code review Слишком поздно; ругать != учить NO Автоматическое code review FindBugs, PMD, IDE inspections № 3
    31. 31. The best of protected void parseSummaryLines() { ... // NOTE: First letters are ommited in order to // support capitalized words as well   String RESULT_GOOD_TEXT_1 = &quot; othing &quot;; // Nothing   String RESULT_GOOD_TEXT_2 = &quot; uccessful &quot;;// Successful   String RESULT_BAD_TEXT_1 = &quot; assword “; // Password   String RESULT_BAD_TEXT_2 = &quot; failed &quot;; // Failed   ... } Этот код спустился с небес ! <ul><li>какмеч? </li></ul><ul><li>жопослово? </li></ul>
    32. 32. W hat T he F aerie Code!
    33. 33. Любите говнокод! Серьёзное лицо – ещё не признак ума. Весь говнокод на земле пишется именно с этим выражением лица. Григорий Горин Улыбайтесь!
    34. 34. <ul><li>http://www.govnokod.ru </li></ul><ul><li>http://lurkmore.ru/ индусский_код </li></ul><ul><li>http://funny-java.blogspot.com/ </li></ul><ul><li>http://community.livejournal.com/programmers_fun </li></ul><ul><li>http://community.livejournal.com/code_wtf </li></ul><ul><li>http://indiacodingpatterns.unkur.com/ </li></ul>Попробуйте только не прочитайте:

    ×