SlideShare a Scribd company logo
1 of 34
WTF Code Andrei Solntsev jug.lv Riga, Latvia May 2011
Обо мне http://asolntsev.livejournal.com http://asolntsev. blogspot .com
Agenda ,[object Object],[object Object],[object Object]
WTFC Весь правильный код похож друг на друга, каждый кривой код крив по-своему. Перефразируя Достоевского
Классика «Лучшие» с сайта  govnokod.ru Например, см. исходники  EHCache : net.sf.ehcache.store.MemoryStore.findEvictionCandidate()
Классика ,[object Object],[object Object]
Классика
Так что же такое говнокод? Говнокод – это код, который явно можно написать проще и быстрее. А.Солнцев
Моя коллекция По колено в коде!
Масло масляное form.set Application Parent Template( form.get Parent Application Template());  ... потому что масло!
Чистый профит try  {    Object o = null;    o.foo();    //200 строк кода } catch(NullPointerException e) {    //200 строк кода }
Константы public class Field  { private final static String  ID_APPLY_FORM_TYPE_ID_5_LABEL  =  "applyFormTypeID_5" ; private final static String  ID_APPLY_FORM_TYPE_ID_22_LABEL  =  "applyFormTypeID_22" ; }
Ещё константы 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 ; ... }
Be expressive ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Обработка ошибок class  LoginException  extends Exception { static final  LoginException   PASSWORD_EXPIRED   = new LoginException("Password expired"); static final  LoginException   INVALID_LOGIN_NAME   = new LoginException("Invalid login name"); static final  LoginException   INVALID_PASSWORD   = new LoginException("Invalid password"); } Сюрприз №1:  Exception ’ы объявлены как константы!
Обработка ошибок 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 ("Unkown …" + result); } } Сюрприз № 2 : У них неправильный  stack trace
Обработка ошибок public class  Login Controller { … catch (LoginException e)    { if ( e   ==   LoginException. PASSWORD_EXPIRED )  // WTF^2! { return  loginNotSucceededExpiredUserPassword (…); } } return loginNotSucceeded(… ); } Сюрприз № 3 : аццкая обработка
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;;
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 Красиво!
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
Искусство программирования заключается в том, чтобы не писать Огюст  Роден всё, что только можно не писать. Мессага Спроси себя: Можно ли сделать это проще ?
Динамика развития boolean  l icenseIsMandatory =  (mvr instanceof MvrDACService) ; if ( l icenseIsMandatory && isEmpty( l icense)) { … } Всё было хорошо, пока девелопер не закоммитил такой фикс:
Динамика развития -  boolean  l icenseIsMandatory =  (mvr instanceof MvrDACService) ; +  boolean  l icenseIsMandatory =  !(mvr instanceof MvrDACService) ; if ( l icenseIsMandatory && isEmpty( l icense)) {   … } Всё было хорошо, пока девелопер не закоммитил такой фикс:
Страшные фиксы try   { nFFAddress = new Integer(sAddressID); }
Страшные фиксы try   { -  nFFAddress = new Integer(sAddressID); +  nFFAddress = new Integer(sAddressID .substring(8) ); +  // remove ADDRESS_ prefix }
Откуда берётся говнокод? ,[object Object],[object Object],[object Object],[object Object]
Мессага Не бывает  красивого  или  некрасивого   кода! От эстетства до педерастии – один шаг. Гоблин
Чем плох говнокод? Написание кода 20% Чтение  кода 80% review эволюция отладка Работа программиста
Мессага «Пишем быстро и плохо, чтобы сэкономить время» - это САМООБМАН! * Экономите лишь 20%, а нагружаете 80%
Средства борьбы с говнокодом 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
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    ... }  Этот код спустился с небес ! ,[object Object],[object Object]
W hat T he F aerie Code!
Любите говнокод! Серьёзное лицо – ещё не признак ума. Весь говнокод на земле  пишется  именно с этим выражением лица. Григорий Горин Улыбайтесь!
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],Попробуйте только  не прочитайте:

More Related Content

What's hot

Методики «Inversion of Control» и «Dependency Injection». Применение в Spring.
Методики «Inversion of Control» и «Dependency Injection». Применение в Spring.Методики «Inversion of Control» и «Dependency Injection». Применение в Spring.
Методики «Inversion of Control» и «Dependency Injection». Применение в Spring.Fedor Malyshkin
 
C++ refelection and cats
C++ refelection and catsC++ refelection and cats
C++ refelection and catscorehard_by
 
Вещи в Java, о которых вы (возможно) не знали
Вещи в Java, о которых вы (возможно) не зналиВещи в Java, о которых вы (возможно) не знали
Вещи в Java, о которых вы (возможно) не зналиZheka Kozlov
 
Статический анализ и регулярные выражения
Статический анализ и регулярные выраженияСтатический анализ и регулярные выражения
Статический анализ и регулярные выраженияTatyanazaxarova
 
Илья Фофанов "Обработка ошибок в C#"
Илья Фофанов "Обработка ошибок в C#"Илья Фофанов "Обработка ошибок в C#"
Илья Фофанов "Обработка ошибок в C#"Yulia Tsisyk
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыcorehard_by
 
Статический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMergeСтатический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMergeTatyanazaxarova
 
kranonit S15 Vladimir Melnik - Ruby on Rails, BDD
kranonit S15 Vladimir Melnik - Ruby on Rails, BDDkranonit S15 Vladimir Melnik - Ruby on Rails, BDD
kranonit S15 Vladimir Melnik - Ruby on Rails, BDDKrivoy Rog IT Community
 
JavaScript Базовый. Занятие 04.
JavaScript Базовый. Занятие 04.JavaScript Базовый. Занятие 04.
JavaScript Базовый. Занятие 04.Igor Shkulipa
 
Django шахрай. версия 4
Django шахрай. версия 4Django шахрай. версия 4
Django шахрай. версия 4smikler
 
Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++Yauheni Akhotnikau
 
JavaScript: хороший тон клиентской разработки
JavaScript: хороший тон клиентской разработкиJavaScript: хороший тон клиентской разработки
JavaScript: хороший тон клиентской разработкиGetDev.NET
 
Компилируемые в реальном времени DSL для С++
Компилируемые в реальном времени DSL для С++Компилируемые в реальном времени DSL для С++
Компилируемые в реальном времени DSL для С++corehard_by
 
DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...
DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...
DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...DevPoint Kyiv
 
Статический анализ кода: современный взгляд
Статический анализ кода: современный взглядСтатический анализ кода: современный взгляд
Статический анализ кода: современный взглядAndrey Karpov
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй этоRoman Dvornov
 
Как работают оптимизации компилятора
Как работают оптимизации компилятораКак работают оптимизации компилятора
Как работают оптимизации компилятораssuserdc56a9
 

What's hot (20)

Методики «Inversion of Control» и «Dependency Injection». Применение в Spring.
Методики «Inversion of Control» и «Dependency Injection». Применение в Spring.Методики «Inversion of Control» и «Dependency Injection». Применение в Spring.
Методики «Inversion of Control» и «Dependency Injection». Применение в Spring.
 
C++ refelection and cats
C++ refelection and catsC++ refelection and cats
C++ refelection and cats
 
Вещи в Java, о которых вы (возможно) не знали
Вещи в Java, о которых вы (возможно) не зналиВещи в Java, о которых вы (возможно) не знали
Вещи в Java, о которых вы (возможно) не знали
 
Статический анализ и регулярные выражения
Статический анализ и регулярные выраженияСтатический анализ и регулярные выражения
Статический анализ и регулярные выражения
 
Илья Фофанов "Обработка ошибок в C#"
Илья Фофанов "Обработка ошибок в C#"Илья Фофанов "Обработка ошибок в C#"
Илья Фофанов "Обработка ошибок в C#"
 
Exceptions
ExceptionsExceptions
Exceptions
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтеры
 
Статический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMergeСтатический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMerge
 
kranonit S15 Vladimir Melnik - Ruby on Rails, BDD
kranonit S15 Vladimir Melnik - Ruby on Rails, BDDkranonit S15 Vladimir Melnik - Ruby on Rails, BDD
kranonit S15 Vladimir Melnik - Ruby on Rails, BDD
 
JavaScript Базовый. Занятие 04.
JavaScript Базовый. Занятие 04.JavaScript Базовый. Занятие 04.
JavaScript Базовый. Занятие 04.
 
Django шахрай. версия 4
Django шахрай. версия 4Django шахрай. версия 4
Django шахрай. версия 4
 
Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++
 
JavaScript: хороший тон клиентской разработки
JavaScript: хороший тон клиентской разработкиJavaScript: хороший тон клиентской разработки
JavaScript: хороший тон клиентской разработки
 
Ruby exceptions
Ruby exceptionsRuby exceptions
Ruby exceptions
 
Компилируемые в реальном времени DSL для С++
Компилируемые в реальном времени DSL для С++Компилируемые в реальном времени DSL для С++
Компилируемые в реальном времени DSL для С++
 
DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...
DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...
DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...
 
Статический анализ кода: современный взгляд
Статический анализ кода: современный взглядСтатический анализ кода: современный взгляд
Статический анализ кода: современный взгляд
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй это
 
How to write good autotests
How to write good autotestsHow to write good autotests
How to write good autotests
 
Как работают оптимизации компилятора
Как работают оптимизации компилятораКак работают оптимизации компилятора
Как работают оптимизации компилятора
 

Viewers also liked

The fast and the continuous - SQA Days 16
The fast and the continuous - SQA Days 16The fast and the continuous - SQA Days 16
The fast and the continuous - SQA Days 16Andrei Solntsev
 
The fast and the continuous (SeleniumCamp 2014)
The fast and the continuous (SeleniumCamp 2014)The fast and the continuous (SeleniumCamp 2014)
The fast and the continuous (SeleniumCamp 2014)Andrei Solntsev
 
Android (Devclub.eu, 30.03.2010)
Android (Devclub.eu, 30.03.2010)Android (Devclub.eu, 30.03.2010)
Android (Devclub.eu, 30.03.2010)Andrei Solntsev
 
Functional Programming Dev Club 2009 - final
Functional Programming Dev Club 2009 - finalFunctional Programming Dev Club 2009 - final
Functional Programming Dev Club 2009 - finalAndrei Solntsev
 
Static website-generators
Static website-generatorsStatic website-generators
Static website-generatorsAndrei Solntsev
 
50 оттенков play!
50 оттенков play!50 оттенков play!
50 оттенков play!Andrei Solntsev
 
Экономически эффективный процесс тестирования (Codefest 2015)
Экономически эффективный процесс тестирования (Codefest 2015)Экономически эффективный процесс тестирования (Codefest 2015)
Экономически эффективный процесс тестирования (Codefest 2015)Andrei Solntsev
 
What is master @ SeleniumConf 2015
What is master @ SeleniumConf 2015What is master @ SeleniumConf 2015
What is master @ SeleniumConf 2015Andrei Solntsev
 
Good test = simple test (with selenide)
Good test = simple test (with selenide)Good test = simple test (with selenide)
Good test = simple test (with selenide)Andrei Solntsev
 
Liquibase & Flyway @ Baltic DevOps
Liquibase & Flyway @ Baltic DevOpsLiquibase & Flyway @ Baltic DevOps
Liquibase & Flyway @ Baltic DevOpsAndrei Solntsev
 
Bullshit driven development
Bullshit driven developmentBullshit driven development
Bullshit driven developmentAndrei Solntsev
 

Viewers also liked (14)

The fast and the continuous - SQA Days 16
The fast and the continuous - SQA Days 16The fast and the continuous - SQA Days 16
The fast and the continuous - SQA Days 16
 
The fast and the continuous (SeleniumCamp 2014)
The fast and the continuous (SeleniumCamp 2014)The fast and the continuous (SeleniumCamp 2014)
The fast and the continuous (SeleniumCamp 2014)
 
Android (Devclub.eu, 30.03.2010)
Android (Devclub.eu, 30.03.2010)Android (Devclub.eu, 30.03.2010)
Android (Devclub.eu, 30.03.2010)
 
Real-life unit tests
Real-life unit testsReal-life unit tests
Real-life unit tests
 
Functional Programming Dev Club 2009 - final
Functional Programming Dev Club 2009 - finalFunctional Programming Dev Club 2009 - final
Functional Programming Dev Club 2009 - final
 
Static website-generators
Static website-generatorsStatic website-generators
Static website-generators
 
50 оттенков play!
50 оттенков play!50 оттенков play!
50 оттенков play!
 
Экономически эффективный процесс тестирования (Codefest 2015)
Экономически эффективный процесс тестирования (Codefest 2015)Экономически эффективный процесс тестирования (Codefest 2015)
Экономически эффективный процесс тестирования (Codefest 2015)
 
What is master @ SeleniumConf 2015
What is master @ SeleniumConf 2015What is master @ SeleniumConf 2015
What is master @ SeleniumConf 2015
 
Extreme banking
Extreme bankingExtreme banking
Extreme banking
 
Good test = simple test (with selenide)
Good test = simple test (with selenide)Good test = simple test (with selenide)
Good test = simple test (with selenide)
 
Liquibase & Flyway @ Baltic DevOps
Liquibase & Flyway @ Baltic DevOpsLiquibase & Flyway @ Baltic DevOps
Liquibase & Flyway @ Baltic DevOps
 
Bullshit driven development
Bullshit driven developmentBullshit driven development
Bullshit driven development
 
The Dangers of Cucumber
The Dangers of CucumberThe Dangers of Cucumber
The Dangers of Cucumber
 

Similar to WTF Code @ jug.lv

ASP.NET MVC - как построить по-настоящему гибкое веб-приложение
ASP.NET MVC - как построить по-настоящему гибкое веб-приложениеASP.NET MVC - как построить по-настоящему гибкое веб-приложение
ASP.NET MVC - как построить по-настоящему гибкое веб-приложениеAlexander Byndyu
 
основы Java переменные, циклы
основы Java   переменные, циклыосновы Java   переменные, циклы
основы Java переменные, циклыSergey Nemchinsky
 
Модульное тестирование iOS-приложений.
Модульное тестирование iOS-приложений.Модульное тестирование iOS-приложений.
Модульное тестирование iOS-приложений.MageCloud
 
анализ кода: от проверки стиля до автоматического тестирования
анализ кода: от проверки стиля до автоматического тестированияанализ кода: от проверки стиля до автоматического тестирования
анализ кода: от проверки стиля до автоматического тестированияRuslan Shevchenko
 
статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кодаAndrey Karpov
 
Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода Pavel Tsukanov
 
Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Andrey Karpov
 
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...Mail.ru Group
 
Moscow Python Conf 2016. Почему 100% покрытие это плохо?
Moscow Python Conf 2016. Почему 100% покрытие это плохо?Moscow Python Conf 2016. Почему 100% покрытие это плохо?
Moscow Python Conf 2016. Почему 100% покрытие это плохо?Ivan Tsyganov
 
PHP Tricks
PHP TricksPHP Tricks
PHP TricksBlackFan
 
Юлия Ковалёва. Fscheck — альтернативный путь для unit тестов
Юлия Ковалёва. Fscheck — альтернативный путь для unit тестовЮлия Ковалёва. Fscheck — альтернативный путь для unit тестов
Юлия Ковалёва. Fscheck — альтернативный путь для unit тестовMskDotNet Community
 
По колено в Си++ г... коде
По колено в Си++ г... кодеПо колено в Си++ г... коде
По колено в Си++ г... кодеTatyanazaxarova
 
Пояснения к статье про Copy-Paste
Пояснения к статье про Copy-PasteПояснения к статье про Copy-Paste
Пояснения к статье про Copy-PasteTatyanazaxarova
 
Оптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templatesОптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templatesPlatonov Sergey
 
Оптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templatesОптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templatesPlatonov Sergey
 

Similar to WTF Code @ jug.lv (20)

Bytecode
BytecodeBytecode
Bytecode
 
ASP.NET MVC - как построить по-настоящему гибкое веб-приложение
ASP.NET MVC - как построить по-настоящему гибкое веб-приложениеASP.NET MVC - как построить по-настоящему гибкое веб-приложение
ASP.NET MVC - как построить по-настоящему гибкое веб-приложение
 
основы Java переменные, циклы
основы Java   переменные, циклыосновы Java   переменные, циклы
основы Java переменные, циклы
 
XML Magic
XML MagicXML Magic
XML Magic
 
Модульное тестирование iOS-приложений.
Модульное тестирование iOS-приложений.Модульное тестирование iOS-приложений.
Модульное тестирование iOS-приложений.
 
анализ кода: от проверки стиля до автоматического тестирования
анализ кода: от проверки стиля до автоматического тестированияанализ кода: от проверки стиля до автоматического тестирования
анализ кода: от проверки стиля до автоматического тестирования
 
статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кода
 
Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода
 
Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?
 
Parallel STL
Parallel STLParallel STL
Parallel STL
 
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...
 
Moscow Python Conf 2016. Почему 100% покрытие это плохо?
Moscow Python Conf 2016. Почему 100% покрытие это плохо?Moscow Python Conf 2016. Почему 100% покрытие это плохо?
Moscow Python Conf 2016. Почему 100% покрытие это плохо?
 
PHP Tricks
PHP TricksPHP Tricks
PHP Tricks
 
Юлия Ковалёва. Fscheck — альтернативный путь для unit тестов
Юлия Ковалёва. Fscheck — альтернативный путь для unit тестовЮлия Ковалёва. Fscheck — альтернативный путь для unit тестов
Юлия Ковалёва. Fscheck — альтернативный путь для unit тестов
 
По колено в Си++ г... коде
По колено в Си++ г... кодеПо колено в Си++ г... коде
По колено в Си++ г... коде
 
Пояснения к статье про Copy-Paste
Пояснения к статье про Copy-PasteПояснения к статье про Copy-Paste
Пояснения к статье про Copy-Paste
 
Оптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templatesОптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templates
 
Оптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templatesОптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templates
 
Java(script) on JVM
Java(script) on JVMJava(script) on JVM
Java(script) on JVM
 
Java(Script) on JVM
Java(Script) on JVMJava(Script) on JVM
Java(Script) on JVM
 

More from Andrei Solntsev

Тройничок: Selenide для Web, Android и iOS
Тройничок: Selenide для Web, Android и iOSТройничок: Selenide для Web, Android и iOS
Тройничок: Selenide для Web, Android и iOSAndrei Solntsev
 
Flaky tests. Метод.
Flaky tests. Метод. Flaky tests. Метод.
Flaky tests. Метод. Andrei Solntsev
 
Батл: Тесты или не тесты?
Батл: Тесты или не тесты?Батл: Тесты или не тесты?
Батл: Тесты или не тесты?Andrei Solntsev
 
Как получить чёрный пояс по программированию
Как получить чёрный пояс по программированиюКак получить чёрный пояс по программированию
Как получить чёрный пояс по программированиюAndrei Solntsev
 
Selenide puzzlers @ devclub.eu
Selenide puzzlers @ devclub.euSelenide puzzlers @ devclub.eu
Selenide puzzlers @ devclub.euAndrei Solntsev
 
Liquibase: Enterprise Edition
Liquibase: Enterprise EditionLiquibase: Enterprise Edition
Liquibase: Enterprise EditionAndrei Solntsev
 
Evolutionary Database Design
Evolutionary Database DesignEvolutionary Database Design
Evolutionary Database DesignAndrei Solntsev
 
Functional Programming In Java
Functional Programming In JavaFunctional Programming In Java
Functional Programming In JavaAndrei Solntsev
 

More from Andrei Solntsev (9)

Тройничок: Selenide для Web, Android и iOS
Тройничок: Selenide для Web, Android и iOSТройничок: Selenide для Web, Android и iOS
Тройничок: Selenide для Web, Android и iOS
 
Flaky tests. Метод.
Flaky tests. Метод. Flaky tests. Метод.
Flaky tests. Метод.
 
Батл: Тесты или не тесты?
Батл: Тесты или не тесты?Батл: Тесты или не тесты?
Батл: Тесты или не тесты?
 
Как получить чёрный пояс по программированию
Как получить чёрный пояс по программированиюКак получить чёрный пояс по программированию
Как получить чёрный пояс по программированию
 
Selenide puzzlers @ devclub.eu
Selenide puzzlers @ devclub.euSelenide puzzlers @ devclub.eu
Selenide puzzlers @ devclub.eu
 
Liquibase: Enterprise Edition
Liquibase: Enterprise EditionLiquibase: Enterprise Edition
Liquibase: Enterprise Edition
 
Kiss.devclub ee.est
Kiss.devclub ee.estKiss.devclub ee.est
Kiss.devclub ee.est
 
Evolutionary Database Design
Evolutionary Database DesignEvolutionary Database Design
Evolutionary Database Design
 
Functional Programming In Java
Functional Programming In JavaFunctional Programming In Java
Functional Programming In Java
 

WTF Code @ jug.lv

  • 1. WTF Code Andrei Solntsev jug.lv Riga, Latvia May 2011
  • 2. Обо мне http://asolntsev.livejournal.com http://asolntsev. blogspot .com
  • 3.
  • 4. WTFC Весь правильный код похож друг на друга, каждый кривой код крив по-своему. Перефразируя Достоевского
  • 5. Классика «Лучшие» с сайта govnokod.ru Например, см. исходники EHCache : net.sf.ehcache.store.MemoryStore.findEvictionCandidate()
  • 6.
  • 8. Так что же такое говнокод? Говнокод – это код, который явно можно написать проще и быстрее. А.Солнцев
  • 9. Моя коллекция По колено в коде!
  • 10. Масло масляное form.set Application Parent Template( form.get Parent Application Template()); ... потому что масло!
  • 11. Чистый профит try {    Object o = null;    o.foo();    //200 строк кода } catch(NullPointerException e) {    //200 строк кода }
  • 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. Ещё константы 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.
  • 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. Обработка ошибок 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. Обработка ошибок public class Login Controller { … catch (LoginException e)   { if ( e == LoginException. PASSWORD_EXPIRED ) // WTF^2! { return loginNotSucceededExpiredUserPassword (…); } } return loginNotSucceeded(… ); } Сюрприз № 3 : аццкая обработка
  • 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. 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. 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. Искусство программирования заключается в том, чтобы не писать Огюст Роден всё, что только можно не писать. Мессага Спроси себя: Можно ли сделать это проще ?
  • 22. Динамика развития boolean l icenseIsMandatory = (mvr instanceof MvrDACService) ; if ( l icenseIsMandatory && isEmpty( l icense)) { … } Всё было хорошо, пока девелопер не закоммитил такой фикс:
  • 23. Динамика развития - boolean l icenseIsMandatory = (mvr instanceof MvrDACService) ; + boolean l icenseIsMandatory = !(mvr instanceof MvrDACService) ; if ( l icenseIsMandatory && isEmpty( l icense)) { … } Всё было хорошо, пока девелопер не закоммитил такой фикс:
  • 24. Страшные фиксы try { nFFAddress = new Integer(sAddressID); }
  • 25. Страшные фиксы try { - nFFAddress = new Integer(sAddressID); + nFFAddress = new Integer(sAddressID .substring(8) ); + // remove ADDRESS_ prefix }
  • 26.
  • 27. Мессага Не бывает красивого или некрасивого кода! От эстетства до педерастии – один шаг. Гоблин
  • 28. Чем плох говнокод? Написание кода 20% Чтение кода 80% review эволюция отладка Работа программиста
  • 29. Мессага «Пишем быстро и плохо, чтобы сэкономить время» - это САМООБМАН! * Экономите лишь 20%, а нагружаете 80%
  • 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.
  • 32. W hat T he F aerie Code!
  • 33. Любите говнокод! Серьёзное лицо – ещё не признак ума. Весь говнокод на земле пишется именно с этим выражением лица. Григорий Горин Улыбайтесь!
  • 34.

Editor's Notes

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