SlideShare a Scribd company logo
Legacy Projects
How to win the race
Legacy Projects
How to win the race
TechnicalLead@ InfopulseUA
Victor Polischuk
Many years of legacy systems reviving
and refactoring experience
Loves it
E-mail:
victor2@ukr.net
Skype:
victor-cr
Legacy Projects History
2004
Others Java
2014
Others Java
What is…
…legacy projects?
Comparison Sheet
Legacy
Earned a fortune
Important
Predictable
Crappy
Designed by morons
Boring
Unmaintainable
No documentation
Legacy
Crappy
What is the main difference?
Happy owner
Better quality
No difference
Project cost
What is the main difference?
Happy owner
Better quality
No difference
Project cost
Why Does…
…a legacy project born?
Time passed
Time
Because of time
Timepassed
Time
Because of time
Is it the ONLY reason?
Would you choose...
Shiny
Dull
Mainstream
Terrible
Project
Clean
Project
In future Now
Legacy
No escape
ReWRite…
…or not?
Failed somewhere?
Refactoring
…cookbook
Boy-scout rule
Libraries
upgrade
Build migration
Code
transformation
Code generation
Miscellaneous
Keep Stack Updated
Build Health
Bulk Code Changes
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>
Prototyping
Scripting
Visio
Rational
Rose
Power
Designer
Maintain Clean Code
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
What have you done to prevent me seeing it?
Universal soldier...
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
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
JavaDoc... No, have never heard
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
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
Fail of fail-over protection
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
Master class of API design
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
Fatality!
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
What Else?
Transaction Management
Dependency Injection
Mass Relocation
Various Migrations
Mindset
Prepare yourself
Legacy Law
Successful
Legacy Non-legacy
Legacy
Crappy Non-crappy
I cannot understand
It is a crap
Assumptions
I cannot understand
It may be a crap
Assumptions
Pet Clinic Comparison
Poor Successful
…
Carenot, killing
…
…
Care, not killing
…
Who would you trust with
your most precious pet?
Conclusions
Finally
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
Questions
Thank you for attention

More Related Content

What's hot

Dzanan_Bajgoric_C2CUDA_MscThesis_Present
Dzanan_Bajgoric_C2CUDA_MscThesis_PresentDzanan_Bajgoric_C2CUDA_MscThesis_Present
Dzanan_Bajgoric_C2CUDA_MscThesis_Present
Džanan Bajgorić
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event Systems
Leonardo Borges
 
Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011
Anton Arhipov
 

What's hot (20)

Actor Concurrency
Actor ConcurrencyActor Concurrency
Actor Concurrency
 
Hidden in Plain Sight: DUAL_EC_DRBG 'n stuff
Hidden in Plain Sight: DUAL_EC_DRBG 'n stuffHidden in Plain Sight: DUAL_EC_DRBG 'n stuff
Hidden in Plain Sight: DUAL_EC_DRBG 'n stuff
 
Virtual machine and javascript engine
Virtual machine and javascript engineVirtual machine and javascript engine
Virtual machine and javascript engine
 
Kotlin: forse è la volta buona (Trento)
Kotlin: forse è la volta buona (Trento)Kotlin: forse è la volta buona (Trento)
Kotlin: forse è la volta buona (Trento)
 
RealmDB for Android
RealmDB for AndroidRealmDB for Android
RealmDB for Android
 
Kotlin meets Gadsu
Kotlin meets GadsuKotlin meets Gadsu
Kotlin meets Gadsu
 
The Ring programming language version 1.6 book - Part 184 of 189
The Ring programming language version 1.6 book - Part 184 of 189The Ring programming language version 1.6 book - Part 184 of 189
The Ring programming language version 1.6 book - Part 184 of 189
 
Kotlin 101 for Java Developers
Kotlin 101 for Java DevelopersKotlin 101 for Java Developers
Kotlin 101 for Java Developers
 
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
 
Non-blocking Michael-Scott queue algorithm
Non-blocking Michael-Scott queue algorithmNon-blocking Michael-Scott queue algorithm
Non-blocking Michael-Scott queue algorithm
 
Deuce STM - CMP'09
Deuce STM - CMP'09Deuce STM - CMP'09
Deuce STM - CMP'09
 
Dzanan_Bajgoric_C2CUDA_MscThesis_Present
Dzanan_Bajgoric_C2CUDA_MscThesis_PresentDzanan_Bajgoric_C2CUDA_MscThesis_Present
Dzanan_Bajgoric_C2CUDA_MscThesis_Present
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error Examples
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event Systems
 
Java Concurrency Idioms
Java Concurrency IdiomsJava Concurrency Idioms
Java Concurrency Idioms
 
How Data Flow analysis works in a static code analyzer
How Data Flow analysis works in a static code analyzerHow Data Flow analysis works in a static code analyzer
How Data Flow analysis works in a static code analyzer
 
