среда, сентября 27, 2006

Что-то там in Action

Есть серия книг типа Spring in Action, Struts in Action.
Но настоящий Struts in Action - это Еклипс + дебаггер...

вторник, сентября 26, 2006

[10:59:54 AM] Я конечно свой язык изобретать не собираюсь, но я сторонник Java-подобного языка, который сочетает в себе все возможности языка Java и необходимые свои фичи.

Вот наш общий знакомый завернул :)

среда, сентября 20, 2006

Тыщу лет таму назад...

Во фантазия у народа :)
...
private Date translateDateAfter(String strValue) {
int value = Integer.parseInt(strValue);
Date returnDate = null;
long secondsInMonth = 2592000; // number of seconds in a month

Calendar today = Calendar.getInstance();
today.set(Calendar.HOUR_OF_DAY, 0);
today.set(Calendar.MINUTE, 0);
today.set(Calendar.SECOND, 0);

switch (value) {
case StaticsDataManager.TODAY: {
returnDate = today.getTime();
break;
}
case StaticsDataManager.PREVIOUS_DAY: {
int dayOfWeek = today.get(Calendar.DAY_OF_WEEK);

if (dayOfWeek == Calendar.MONDAY)
today.add(Calendar.DAY_OF_YEAR, -3);
else if (dayOfWeek == Calendar.SUNDAY)
today.add(Calendar.DAY_OF_YEAR, -2);
else
today.add(Calendar.DAY_OF_YEAR, -1);

returnDate = today.getTime();
break;
}
case StaticsDataManager.LAST_ONE_MONTH: {
returnDate = new Date(System.currentTimeMillis()
- (secondsInMonth * 1000));
break;
}
case StaticsDataManager.LAST_THREE_MONTH: {
returnDate = new Date(System.currentTimeMillis()
- (secondsInMonth * 1000 * 3));
break;
}
case StaticsDataManager.LAST_SIX_MONTH: {
returnDate = new Date(System.currentTimeMillis()
- (secondsInMonth * 1000 * 6));
break;
}
case StaticsDataManager.ALL: {
returnDate = new Date(System.currentTimeMillis()
- (secondsInMonth * 1000 * 1000));
break;
}
}

log.info("After Date = " + returnDate);

return returnDate;
}

вторник, сентября 12, 2006

Болезнь кода или программиста?

Ну вообщем-то вот рабочий код, сделанный скорее всего по технологии "копи-паст":

