60
Legacy Projects How to win the race

Legacy projects: how to win the race

Embed Size (px)

Citation preview

Legacy ProjectsHow to win the race

Legacy ProjectsHow to win the race

Technical Lead @ Infopulse UAVictor Polischuk

Many years of legacy systems reviving and refactoring experience

Loves it

E-mail:[email protected]

Skype:victor-cr

Legacy Projects History

2004

Others Java

2014

Others Java

What is……legacy projects?

Comparison Sheet

LegacyEarned a fortune

Important

Predictable

CrappyDesigned 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

Time passed

Tim

e

Because of time

Is it the ONLY reason?

Would you choose...

Shiny

DullMainstream

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 ToolsRegexp:(?ms)public\s+static\s+([^{]+).*?(?=\s+public\s+|}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) { //windowscmd = 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 forkProcess 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 AbstractParser23: 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

MindsetPrepare 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

Care not, killing

Care, not killing

Who would you trust with your most precious pet?

ConclusionsFinally

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

QuestionsThank you for attention