​"Delegates, Delegates everywhere" Владимир Миронов
​"Delegates, Delegates everywhere" Владимир Миронов​"Delegates, Delegates everywhere" Владимир Миронов
​"Delegates, Delegates everywhere" Владимир Миронов
 
Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011
 
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloadingJEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
 
Modern c++ Memory Management
Modern c++ Memory ManagementModern c++ Memory Management
Modern c++ Memory Management
 

Similar to Legacy projects: how to win the race

ADG Poznań - Kotlin for Android developers
ADG Poznań - Kotlin for Android developersADG Poznań - Kotlin for Android developers
ADG Poznań - Kotlin for Android developers
Bartosz Kosarzycki
 

Similar to Legacy projects: how to win the race (20)

JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
 
4Developers 2018: Ile (nie) wiesz o strukturach w .NET (Łukasz Pyrzyk)
4Developers 2018: Ile (nie) wiesz o strukturach w .NET (Łukasz Pyrzyk)4Developers 2018: Ile (nie) wiesz o strukturach w .NET (Łukasz Pyrzyk)
4Developers 2018: Ile (nie) wiesz o strukturach w .NET (Łukasz Pyrzyk)
 
Big Data Scala by the Bay: Interactive Spark in your Browser
Big Data Scala by the Bay: Interactive Spark in your BrowserBig Data Scala by the Bay: Interactive Spark in your Browser
Big Data Scala by the Bay: Interactive Spark in your Browser
 
Kotlin / Android Update
Kotlin / Android UpdateKotlin / Android Update
Kotlin / Android Update
 
掀起 Swift 的面紗
掀起 Swift 的面紗掀起 Swift 的面紗
掀起 Swift 的面紗
 
Reactive Qt - Ivan Čukić (Qt World Summit 2015)
Reactive Qt - Ivan Čukić (Qt World Summit 2015)Reactive Qt - Ivan Čukić (Qt World Summit 2015)
Reactive Qt - Ivan Čukić (Qt World Summit 2015)
 
IL2CPP: Debugging and Profiling
IL2CPP: Debugging and ProfilingIL2CPP: Debugging and Profiling
IL2CPP: Debugging and Profiling
 
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
 
The TclQuadcode Compiler
The TclQuadcode CompilerThe TclQuadcode Compiler
The TclQuadcode Compiler
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
 
Second Level Cache in JPA Explained
Second Level Cache in JPA ExplainedSecond Level Cache in JPA Explained
Second Level Cache in JPA Explained
 
Introduction to-java
Introduction to-javaIntroduction to-java
Introduction to-java
 
Mining Branch-Time Scenarios From Execution Logs
Mining Branch-Time Scenarios From Execution LogsMining Branch-Time Scenarios From Execution Logs
Mining Branch-Time Scenarios From Execution Logs
 
Rx workshop
Rx workshopRx workshop
Rx workshop
 
The things we don't see – stories of Software, Scala and Akka
The things we don't see – stories of Software, Scala and AkkaThe things we don't see – stories of Software, Scala and Akka
The things we don't see – stories of Software, Scala and Akka
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup Edinburgh
 
Swift rocks! #1
Swift rocks! #1Swift rocks! #1
Swift rocks! #1
 
ADG Poznań - Kotlin for Android developers
ADG Poznań - Kotlin for Android developersADG Poznań - Kotlin for Android developers
ADG Poznań - Kotlin for Android developers
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)
 
Silicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsSilicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM Mechanics
 

More from Victor_Cr

Jboss drools expert (ru)
Jboss drools expert (ru)Jboss drools expert (ru)
Jboss drools expert (ru)
Victor_Cr
 
JEEConf JBoss Drools
JEEConf JBoss DroolsJEEConf JBoss Drools
JEEConf JBoss Drools
Victor_Cr
 
JBoss Drools
JBoss DroolsJBoss Drools
JBoss Drools
Victor_Cr
 

More from Victor_Cr (14)

Data Wars: The Bloody Enterprise strikes back
Data Wars: The Bloody Enterprise strikes backData Wars: The Bloody Enterprise strikes back
Data Wars: The Bloody Enterprise strikes back
 
Data Wars: The Bloody Enterprise strikes back
Data Wars: The Bloody Enterprise strikes backData Wars: The Bloody Enterprise strikes back
Data Wars: The Bloody Enterprise strikes back
 
Type War: Weak vs Strong [JEEConf 2016]
Type War: Weak vs Strong [JEEConf 2016]Type War: Weak vs Strong [JEEConf 2016]
Type War: Weak vs Strong [JEEConf 2016]
 
Types: Weak/Duck/Optional vs Strong/Strict. Let the War Begin!
Types: Weak/Duck/Optional vs Strong/Strict. Let the War Begin!Types: Weak/Duck/Optional vs Strong/Strict. Let the War Begin!
Types: Weak/Duck/Optional vs Strong/Strict. Let the War Begin!
 
