Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

JavaFest. Виктор Полищук. Legacy: как победить в гонке

66 views

Published on

У вас древний проект? Все зовут его «Legacy», а вас «неудачник»? Возможно они даже смеются над вами.
Давайте взглянем на ситуацию с другого ракурса. Все (все, Карл!) успешные проекты рано или поздно превращаются в Legacy-проекты.
Я затрону тему Legacy не просто как явление, а как возможность быть постоянно в тренде, прослыть супер-спецом (даже если ты знаешь всего два фреймворка), сделать карьеру, как делать, то что ты хочешь, а не то что тебя просят. Ладно, ладно, я наврал про два фреймворка, но все остальное чистая правда. Я покажу, что вы можете творить, имея правильный подход к Legacy коду.
Суть в том, что Legacy — это не грустно/уныло/немодно, это просто/клево/весело, если с умом подойти к задаче!

Published in: Education
  • Be the first to comment

  • Be the first to like this

JavaFest. Виктор Полищук. Legacy: как победить в гонке

  1. 1. Legacy Projects How to win the race
  2. 2. Victor Polischuk Many years of legacy systems reviving and refactoring experience Loves it E-mail: victor2@ukr.net Skype: victor-cr Twitter: @alkovictor
  3. 3. Legacy Projects History 2004 Others Java 2014 Others Java
  4. 4. What is… …legacy projects?
  5. 5. Comparison Sheet Legacy Earned a fortune Important Predictable Crappy Designed by morons Boring Unmaintainable No documentation
  6. 6. Legacy Crappy
  7. 7. What is the main difference? Happy owner Better quality No difference Project cost
  8. 8. What is the main difference? Happy owner Better quality No difference Project cost
  9. 9. Why Does… …a legacy project born?
  10. 10. Time Timepassed Time Because of time Tim e Time passed Time Time Timepassed Becauseoftim e Because of time Because of time Time passed Time passed Tim e Time Time Time passed Time Tim e Timepassed Because of time Time passed Time passed Tim e Time Is it the ONLY reason?
  11. 11. You are an Architect
  12. 12. Brand new projectis waiting...
  13. 13. Would you choose...
  14. 14. Cutting Edge Shiny
  15. 15. Dull Mainstream
  16. 16. New technologies Challenge unknown Evolve You are special Boring stack Challenge patience Nothing new You are just as everyone
  17. 17. Terrible Project Clean Project In future Now Legacy
  18. 18. No escape Legacy is everywhere!
  19. 19. Rewrite… …or not?
  20. 20. 1. Specify 2. Estimate 3. Compare 4. ????? 5. Profit!!!!! Write down all requirements Each module complexity Pick reasonable bounds ????? Happy dancing
  21. 21. Failed somewhere?
  22. 22. Refactoring …cookbook
  23. 23. Boy-scout rule Libraries upgrade Build migration Code transformation Code generation Miscellaneous
  24. 24. Keep Stack Updated
  25. 25. Obsolete Let’s upgrade MigrationSanity Check Production
  26. 26. Build Health
  27. 27. Checkout / Clone Valid Artefact Test/Prod Deploy
  28. 28. Bulk Code Changes
  29. 29. Know Your Tools 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>
  30. 30. <struts-config> … <action-mappings> … <action path="/logon“ type="example.LogonAction"> <forward ... /> <exception ... /> </action> <action type="example.LogoutAction" path="/logout"/> … </action-mappings> … </struts-config> XSLT: Source
  31. 31. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <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> XSLT: Template
  32. 32. <beans> ... <bean id="/logon" class="example.LogonAction"/> <bean id="/logout" class="example.LogoutAction"/> ... </beans> XSLT: Result
  33. 33. Prototyping
  34. 34. Scripting Visio Rational Rose Power Designer
  35. 35. Script Data Model Template Engine Generated Prototype
  36. 36. Maintain Clean Code
  37. 37. 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
  38. 38. What have you done to prevent me seeing it?
  39. 39. Universal soldier...
  40. 40. 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
  41. 41. 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
  42. 42. Standard Library??? No, have never heard
  43. 43. 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
  44. 44. Code review?... WTF? 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
  45. 45. Fail of fail-over protection
  46. 46. 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
  47. 47. Master class of API design
  48. 48. 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
  49. 49. Comparatality!
  50. 50. 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
  51. 51. What Else?
  52. 52. Transaction Management Dependency Injection Mass Relocation Various Migrations
  53. 53. Mindset Prepare yourself
  54. 54. Legacy Law Successful Legacy Non-legacy Legacy Crappy Non-crappy
  55. 55. I cannot understand It is a crap Assumptions
  56. 56. I cannot understand It may be a crap Assumptions
  57. 57. Victim Warrior
  58. 58. Pet Clinic Comparison Poor Successful … Care not, killing … … Care, not killing …
  59. 59. Who would you trust with your most precious pet?
  60. 60. Conclusions Finally
  61. 61. Legacy is everywhere • You cannot hide or pretend it has nothing to do with you Legacy means success • Truly crappy things do not live long Knowledge is a weapon • People feel calm when encounter known problems Change your mindset • It is up to you: run crying or deal with it like a boss Trust is important • It also influences your freedom in decision making
  62. 62. Questions Thank you for attention

×