Legacy: как победить в гонке (Joker)

2,062 views

Published on



У вас древний проект? Все зовут его «Legacy», а вас «неудачник»? Возможно они даже смеются над вами.

Давайте взглянем на ситуацию с другого ракурса. Все (все, Карл!) успешные проекты рано или поздно превращаются в Legacy-проекты.

Я затрону тему Legacy не просто как явление, а как возможность быть постоянно в тренде, прослыть супер-спецом (даже если ты знаешь всего два фреймворка), сделать карьеру, как делать, то что ты хочешь, а не то что тебя просят. Ладно, ладно, я наврал про два фреймворка, но все остальное чистая правда. Я покажу, что вы можете творить, имея правильный подход к Legacy коду. 



Суть в том, что Legacy — это не грустно/уныло/немодно, это просто/клево/весело, если с умом подойти к задаче!

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

  • Be the first to like this

No Downloads
Views
Total views
2,062
On SlideShare
0
From Embeds
0
Number of Embeds
1,412
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Legacy: как победить в гонке (Joker)

  1. 1. Legacy Как победить в гонке
  2. 2. Технический лидер @ Infopulse Виктор Полищук Многолетний опыт воскрешения, лечения и профилактики старых систем Любит это дело E-mail: victor2@ukr.net Skype: victor-cr Twitter: @alkovictor
  3. 3. Немного Истории 2004 Другие Java 2014 Другие Java
  4. 4. Что такое… …легаси?
  5. 5. Сравнение Легаси-проект Работает Важен Предсказуем Говно-проект Сделан идиотами Стар и уныл Страшен и ужасен Неочевиден
  6. 6. Легаси Говно
  7. 7. В чем же разница? Качество выше Заказчик довольнее Стоимость выше Да, нет же разницы
  8. 8. Почему… …они появляются?
  9. 9. Идиоты Давно писали Быстро надо было Идиоты Давнописали Быстро надо было Единственная ли это причина?
  10. 10. Выберешь ли ты...
  11. 11. Хипстерский
  12. 12. Мейнстримовый Отстой
  13. 13. Ужасный проект Шаблонный проект Потом Сейчас Легаси
  14. 14. Выхода нет
  15. 15. Переписываем… …с нуля!!!
  16. 16. Что-то пошло не так?
  17. 17. Рефакторим …и страдаем
  18. 18. Правило бойскаута Обновление библиотек Автоматизация сборки Манипуляции с кодом Генерация кода Всякое-разное
  19. 19. Обновляйся
  20. 20. Кодобилдер
  21. 21. Сапоги Сапожника
  22. 22. Мои инструменты Regexp: (?ms)publics+statics+([^{]+).*?(?=s+publics+|}s+z) XSLT: <xsl:stylesheet…> <xsl:template match="/"> <beans> <xsl:apply-templates select="struts-config/action-mappings/*"/> </beans> </xsl:template> <xsl:template match="action"> <bean id="{@path}" class="{@type}"/> </xsl:template> </xsl:stylesheet>
  23. 23. Прототипируем
  24. 24. Скрипты Visio Rational Rose Power Designer
  25. 25. Приятные Мелочи
  26. 26. Dependency Injection Можно вводить частями Не ломает существующий код Упрощает интеграцию Transaction Management Потеря данных – не шутки Помогает найти причины редких невоспроизводимых багов Возможен поэтапный ввод Multi- threading Переводим на Executor-ы Запрещаем ручное создание потоков Migration Находим модули, которые можно заменить современными библиотеками Обкладываем их адаптерами Удаляем тонны кода
  27. 27. Ящик Пандоры
  28. 28. Что сделал ТЫ для того, чтобы я не увидел этого?
  29. 29. ResultSet aResultSet = null; ArrayList theAttribute1List = new ArrayList(); ArrayList theAttribute2List = new ArrayList(); … ArrayList theAttribute30List = new ArrayList(); … StringBuffer aQuery = new StringBuffer("select ") .append("ATTRIBUTE1,") .append("ATTRIBUTE2,") … while (aResultSet.next()) { if (aResultSet.getString("ATTRIBUTE1") != null) theAttribute1List.add(aResultSet.getString("ATTRIBUTE1")); … htAttributeList.put("ATTRIBUTE1", distinct(theAttribute1List)); htAttributeList.put("ATTRIBUTE2", distinct(theAttribute2List)); 010
  30. 30. Универсальный солдат...
  31. 31. public class UniversalComparator implements Comparator { … if (value1 instanceof GregorianCalendar) { GregorianCalendar lcal_obj1 = (GregorianCalendar) value1; GregorianCalendar lcal_obj2 = (GregorianCalendar) value2; boolean lb_value = lcal_obj1.before(lcal_obj2); if (ii_comparatorDirection == COMP_ASC) { if (lb_value == true) { return 1; } else { return -1; } } else { if (lb_value == true) { return -1; } else { return 1; } } } 07
  32. 32. if (value1 instanceof Boolean) { Boolean lv_obj1 = (Boolean) value1; Boolean lv_obj2 = (Boolean) value2; String ls_value1 = lv_obj1.toString(); String ls_value2 = lv_obj2.toString(); logService.debug("compare: lb_value1, lb_value2: " + ls_value1 + ", " + ls_value2); int lv_value1 = (ls_value1 == "true") ? 1 : 0; int lv_value2 = (ls_value2 == "true") ? 1 : 0; if (ii_comparatorDirection == COMP_ASC) { int val = (lv_value1 < lv_value2) ? -1 : 1; // log("val: " + val); return (lv_value1 < lv_value2) ? -1 : 1; } else return (lv_value1 < lv_value2) ? 1 : -1; } 06
  33. 33. Стандартные библиотеки??? Не, не слышал
  34. 34. private void moveFile(String from, String to) throws Exception { //move files from 'from' to 'to' String[] cmd; if (File.separator.compareTo("") == 0) { //windows cmd = new String[] {"cmd", "/c", "move", from.trim().replace("/", File.separator), to.trim().replace("/", File.separator) }; } else {//linux like, simple mv command does not work, using script cmd = new String[] {parameters.get("movePath") + ".sh", from.trim().replace("/", File.separator), to.trim().replace("/", File.separator) }; } System.gc(); //reduces current process size before fork Process p = Runtime.getRuntime().exec(cmd); p.waitFor(); p.destroy(); //free up memory } 05
  35. 35. Код ревью? Да, ну его
  36. 36. private static final List<Option> DEFAULT_OPTIONS = new ArrayList<Option>(4); { DEFAULT_OPTIONS.add(new Option(1, "Unavailable")); DEFAULT_OPTIONS.add(new Option(2, "Unidirectional")); DEFAULT_OPTIONS.add(new Option(3, "Bidirectional")); DEFAULT_OPTIONS.add(new Option(4, "Not applicable")); } 04
  37. 37. Кодга хочешь сделать надежно
  38. 38. public static void lockPartyWithLog(Party p, UnitOfWork uow) { // Local variables Party partyClone = null; // Lock the object // LOCK_NOWAIT : an exception occurs if the object is being locked try { partyClone = (Party) uow.refreshAndLockObject(p, ObjectLevelReadQuery.LOCK_NOWAIT); } catch (DatabaseException dbe) { logService.info("The party ID = " + p.getId() + " is locked by an other process"); try { Thread.currentThread().sleep(1000); } catch (Exception e) { logService.error("Thread Exception ", e); } lockPartyWithLog(p, uow); } } 03
  39. 39. Мастер-класс API дизайна
  40. 40. public interface Parser { void setReport(InputStream inputstream); void setReport(String s); String getReport(); void save(); void delete(String Query) throws HibernateException; void setParams(Map<String, String> map); Map<String, String> getParams(); void saveReport(String reportPath); Boolean isDuplicated(String fileName); } 23: public class PMScanReport extends AbstractParser 23: implements Parser { .......... 1556: } 02
  41. 41. Сравнятор!
  42. 42. public int compare(TradeConfirmation tc1, TradeConfirmation tc2) { int value; Offer o1 = (Offer) tc1.getOffer(); Offer o2 = (Offer) tc2.getOffer(); if (o1.getTradingInterval() < o2.getTradingInterval()) { value = -1; } else { if (o1.getTradingInterval() == o2.getTradingInterval()) { if (o1.getType() < o2.getType()) { value = -1; } else { if (o1.getType() == o2.getType()) { PartyDef p1 = o1.getParty().getEffectiveNow(); PartyDef p2 = o2.getParty().getEffectiveNow(); if (p1.getName().compareTo(p2.getName()) < 0) { value = -1; } else { if (p1.getName().compareTo(p2.getName()) == 0) { if (o1.getTradingZone().getEffectiveNow().getIdentification().compareTo(…) < 0) { value = -1; } else { if (o1.getTradingZone().getEffectiveNow().getIdentification().compareTo(…)) == 0) { value = 0; } else { value = 1; } } } else { value = 1; } } } else { value = 1; } } } else { value = 1; } } return value; } 01
  43. 43. Мировоззрение У нас не зомбируют
  44. 44. Закон Легаси Успешный Легаси Остальные Легаси Плохие Хорошие
  45. 45. Я не понимаю Значит это говнокод Предположения
  46. 46. Предположения Я не понимаю Это может быть говнокод
  47. 47. Ветеринарная Клиника Обычная … Вылечить нельзя, смириться … Успешная … Вылечить, нельзя смириться …
  48. 48. Кому же вы отдадите свою любимую зверюшку?
  49. 49. Итоги Подведем наконец-то
  50. 50. Легаси сплошь и рядом • Ты не сможешь спрятаться или притвориться мертвым Легаси означает успех • По-настоящему унылые вещи не живут долго Знание – сила • Люди чувствуют себя комфортнее, если проблема известна Настрой важен • Твой выбор: страдать и плакать или придумать и сделать Доверие – ключ • Ты врядли успешно закончишь работу без него
  51. 51. Вопросы Спасибо за внимание

×