Types: Weak/Duck/Optional vs Strong/Strict. Let the War Begin!
Types: Weak/Duck/Optional vs Strong/Strict. Let the War Begin!Types: Weak/Duck/Optional vs Strong/Strict. Let the War Begin!
Types: Weak/Duck/Optional vs Strong/Strict. Let the War Begin!
 
Legacy: как победить в гонке (Joker)
Legacy: как победить в гонке (Joker)Legacy: как победить в гонке (Joker)
Legacy: как победить в гонке (Joker)
 
Web-application I’ve always dreamt of (Kharkiv)
Web-application I’ve always dreamt of (Kharkiv)Web-application I’ve always dreamt of (Kharkiv)
Web-application I’ve always dreamt of (Kharkiv)
 
Web application I have always dreamt of (Lviv)
Web application I have always dreamt of (Lviv)Web application I have always dreamt of (Lviv)
Web application I have always dreamt of (Lviv)
 
Web application I have always dreamt of
Web application I have always dreamt ofWeb application I have always dreamt of
Web application I have always dreamt of
 
Jboss drools expert (ru)
Jboss drools expert (ru)Jboss drools expert (ru)
Jboss drools expert (ru)
 
JEEConf WEB
JEEConf WEBJEEConf WEB
JEEConf WEB
 
JEEConf JBoss Drools
JEEConf JBoss DroolsJEEConf JBoss Drools
JEEConf JBoss Drools
 
JBoss Drools
JBoss DroolsJBoss Drools
JBoss Drools
 
XPDays Ukraine: Legacy
XPDays Ukraine: LegacyXPDays Ukraine: Legacy
XPDays Ukraine: Legacy
 

Recently uploaded

Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisProviding Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Globus
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns
 

Recently uploaded (20)

Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
Software Testing Exam imp Ques Notes.pdf
Software Testing Exam imp Ques Notes.pdfSoftware Testing Exam imp Ques Notes.pdf
Software Testing Exam imp Ques Notes.pdf
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
 
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
 
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...
 
Designing for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web ServicesDesigning for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web Services
 
Understanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSageUnderstanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSage
 
Using IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandUsing IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New Zealand
 
De mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEDe mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FME
 
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisProviding Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
 
Corporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMSCorporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMS
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
 
Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...
Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...
Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdf
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
 

Legacy projects: how to win the race

  • 1. Legacy Projects How to win the race
  • 2. Legacy Projects How to win the race
  • 3. TechnicalLead@ InfopulseUA Victor Polischuk Many years of legacy systems reviving and refactoring experience Loves it E-mail: victor2@ukr.net Skype: victor-cr
  • 4. Legacy Projects History 2004 Others Java 2014 Others Java
  • 6. Comparison Sheet Legacy Earned a fortune Important Predictable Crappy Designed by morons Boring Unmaintainable No documentation
  • 8. What is the main difference? Happy owner Better quality No difference Project cost
  • 9. What is the main difference? Happy owner Better quality No difference Project cost
  • 10. Why Does… …a legacy project born?
  • 11. Time passed Time Because of time Timepassed Time Because of time Is it the ONLY reason?
  • 12.
  • 13.
  • 15. Shiny
  • 17.
  • 21.
  • 26.
  • 28.
  • 30. 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>
  • 33.
  • 35. 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
  • 36. What have you done to prevent me seeing it?
  • 38. 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
  • 39. 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
  • 40. JavaDoc... No, have never heard
  • 41. 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
  • 42. 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
  • 43. Fail of fail-over protection
  • 44. 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
  • 45. Master class of API design
  • 46. 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
  • 48. 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
  • 50. Transaction Management Dependency Injection Mass Relocation Various Migrations
  • 53. I cannot understand It is a crap Assumptions
  • 54. I cannot understand It may be a crap Assumptions
  • 55.
  • 56. Pet Clinic Comparison Poor Successful … Carenot, killing … … Care, not killing …
  • 57. Who would you trust with your most precious pet?
  • 59. 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

Editor's Notes

  1. Боль
  2. Больная тема. Хотел бы дать живые примеры, но...
  3. 10 лет
  4. Легаси код против грязного кода, можете перевести дословно, я не могу, меня наругают
  5. Ортогональные вещи Как на самом деле?
  6. Чем выделяется легаси на фоне грязи... Довольный владелец, качеством, ничем, стоимостью... И-и-и-и-и-и....
  7. Довольным, но хотящим большего.
  8. Есть идеи как они появляются на свет? Не обращая внимания на картинку... Ну был проект как проект, а тут бац и легаси... Многие из вас наверное скажут...
  9. Так ли это? Определяющая ли это причина...
  10. Ульта-модные «мотивирующие» библиотеки и фреймворки
  11. Грустный и унылый мейнстрим...
  12. Бросить вызов неизведанному или испытывать свое терпение? Кто за левую часть?
  13. То как я определяю для себя и своей команды...