/**
* Check country and state of member (need for Experian L1 auth).
* @param member
* @return
* @throws TorqueException
*/
private boolean checkTerritory(final Member member) throws TorqueException {
if (!member.getCountry().getAbbreviation().equalsIgnoreCase("US")) {
return false;
}
if (!member.getState().getAbbreviation().equals("AL")
&& !member.getState().getAbbreviation().equals("AK")
&& !member.getState().getAbbreviation().equals("AR")
&& !member.getState().getAbbreviation().equals("AZ")
&& !member.getState().getAbbreviation().equals("CA")
&& !member.getState().getAbbreviation().equals("CO")
&& !member.getState().getAbbreviation().equals("CT")
&& !member.getState().getAbbreviation().equals("DE")
&& !member.getState().getAbbreviation().equals("FL")
&& !member.getState().getAbbreviation().equals("GA")
&& !member.getState().getAbbreviation().equals("HI")
&& !member.getState().getAbbreviation().equals("ID")
&& !member.getState().getAbbreviation().equals("IL")
&& !member.getState().getAbbreviation().equals("IN")
&& !member.getState().getAbbreviation().equals("IA")
&& !member.getState().getAbbreviation().equals("KS")
&& !member.getState().getAbbreviation().equals("KY")
&& !member.getState().getAbbreviation().equals("LA")
&& !member.getState().getAbbreviation().equals("ME")
&& !member.getState().getAbbreviation().equals("MD")
&& !member.getState().getAbbreviation().equals("MA")
&& !member.getState().getAbbreviation().equals("MI")
&& !member.getState().getAbbreviation().equals("MN")
&& !member.getState().getAbbreviation().equals("MS")
&& !member.getState().getAbbreviation().equals("MO")
&& !member.getState().getAbbreviation().equals("MT")
&& !member.getState().getAbbreviation().equals("NE")
// && !member.getState().getAbbreviation().equals("NV")
&& !member.getState().getAbbreviation().equals("NH")
&& !member.getState().getAbbreviation().equals("NJ")
&& !member.getState().getAbbreviation().equals("NM")
&& !member.getState().getAbbreviation().equals("NY")
&& !member.getState().getAbbreviation().equals("NC")
&& !member.getState().getAbbreviation().equals("ND")
&& !member.getState().getAbbreviation().equals("OH")
&& !member.getState().getAbbreviation().equals("OK")
&& !member.getState().getAbbreviation().equals("OR")
&& !member.getState().getAbbreviation().equals("PA")
&& !member.getState().getAbbreviation().equals("RI")
&& !member.getState().getAbbreviation().equals("SC")
&& !member.getState().getAbbreviation().equals("SD")
&& !member.getState().getAbbreviation().equals("TN")
&& !member.getState().getAbbreviation().equals("TX")
&& !member.getState().getAbbreviation().equals("UT")
&& !member.getState().getAbbreviation().equals("VT")
&& !member.getState().getAbbreviation().equals("VA")
&& !member.getState().getAbbreviation().equals("WA")
&& !member.getState().getAbbreviation().equals("WV")
&& !member.getState().getAbbreviation().equals("WI")
&& !member.getState().getAbbreviation().equals("WY")) {
return false;
}
return true;
}

четверг, сентября 07, 2006

Основная проблемма рефакторинга.
Опытные инженеры (нетолько 'тире' программисты) говорят:
если что-то работает, то не трогай это!
Это идет вразрез с позицией Мартина Фаулера, который утверждает, что если что-то "пахнет",
то надо переделать.
ИМХО - здесь он прав:
"не тронь - не воняет".
А уж если завоняло, то как-то самому неприятно становится.
Все бы хорошо, но вот код
/**
* Formats decimal number (sum) down to cents
* @param number Number that is formatted
* @return Double formated number
*/
public static double format(final double number) {
return Double.parseDouble(String.format(new Locale("en"), "%04.2f",number));
}
из числа строку из строки в число - и все одной строкой. - "Запах" не очень приятный
А я человек чувствительный к такого рода "запахам".
Проблем возникающих в случае если делать хотябы так:
public static double format(final double number) {
return Math.round(number*100)/100;
}
я не нашел.
Но код писал явно человек знающий компьютер и языки программирования - а значит...
Ну человек разумный в конце концов. "А вдруг здесь какая-то хитрость" - подумал я.
На этом мысль застопорилось. Теперь с одной стороны "запах" - с другой "возможная хитрость".
Может кто подскажет как быть в таком случае?

вторник, сентября 05, 2006

После долгих раздумий с Разумьяном, пришли к выводу, чем отличается "враппер" от "адаптера". "Враппер" - это нормальная "обертка" для нормальных поцанов, а "адаптер" - это "обертка" для костылей.
Было найдено в инете по фразе "сломает линейку об стол"

Русский программист


Любой русский программист, после пары минут чтения кода, обязательно вскочит и произнесет, обращаясь к себе: переписать это все нафиг. Потом в нем шевельнется сомнение в том, сколько времени это займет, и остаток дня русский программист потратит на то, что будет доказывать самому себе, что это только кажется, что переписать это много работы. А если взяться и посидеть немного, то все получится. Зато код будет красивый и правильный. На следующее утро русский программист свеж, доволен собой и без единой запинки докладывает начальству, что переписать этот кусок займет один день, не больше. Да, не больше. Ну, в крайнем случае, два, если учесть все риски. В итоге начальство даст ему неделю и через полгода процесс будет успешно завершен. До той поры, пока этот код не увидит другой русский программист.

