wtf code @ jug.lv

34
WTF Code Andrei Solntsev jug.lv Riga, Latvia May 2011

Upload: andrei-solntsev

Post on 18-Jun-2015

1.021 views

Category:

Technology


1 download

DESCRIPTION

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

TRANSCRIPT

Page 1: WTF Code @ jug.lv

WTF Code

Andrei Solntsev

jug.lv

Riga, LatviaMay 2011

Page 2: WTF Code @ jug.lv

Обо мнеhttp://asolntsev.livejournal.comhttp://asolntsev.blogspot.com

Page 3: WTF Code @ jug.lv

Agenda

Классический говнокод

Моя коллекция

Кто виноват и что делать

Page 4: WTF Code @ jug.lv

Весь правильный код похож друг на друга,

каждый кривой код крив по-своему.

Перефразируя Достоевского

WTFC

Page 5: WTF Code @ jug.lv

Классика

«Лучшие» с сайта govnokod.ru

Например, см. исходники EHCache:net.sf.ehcache.store.MemoryStore.findEvictionCandidate()

Page 6: WTF Code @ jug.lv

Классика

• «true» - 4 символа• «false» - 5 символов

Page 7: WTF Code @ jug.lv

Классика

Page 8: WTF Code @ jug.lv

Говнокод – это код, который явно можно написатьпроще и быстрее.

А.Солнцев

Так что же такое говнокод?

Page 9: WTF Code @ jug.lv

По колено в коде!

Моя коллекция

Page 10: WTF Code @ jug.lv

Масло масляное

form.setApplicationParentTemplate(form.getParentApplicationTemplate());

... потому что масло!

Page 11: WTF Code @ jug.lv

Чистый профит

try {  Object o = null;  o.foo();  //200 строк кода}catch(NullPointerException e){  //200 строк кода}

Page 12: WTF Code @ jug.lv

Константы

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";

}

Page 13: WTF Code @ jug.lv

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

Page 14: WTF Code @ jug.lv

Be expressive

Объясняйте свой код: Имя переменной Имя метода Имя класса Имя юнит-теста (в последнюю очередь!) комментарий

Page 15: WTF Code @ jug.lv

Обработка ошибок

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’ы объявлены как константы!

Page 16: WTF Code @ jug.lv

Обработка ошибокpublic User login(String username, String password) { … 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

Page 17: WTF Code @ jug.lv

Обработка ошибок

public class LoginController{ … catch (LoginException e)  { if (e == LoginException.PASSWORD_EXPIRED) // WTF^2! { return loginNotSucceededExpiredUserPassword(…); } }

return loginNotSucceeded(…);}

Сюрприз №3: аццкая обработка

Page 18: WTF Code @ jug.lv

XML Builder

private final void init(){ m_sResponseTemplate = new StringBuilder("<response>") .append("<dttm>" + LBL_TO_REPLACE_DTTM + "</dttm>") .append("<status>" + LBL_TO_REPLACE_STATUS + "</status>") .append("<reason>" + LBL_TO_REPLACE_REASON + "</reason>") .append("<requestID>" + LBL_TO_REPLACE_REQID + "</requestID>") .append("</response>") .toString();}

Part 1/2

LBL_TO_REPLACE_DTTM = "%DTTM%";LBL_TO_REPLACE_STATUS = "%STATUS%";LBL_TO_REPLACE_REASON = "%REASON%";LBL_TO_REPLACE_REQID = "%REQID%";

Page 19: WTF Code @ jug.lv

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

Краси

во!

Page 20: WTF Code @ jug.lv

public final String initSuccessful(String sReqID) { return "<response>" +

"<dttm>" + new Date() + "</dttm>" +"<status>" + STATE_SUCCESS + "</status>" +"<reason>" + REASON_NO + "</reason>" +"<requestID>" + sReqID + "</requestID>" +"</response>";

}

Part 2/2

Прост

о!

Строк кода: 58 -> 15

XML Builder

Page 21: WTF Code @ jug.lv

Искусство программирования заключается в том, чтобы

не писать

Огюст Роденвсё, что только можно не писать.

Мессага

Спроси себя:Можно ли сделать это проще?

Page 22: WTF Code @ jug.lv

Динамика развития

boolean licenseIsMandatory = (mvr instanceof MvrDACService);

if (licenseIsMandatory && isEmpty(license)) {…

}

Всё было хорошо,

пока

девелопер не закоммитил такой фикс:

Page 23: WTF Code @ jug.lv

- boolean licenseIsMandatory = (mvr instanceof MvrDACService);+ boolean licenseIsMandatory = !(mvr instanceof MvrDACService);

if (licenseIsMandatory && isEmpty(license)) { …

}

Всё было хорошо,

пока

девелопер не закоммитил такой фикс:

Динамика развития

Page 24: WTF Code @ jug.lv

Страшные фиксы

try { nFFAddress = new Integer(sAddressID);

}

Page 25: WTF Code @ jug.lv

Страшные фиксы

try {- nFFAddress = new Integer(sAddressID);+ nFFAddress = new Integer(sAddressID.substring(8));+ // remove ADDRESS_ prefix }

Page 26: WTF Code @ jug.lv

Откуда берётся говнокод?

(студенты, индусы, спешка, демотивация, …)

Руки впереди головы

Привычки

Стремление написать красиво

Page 27: WTF Code @ jug.lv

Мессага

Не бывает красивого или некрасивого

кода!

От эстетства до педерастии – один шаг.Гоблин

Page 28: WTF Code @ jug.lv

Чем плох говнокод?

Написание кода

20%

Чтение кода

80%

review

эволюция

отладка

Работа программиста

Page 29: WTF Code @ jug.lv

Мессага

«Пишем быстро и плохо, чтобы сэкономить время»

- это САМООБМАН!

* Экономите лишь 20%, а нагружаете 80%

Page 30: WTF Code @ jug.lv

Средства борьбы с говнокодом

Self-reviewCtrl+K (IDEA)

№1

Юнит-тесты & TDDhttp://asolntsev.livejournal.com/46049.html

№2

Парное программированиеonline code review

№4

Code reviewСлишком поздно; ругать != учить

NO

Автоматическое code reviewFindBugs, PMD, IDE inspections

№3

Page 31: WTF Code @ jug.lv

The best of

protected void parseSummaryLines() { ...

// NOTE: First letters are ommited in order to // support capitalized words as well  String RESULT_GOOD_TEXT_1 = "othing"; // Nothing  String RESULT_GOOD_TEXT_2 = "uccessful";// Successful  String RESULT_BAD_TEXT_1 = "assword“; // Password  String RESULT_BAD_TEXT_2 = "failed"; // Failed

  ...}

Этот код спустился с небес!

• какмеч?• жопослово?

Page 32: WTF Code @ jug.lv

What

The

Faerie

Code!

Page 33: WTF Code @ jug.lv

Серьёзное лицо – ещё не признак ума.

Весь говнокод на земле пишется

именно с этим выражением лица.

Григорий Горин

Любите говнокод!

Улыбайтесь!

Page 34: WTF Code @ jug.lv

http://www.govnokod.ru http://lurkmore.ru/индусский_код http://funny-java.blogspot.com/ http://community.livejournal.com/programmers_fun http://community.livejournal.com/code_wtf http://indiacodingpatterns.unkur.com/

Попробуйте только не прочитайте: