blob: db5ba01bb806d70d8b187994e6520234328281a9 [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<org.eclipse.epf.uma:ContentDescription xmi:version="2.0"
xmlns:xmi="http://www.omg.org/XMI" xmlns:org.eclipse.epf.uma="http://www.eclipse.org/epf/uma/1.0.4/uma.ecore"
xmlns:epf="http://www.eclipse.org/epf" epf:version="1.2.0" xmi:id="-dbA7zKOJY5WPZyLXErA9vw"
name="refactoring,8.137126904637637E-306" guid="-dbA7zKOJY5WPZyLXErA9vw" changeDate="2006-11-09T19:45:22.634-0500"
version="1.0.0">
<mainDescription>&lt;h3>&#xD;
Topics&#xD;
&lt;/h3>&#xD;
&lt;ul>&#xD;
&lt;li>&#xD;
&lt;a href=&quot;#WhatIs&quot;>What is refactoring?&lt;/a>&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
&lt;a href=&quot;#Why&quot;>Why should I refactor?&lt;/a>&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
&lt;a href=&quot;#When&quot;>When should I refactor?&lt;/a>&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
&lt;a href=&quot;#Example&quot;>An example of refactoring&lt;/a>&#xD;
&lt;/li>&#xD;
&lt;/ul>&#xD;
&lt;h3>&#xD;
&lt;a id=&quot;WhatIs&quot; name=&quot;WhatIs&quot;>What is refactoring?&lt;/a>&#xD;
&lt;/h3>&#xD;
&lt;p>&#xD;
Refactoring is the act of improving the structure of a program without changing its behavior. Refactoring is done in&#xD;
tiny little steps, each barely worth doing. In between each step, we run the relevant unit tests to make sure that the&#xD;
changes we made have not broken anything. The edit/compile/test cycle is usually between 30 seconds and five minutes.&#xD;
&lt;/p>&#xD;
&lt;h3>&#xD;
&lt;a id=&quot;Why&quot; name=&quot;Why&quot;>Why should I refactor?&lt;/a>&#xD;
&lt;/h3>&#xD;
&lt;p>&#xD;
The purpose of refactoring is to improve the design and readability of the code. There are several specific goals:&#xD;
&lt;/p>&#xD;
&lt;ul>&#xD;
&lt;li>&#xD;
The code should pass all its tests.&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
It should be as expressive as it is possible for you to make it.&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
It should be as simple as it is possible for you to make it.&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
It should have no redundancy.&#xD;
&lt;/li>&#xD;
&lt;/ul>&#xD;
&lt;h3>&#xD;
&lt;a id=&quot;When&quot; name=&quot;When&quot;>When should I refactor?&lt;/a>&#xD;
&lt;/h3>&#xD;
&lt;p>&#xD;
Refactoring is not something that we schedule. There is no line item in the schedule for it. There is no particular&#xD;
time when we do it. Refactoring is done all the time. As you and your pair partner work on a task, such as writing&#xD;
tests and code, you will notice that the code and tests are not as clean and simple as they could be. That is the time&#xD;
to stop and refactor that code.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
The rule is: &lt;b>Don't let the sun set on bad code.&lt;/b>&#xD;
&lt;/p>&#xD;
&lt;h3>&#xD;
&lt;a id=&quot;Example&quot; name=&quot;Example&quot;>An Example of Refactoring&lt;/a>&#xD;
&lt;/h3>&#xD;
&lt;p>&#xD;
Consider the two unit tests and the &lt;font size=&quot;3&quot;>&lt;tt>Formatter&lt;/tt>&lt;/font> class shown below. The &lt;font size=&quot;3&quot;>&lt;tt>Formatter&lt;/tt>&lt;/font> class works but is not as expressive as I'd like it to be. So I'll refactor it in&#xD;
stages.&#xD;
&lt;/p>&#xD;
&lt;table width=&quot;100%&quot; border=&quot;1&quot;>&#xD;
&lt;tbody>&#xD;
&lt;tr>&#xD;
&lt;td>&#xD;
&lt;pre>&#xD;
public void testCenterLine()&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
{ &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
Formatter f = new Formatter(); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
f.setLineWidth(10); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
assertEquals(&quot; word &quot;, f.center(&quot;word&quot;)); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
}&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
public void testOddCenterLine() throws Exception&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
{ &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
Formatter f = new Formatter(); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
f.setLineWidth(10); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
assertEquals(&quot; hello &quot;, f.center(&quot;hello&quot;));&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
}&#xD;
&lt;/pre>&#xD;
&lt;/td>&#xD;
&lt;/tr>&#xD;
&lt;/tbody>&#xD;
&lt;/table>&lt;br />&#xD;
&lt;br />&#xD;
&lt;table width=&quot;100%&quot; border=&quot;1&quot;>&#xD;
&lt;tbody>&#xD;
&lt;tr>&#xD;
&lt;td>&#xD;
&lt;pre>&#xD;
import java.util.Arrays;&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
public class Formatter&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
{ &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
private int width; &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
private char spaces[]; &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
public void setLineWidth(int width)&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
{ &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
this.width = width; &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
spaces = new char[width]; &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
Arrays.fill(spaces, ' '); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
} &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
public String center(String line)&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
{ &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
int remainder = 0; &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
StringBuffer b = new StringBuffer(); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
int padding = (width - line.length()) / 2; &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
remainder = line.length() % 2; &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
b.append(spaces, 0, padding); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
b.append(line); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
b.append(spaces, 0, padding + remainder); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
return b.toString(); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
}&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
}&#xD;
&lt;/pre>&#xD;
&lt;/td>&#xD;
&lt;/tr>&#xD;
&lt;/tbody>&#xD;
&lt;/table>&#xD;
&lt;p>&#xD;
The &lt;font size=&quot;3&quot;>&lt;tt>setLineWidth&lt;/tt>&lt;/font> function is a little mysterious. What is this &lt;font size=&quot;3&quot;>&lt;tt>spaces&lt;/tt>&lt;/font> array and why is it being filled with blanks? By looking ahead into the &lt;font size=&quot;3&quot;>&lt;tt>center&lt;/tt>&lt;/font> function, we see that the &lt;font size=&quot;3&quot;>&lt;tt>spaces&lt;/tt>&lt;/font> array is just a&#xD;
convenience to allow us to move a number of blanks into a &lt;font size=&quot;3&quot;>&lt;tt>StringBuffer&lt;/tt>&lt;/font>. I wonder if we&#xD;
really need this convenience array.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
For the moment, I'm going to pull the initialization of the array out into its own function named &lt;font size=&quot;3&quot;>&lt;tt>buildArrayOfSpaces&lt;/tt>&lt;/font>. That way, it's all in one place, and I can think about it a little more&#xD;
clearly.&#xD;
&lt;/p>&#xD;
&lt;table width=&quot;100%&quot; border=&quot;1&quot;>&#xD;
&lt;tbody>&#xD;
&lt;tr>&#xD;
&lt;td>&#xD;
&lt;pre>&#xD;
public void setLineWidth(int width)&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
{ &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
this.width = width; &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
&lt;b>&#xD;
buildArrayOfSpaces(width);&lt;/b> &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
} &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
private void &lt;b>&#xD;
buildArrayOfSpaces(int width)&lt;/b>&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
{ &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
spaces = new char[width]; &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
Arrays.fill(spaces, ' '); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
} &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
&lt;font size=&quot;3&quot;>&#xD;
&lt;b>&#xD;
&lt;i>&#xD;
Run the tests: the tests pass&lt;/i>&lt;/b>&lt;/font>&#xD;
&lt;/pre>&#xD;
&lt;/td>&#xD;
&lt;/tr>&#xD;
&lt;/tbody>&#xD;
&lt;/table>&#xD;
&lt;p>&#xD;
I don't like the way &lt;font size=&quot;3&quot;>&lt;tt>center&lt;/tt>&lt;/font> function is constructed. There is math scattered all through&#xD;
it. I think we can rearrange the math to make things clearer.&#xD;
&lt;/p>&#xD;
&lt;table width=&quot;100%&quot; border=&quot;1&quot;>&#xD;
&lt;tbody>&#xD;
&lt;tr>&#xD;
&lt;td>&#xD;
&lt;pre>&#xD;
public String center(String line)&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
{ &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
&lt;b>&#xD;
int remainder = line.length() % 2;&lt;/b> &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
&lt;b>&#xD;
int numberOfBlanksInFront = (width - line.length()) / 2;&lt;/b> &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
&lt;b>&#xD;
int numberOfBlanksAtEnd = (width - line.length()) / 2 + remainder;&lt;/b> &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
StringBuffer b = new StringBuffer(); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
b.append(spaces, 0, &lt;b>&#xD;
numberOfBlanksInFront&lt;/b>); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
b.append(line); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
b.append(spaces, 0, &lt;b>&#xD;
numberOfBlanksAtEnd&lt;/b>); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
return b.toString(); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
}&#xD;
&lt;font size=&quot;3&quot;>&#xD;
&lt;b>&#xD;
&lt;i>&#xD;
Run the tests: the tests pass&lt;/i>&lt;/b>&lt;/font>&lt;br />&#xD;
&#xD;
&lt;/pre>&#xD;
&lt;/td>&#xD;
&lt;/tr>&#xD;
&lt;/tbody>&#xD;
&lt;/table>&#xD;
&lt;p>&#xD;
This looks good, but we can reduce the clutter by changing some of the variables into functions.&#xD;
&lt;/p>&#xD;
&lt;table width=&quot;100%&quot; border=&quot;1&quot;>&#xD;
&lt;tbody>&#xD;
&lt;tr>&#xD;
&lt;td>&#xD;
&lt;pre>&#xD;
public String center(String line)&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
{ &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
StringBuffer b = new StringBuffer(); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
b.append(spaces, 0, &lt;b>&#xD;
numberOfBlanksInFront(line)&lt;/b>); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
b.append(line); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
b.append(spaces, 0, &lt;b>&#xD;
numberOfBlanksBehind(line)&lt;/b>); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
return b.toString(); &#xD;
} &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
&lt;b>&#xD;
private int numberOfBlanksBehind(String line)&lt;/b>&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
&lt;b>&#xD;
{&lt;/b> &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
&lt;b>&#xD;
int extraBlankIfOdd = line.length() % 2;&lt;/b> &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
&lt;b>&#xD;
return (width - line.length()) / 2 + extraBlankIfOdd;&lt;/b> &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
&lt;b>&#xD;
}&lt;/b> &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
&lt;b>&#xD;
private int numberOfBlanksInFront(String line)&lt;/b>&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
&lt;b>&#xD;
{&lt;/b> &#xD;
&lt;b>&#xD;
return (width - line.length()) / 2;&lt;/b> &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
&lt;b>&#xD;
}&lt;/b> &#xD;
&lt;font size=&quot;3&quot;>&#xD;
&lt;b>&#xD;
&lt;i>&#xD;
Run the tests: the tests pass&lt;/i>&lt;/b>&lt;/font>&#xD;
&lt;/pre>&#xD;
&lt;/td>&#xD;
&lt;/tr>&#xD;
&lt;/tbody>&#xD;
&lt;/table>&#xD;
&lt;p>&#xD;
This makes the &lt;font size=&quot;3&quot;>&lt;tt>center&lt;/tt>&lt;/font> function read a little better. However, the use of the &lt;font size=&quot;3&quot;>&lt;tt>StringBuffer.append&lt;/tt>&lt;/font> function is a little confusing. We might be able to improve it a little by&#xD;
creating a more explicit function.&#xD;
&lt;/p>&#xD;
&lt;table width=&quot;100%&quot; border=&quot;1&quot;>&#xD;
&lt;tbody>&#xD;
&lt;tr>&#xD;
&lt;td>&#xD;
&lt;pre>&#xD;
public String center(String line)&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
{ &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
StringBuffer b = new StringBuffer(); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
&lt;b>&#xD;
appendBlanks(b, numberOfBlanksInFront(line));&lt;/b> &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
b.append(line); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
&lt;b>&#xD;
appendBlanks(b, numberOfBlanksBehind(line));&lt;/b> &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
return b.toString(); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
} &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
&lt;strong>&#xD;
private void appendBlanks(StringBuffer b, int numberOfBlanks)&lt;/strong>&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
&lt;strong>&#xD;
{&lt;/strong> &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
&lt;strong>&#xD;
b.append(spaces, 0, numberOfBlanks);&lt;/strong> &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
&lt;strong>&#xD;
}&lt;/strong> &#xD;
&lt;font size=&quot;3&quot;>&#xD;
&lt;b>&#xD;
&lt;i>&#xD;
Run the tests: the tests pass&lt;/i>&lt;/b>&lt;/font>&#xD;
&lt;/pre>&#xD;
&lt;/td>&#xD;
&lt;/tr>&#xD;
&lt;/tbody>&#xD;
&lt;/table>&#xD;
&lt;p>&#xD;
Now we can rewrite &lt;font size=&quot;3&quot;>&lt;tt>appendBlanks&lt;/tt>&lt;/font> to avoid using the &lt;font size=&quot;3&quot;>&lt;tt>spaces&lt;/tt>&lt;/font>&#xD;
array.&#xD;
&lt;/p>&#xD;
&lt;table width=&quot;100%&quot; border=&quot;1&quot;>&#xD;
&lt;tbody>&#xD;
&lt;tr>&#xD;
&lt;td>&#xD;
&lt;pre>&#xD;
import java.util.Arrays; &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
public class Formatter&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
{ &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
private int width; &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
public void setLineWidth(int width)&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
{ &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
this.width = width; &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
} &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
public String center(String line)&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
{ &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
StringBuffer b = new StringBuffer(); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
appendBlanks(b, numberOfBlanksInFront(line)); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
b.append(line); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
appendBlanks(b, numberOfBlanksBehind(line)); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
return b.toString(); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
} &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
private void appendBlanks(StringBuffer b, int numberOfBlanks)&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
{&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
&lt;b>&#xD;
while(numberOfBlanks-- &amp;gt; 0)&lt;/b> &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
&lt;b>&#xD;
b.append(' ');&lt;/b> &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
} &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
private int numberOfBlanksBehind(String line)&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
{ &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
int extraBlankIfOdd = line.length() % 2; &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
return (width - line.length()) / 2 + extraBlankIfOdd; &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
} &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
private int numberOfBlanksInFront(String line)&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
{ &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
return (width - line.length()) / 2; } &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
} &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
}&lt;font size=&quot;3&quot;>&#xD;
&lt;b>&#xD;
&lt;i>&#xD;
Run the tests: the tests pass&lt;/i>&lt;/b>&lt;/font>&lt;br />&#xD;
&#xD;
&lt;/pre>&#xD;
&lt;/td>&#xD;
&lt;/tr>&#xD;
&lt;/tbody>&#xD;
&lt;/table>&#xD;
&lt;p>&#xD;
The names of functions like &lt;font size=&quot;3&quot;>&lt;tt>numberOfBlanksBehind&lt;/tt>&lt;/font> imply that the reader knows that these&#xD;
will be called from the &lt;font size=&quot;3&quot;>&lt;tt>center&lt;/tt>&lt;/font> function. We should eliminate this implication by&#xD;
renaming those functions.&#xD;
&lt;/p>&#xD;
&lt;table width=&quot;100%&quot; border=&quot;1&quot;>&#xD;
&lt;tbody>&#xD;
&lt;tr>&#xD;
&lt;td>&#xD;
&lt;pre>&#xD;
import java.util.Arrays;&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
public class Formatter &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
{ &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
private int width; &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
public void setLineWidth(int width)&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
{ &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
this.width = width; &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
} &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
public String center(String line)&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
{ &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
StringBuffer b = new StringBuffer(); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
appendBlanks(b, &lt;b>&#xD;
numberOfBlanksToLeftOfCenter&lt;/b>(line)); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
b.append(line); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
appendBlanks(b, &lt;b>&#xD;
numberOfBlanksToRightOfCenter&lt;/b>(line)); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
return b.toString(); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
} &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
private void appendBlanks(StringBuffer b, int numberOfBlanks)&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
{ &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
while(numberOfBlanks-- &amp;gt; 0) &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
b.append(' '); &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
} &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
private int &lt;b>&#xD;
numberOfBlanksToRightOfCenter&lt;/b>(String line)&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
{ &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
int extraBlankIfOdd = line.length() % 2; &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
return (width - line.length()) / 2 + extraBlankIfOdd; &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
} &#xD;
&#xD;
private int &lt;b>&#xD;
numberOfBlanksToLeftOfCenter&lt;/b>(String line)&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
{ &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
return (width - line.length()) / 2; &#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
}&#xD;
&lt;/pre>&#xD;
&lt;pre>&#xD;
} &#xD;
&lt;font size=&quot;3&quot;>&#xD;
&lt;b>&#xD;
&lt;i>&#xD;
Run the tests: the tests pass&lt;/i>&lt;/b>&lt;/font>&#xD;
&lt;/pre>&#xD;
&lt;/td>&#xD;
&lt;/tr>&#xD;
&lt;/tbody>&#xD;
&lt;/table>&#xD;
&lt;p>&#xD;
And I think we are done. You might find other refactorings to do, or you might not agree with all of the refactorings&#xD;
I've done. That's to be expected. The point is, however, that I have put a lot of effort into the readability and&#xD;
simplicity of this class. That effort will help others understand this class and make it easier for them to change the&#xD;
class when the time comes.&#xD;
&lt;/p></mainDescription>
</org.eclipse.epf.uma:ContentDescription>