Quick refactoring with Refactor! Pro

29 July 2009

A moment ago, I was writing some code that configured a chart and I thought it would be good to quickly post what I was doing, not because it was especially difficult XtraCharts code, but it illustrated a refactoring technique that not many people know.

The code I'd written added two horizontal constant lines to a bar chart. This was the starting point:

    // set up the constant lines
    ConstantLine line = new ConstantLine();
    line.ShowBehind = true;
    line.AxisValue = 1000000;
    line.ShowInLegend = false;
    line.Color = Color.DarkSeaGreen;
    line.LineStyle.DashStyle = DashStyle.Dot;
    diagram.AxisY.ConstantLines.Add(line);

    line = new ConstantLine();
    line.ShowBehind = true;
    line.AxisValue = 1500000;
    line.ShowInLegend = false;
    line.Color = Color.DarkSeaGreen;
    line.LineStyle.DashStyle = DashStyle.Dot;
    diagram.AxisY.ConstantLines.Add(line);

I'm sure, like me, you're shuddering at the repetition. No sweat, I deliberately decided to code it like this, prior to removing the redundancy, so that I could make sure that (a) it worked, and (b) that I'd configured the lines the way I wanted. As it happened, after that bit of coding, the only difference between the two blocks of code was the value, but I could have decided on, say, different colors for the lines as well, so it was worth doing it this way.

I highlighted the first block of code, minus the line that added the line to the axis' collection of lines, hit the Refactor key (the back tick) and extracted a method. The extracted method looked like this:

  private static ConstantLine GetLine() {
    ConstantLine line = new ConstantLine();
    line.ShowBehind = true;
    line.AxisValue = 1000000;
    line.ShowInLegend = false;
    line.Color = Color.DarkSeaGreen;
    line.LineStyle.DashStyle = DashStyle.Dot;
    return line;
  }

I'm fine with the automatically-generated name of the method (and that it's marked static), but I now need to add a parameter to pass in the axis value (here it's 1000000). This is a two step process.

First declare the constant as a local: highlight the value and select the "Declare Local" refactoring. I called the new variable axisValue:

  private static ConstantLine GetLine() {
    ConstantLine line = new ConstantLine();
    line.ShowBehind = true;
    int axisValue = 1000000;
    line.AxisValue = axisValue;
    line.ShowInLegend = false;
    line.Color = Color.DarkSeaGreen;
    line.LineStyle.DashStyle = DashStyle.Dot;
    return line;
  }

Second, promote that local variable to a parameter. No need to highlight the variable name, just hit the Refactor key while the cursor is in the identifier.

  private static ConstantLine GetLine(int axisValue) {
    ConstantLine line = new ConstantLine();
    line.ShowBehind = true;
    line.AxisValue = axisValue;
    line.ShowInLegend = false;
    line.Color = Color.DarkSeaGreen;
    line.LineStyle.DashStyle = DashStyle.Dot;
    return line;
  }

Just what I wanted. I then hit Esc to gather the marker left by the Extract Method refactoring to see this:

    // set up the constant lines
    ConstantLine line = GetLine(1000000);
    diagram.AxisY.ConstantLines.Add(line);

    line = new ConstantLine();
    line.ShowBehind = true;
    line.AxisValue = 1500000;
    line.ShowInLegend = false;
    line.Color = Color.DarkSeaGreen;
    line.LineStyle.DashStyle = DashStyle.Dot;
    diagram.AxisY.ConstantLines.Add(line);

I can now inline that assignment since there's no need to assign the result of GetLine to a variable, and then pass the variable to the Add method. Note the variable is not removed by the refactoring since it's used lower down.

    // set up the constant lines
    ConstantLine line = GetLine(1000000);
    diagram.AxisY.ConstantLines.Add(GetLine(1000000));

    line = new ConstantLine();
    line.ShowBehind = true;
    line.AxisValue = 1500000;
    line.ShowInLegend = false;
    line.Color = Color.DarkSeaGreen;
    line.LineStyle.DashStyle = DashStyle.Dot;
    diagram.AxisY.ConstantLines.Add(line);

Now I can dupe the code that adds the new line from a call to GetLine, change the parameter to 1500000, and delete the other unnecessary lines.

    // set up the constant lines
    diagram.AxisY.ConstantLines.Add(GetLine(1000000));
    diagram.AxisY.ConstantLines.Add(GetLine(1500000));

Done. Of course, it would be nice if Refactor! Pro noticed the duplicated block during the Extract Method refactoring and fix it up too. We're working on that.

Free DevExpress Products - Get Your Copy Today

The following free DevExpress product offers remain available. Should you have any questions about the free offers below, please submit a ticket via the DevExpress Support Center at your convenience. We'll be happy to follow-up.