What Is Refactoring?
Martin Fowler
Refactoring is the process of improving the design of code without affecting its external behavior. We refactor so that our code is kept as simple as possible, ready for any change that comes along.
See Martin Fowler's book Refactoring (1999) for a full discussion of the subject.
In this chapter, we'll start with some realistic code and work our way through several refactorings. Our code will become more clear, better designed, and of higher quality.
What do we need for refactoring?
Our original code
Unit tests (to ensure we haven't unwittingly changed the code's external behavior)
A way to identify things to improve
A set of refactorings we know how to apply
A process to guide us
Original Code
The following code was designed to generate a Web page, by substituting strings for %CODE% and %ALTCODE% in a template read from a file. The code works, but a performance test showed that it is too slow; the prime reason is that it creates too many temporary strings. Once our attention is called to it, we see that this code needs a good cleanup as well.
import java.io.*; import java.util.*; /** Replace %CODE% with requested id, and ** replace %ALTCODE% w/"dashed" version of id. */ public class CodeReplacer { public final String TEMPLATE_DIR = "templatedir"; String sourceTemplate; String code; String altcode; /** * @param reqId java.lang.String * @param oStream java.io.OutputStream * @exception java.io.IOException The exception description. */ public void substitute(String reqId, PrintWriter out) throws IOException { // Read in the template file String templateDir = System.getProperty(TEMPLATE_DIR, ""); StringBuffer sb = new StringBuffer(""); try { FileReader fr = new FileReader(templateDir + "template.html"); BufferedReader br = new BufferedReader(fr); String line; while(((line=br.readLine())!="") && line!=null) sb = new StringBuffer(sb + line + "\n"); br.close(); fr.close(); } catch (Exception e) { } sourceTemplate = new String(sb); try { String template = new String(sourceTemplate); // Substitute for %CODE% int templateSplitBegin = template.indexOf("%CODE%"); int templateSplitEnd = templateSplitBegin + 6; String templatePartOne = new String( template.substring(0, templateSplitBegin)); String templatePartTwo = new String( template.substring(templateSplitEnd, template.length())); code = new String(reqId); template = new String( templatePartOne+code+templatePartTwo); // Substitute for %ALTCODE% templateSplitBegin = template.indexOf("%ALTCODE%"); templateSplitEnd = templateSplitBegin + 9; templatePartOne = new String( template.substring(0, templateSplitBegin)); templatePartTwo = new String( template.substring(templateSplitEnd, template.length())); altcode = code.substring(0,5) + "-" + code.substring(5,8); out.print(templatePartOne+altcode+templatePartTwo); } catch (Exception e) { System.out.println("Error in substitute()"); } out.flush(); out.close(); } }