Refactoring: Legacy
Who am I?
Victor Polischuk A man with a terrible character. Java architect, team leader and coach. 8+ years of software development experience. 6+ years of Java experience. Have participated in 6+ legacy projects. Have seen numbers of them. Employed in Luxoft
What is...
Short Name DescriptionThe Highlander Old, mature projects, had been written ages
ago. Paragon.
Die Hard Nobody knows why it is still alive.
Fashion Victims Nobody wants this sh%t anymore.
Problem Child Nobody loves it.
Sentenced Customer tired of supporting it, everything is up to you.
Apathetic Nobody cares.
Rewrite or refactor?
What do we need...
1.A legacy project
2.A team of developers eager to refactor it.
3.A customer convinced enough to pay for it.
4.Smart tools (IDE, RegEx, File Manager etc.)
5.Open mind
Customer vs Developer
Be Honest
Be a Friend
Do Care
Trust
Silly equals
Budget + Time Code + Time=Ignorance Risks=
Business Needs Tech Needs=
#1. Build procedure
Target Oriented Model
Each build script is unique
Low-level build instructions
No use of project information
Build flow or process issues
Project Oriented Model
Every script looks like others
High-level goals
Reuse of project information
Predefined build flow
#2. Inversion of control
Reasons
Reduce coupling.
Increase testability.
Makes further integration easier.
Everybody use it.
Attach IoC library
It is FREE!
XSLT
RegEx
Shell
Java
C#
Python
Etc
Etc
Etc
XSLT: Source
<struts-config>…<action-mappings>…<action path="/logon" type="example.LogonAction"> <forward ... /> <exception ... /></action>
<action type="example.LogoutAction" path="/logout"/>…</action-mappings>…</struts-config>
XSLT: Template
<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: Result
<beans>
...
<bean id="/logon" class="example.LogonAction"/>
<bean id="/logout" class="example.LogoutAction"/>
...
</beans>
New code
#3. Fortify defence line
Wall Old code
RegEx: Source
public class UserQuery {...public static User getUser(String userName) {…}
/** JavaDoc */private static void doSomething(Object obj) {…}
/** JavaDoc */public static void saveUser(User user) throws MagicError {…}...}
RegEx: Interface introduction
(?ms)(public\s+static\s+([^{]+).*?)(?=\s+public\s+|\}\s+\z)
public class UserQuery {...User getUser(String userName);
void saveUser(User user) throws MagicError;...}
RegEx: Delegate methods 1
void\s+(\w+)\s*\(((?:(\w+)\s+(\w+),?\s*)+)\)\s*;
void $1($2) {UserQuery.$1(<...>);}
public class UserDaoImpl implements UserDao {...User getUser(String userName);
void saveUser(User user) {UserQuery.saveUser(user);}...}
RegEx: Delegate methods 2
(\w+)\s+(\w+)\s*\(((?:(\w+)\s+(\w+),?\s*)+)\)\s*;
$1 $2($3) {return UserQuery.$2(<...>);}
public class UserDaoImpl implements UserDao {...User getUser(String userName) { return UserQuery.getUser(userName);}
void saveUser(User user) {UserQuery.saveUser(user);}...}
Integration Steps
Attach IoC container.
Convert a couple of similar classes.
Develop a concept.
Share it with the team.
#4. Transaction management
Programmatic
Full control
Low scalability
Noise in code
High mistakes probability
Declarative
Limited control
High scalability
Clean code
Rare mistakes
TransactionManager
Shall be only one ruler
rollbackcommitbegin
Programmatic TM Declarative TM
rollback
commit
begin Data Access Tier
Service Tier
UI Controller Tier
Programmatic TM Declarative TM
rollback
commit
begin get
Programmatic TM
Still Working?
Epilogue
Developer + Customer = Trust
Do you really want it?
Just DO it
Small steps
Problems only