Removing Duplication


It s late in the evening, and I m getting tired . I want to make a little more progress before I call it quits, so I ll do something very simple. Normally I would try something bigger, probably unwisely. See the following two loops that go over the lines up to cursorLine, adding up their lengths? I m going to remove that duplication.

 private int NewParaSelectionStart(int cursorLine) { 
int length = 0;
for (int i = 0; i < cursorLine; i++) length += ((String)lines[i]).Length + Environment.NewLine.Length;
return length + "<p>".Length;
}

private int NewSectionSelectionStart(int cursorLine) {
int length = 0;
for (int i = 0; i < cursorLine; i++) length += ((String)lines[i]).Length + Environment.NewLine.Length;
return length + "<sect1><title>".Length;
}

The result looks like this:

 private int NewSectionSelectionStart(int cursorLine) { 
return SumLineLengths(cursorLine) + "<sect1><title>".Length;
}
private int SumLineLengths(int cursorLine) {
int length = 0;
for (int i = 0; i < cursorLine; i++) length += ((String)lines[i]).Length + Environment.NewLine.Length; return length;
}

I just extracted the loop code into a new method, SumLineLengths(), and used it in NewSectionSelectionStart. I ran the tests and they work. Now I ll use the method in the other location:

 private int NewParaSelectionStart(int cursorLine) { 
return SumLineLengths(cursorLine) + "<p>".Length;
}

The tests still work ”wahoo! The code is a little bit nicer. This gives me an idea. Look at those two methods ”they are almost completely duplicated except for the string. Recall how they re used. Here s one example:

 public void InsertSectionTags() { 
if ( lines.Count == 0 ) {
lines.Add( "<sect1><title></title>" );
lines.Add( "</sect1>");
selectionStart = 14;
return;
}
lines.InsertRange(LineContainingCursor()+1, NewSection());
selectionStart = NewSectionSelectionStart(LineContainingCursor() + 1);
}

The other usage looks the same except that it calls NewParaSelectionStart. Let s consolidate those two methods by passing in the string as a parameter from the methods that use them. This is a common situation in removing duplication: we extract the common elements to a method that takes one or more parameters, and we leave the parameters ”the differences ”in the code that uses the new method. In this case, our calling methods know that string anyway, so let s put all knowledge of it in the callers :

 public void InsertSectionTags() { 
if ( lines.Count == 0 ) {
lines.Add( "<sect1><title></title>" );
lines.Add( "</sect1>");
selectionStart = 14;
return;
}
lines.InsertRange(LineContainingCursor()+1, NewSection());
selectionStart = NewSelectionStart(LineContainingCursor() + 1,
" < sect1 >< title > ");
}

And NewSelectionStart gets the obvious implementation:

  private int NewSelectionStart(int cursorLine, string tags) {    return SumLineLengths(cursorLine) + tags.Length;     }  

Tests run! Now I ll use that same method in the paragraph code:

 public void InsertParagraphTag() { 
if ( lines.Count == 0 ) {
lines.Add( "<P></P>" );
selectionStart = 3;
return;
}
lines.InsertRange(LineContainingCursor()+1, NewParagraph());
selectionStart = NewSelectionStart(LineContainingCursor() + 2, " < P > ");
}

Now the specialized methods NewParaSelectionStart and NewSectionSelectionStart can be removed. I ll do that and run the tests. Sure enough, they run!




Extreme Programming Adventures in C#
Javaв„ў EE 5 Tutorial, The (3rd Edition)
ISBN: 735619492
EAN: 2147483647
Year: 2006
Pages: 291

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net