А в это время, в соседних четырех кубиках, будет ни на секунду не утихать работа китайских программистов, непостижимым образом умудряющихся прийти раньше русского программиста, уйти позже, и при этом сделать примерно втрое меньше. Эта четверка давно не пишет никакого кода, а только поддерживает код, написанный в свое время индусом, и дважды переписанный двумя разными русскими. В этом коде не просто живут баги. Здесь их гнездо. Это гнездо постоянно воспроизводит себя при помощи любимой китайской технологии реиспользования кода - copy/paste. Отсюда баги расползаются в разные стороны посредством статических переменных и переменных, переданных по ссылке (поскольку, китайский программист не может смириться с неудобствами вызванными тем, что он не может изменить значение внешней переменной переданной в его функцию модулями, которые переписывает русский программист). Вспоминая об этой функции русский программист, как правило, на время теряет дар английской речи, и переходит к какой-то помеси русского и китайского. Он давно мечтает переписать весь кусок, над которым работают китайцы, но у него нет времени.

На китайцах висят серьезные баги, о которых знает начальство и постоянно их торопит. Китайцы торопливо перевешивают баги друг на друга, поскольку знают, что попытки их починить приведут к появлению новых, еще худших. И в этом они правы. Разобраться в том, в каком порядке меняются статические переменные, и как приобретают свои значения, способен только один человек на фирме - индус. Но он пребывает в медитации. Поэтому, когда всю четверку уволят во время сокращения... А кого еще увольнять? Русский - еще не переписал свой кусок, а индус - главная ценность фирмы - он редко обращает внимание на проект, но когда обращает, все понимают, что так как он, архитектуру никто не знает. Так вот, когда китайцев увольняют, у их кода возможны две основные судьбы. Первая - он попадет к русским, и его перепишут. Вторая - он попадет к местному, канадскому программисту.

О, канадский программист это особый тип. Он, ни на минуту не задумываясь, как рыцарь без страха и упрека, бросится фиксить самый свирепый баг китайского кода. Этот Баг живет там уже три года, и китайцы уже четырежды (каждый по разу) сообщали начальству, что он пофиксен. Но Баг каждый раз возвращался, как Бетмен в свой Готхем.

Итак, канадский программист сделает то, чего китайцы не рисковали делать в течении трех долгих лет. Он, при помощи дебагера, отследит место, где статическая переменная приняла значение -1 вместо правильного 0, и решительным движением заведет рядом вторую переменную с правильным значением. Баг погибнет в неравной схватке с канадским программистом. Но победа будет достигнута тяжелой ценой. Работать перестанет все, включая только что переписанный русским программистом код. Это повергнет русского программиста в задумчивость на целых два дня, после чего он сделает, в общем-то, предсказуемый вывод о том, что дизайн с самого начала был неправильным, и все надо переписать. На это нам нужна неделя. Да, неделя, не больше.

Канадский программист смело бросится налаживать все, и станет еще хуже, хотя казалось бы... Эта суета выведет из медитации индуса, который придумает и вовсе гениальное решение - отбранчить код. Согласно его плану, мы теперь будем поддерживать две версии одного и того же кода - одну работающую, но с Багом, другую без Бага, но не работающую. Русский программист, услышав об этом плане, сломает линейку об стол и дома обзовет жену дурой, но на митинге возразить не решится.

К счастью, все это не сильно влияет на дела фирмы, поскольку продукт продается и так. Поэтому менеджмент ходит в целом довольный и не устает напоминать всем, что они отобраны как лучшие среди лучших. И что мы давно доказали свою способность выпускать продукт тем, что выпускаем его иногда.
Замыкания.
Собственно, о замыканиях тут и будет идти речь.