Refactoring helps developers re-engineer their code and removes much of the tedium of maintaining an application. Considerable time is spent re-engineering during the lifetime of an application. This sometimes starts as early as the development phase and accelerates as the application matures. This includes—but is not limited to—renaming variables, moving methods, changing method signatures, and redesigning classes. The objective is to improve the application. The process is tedious. Finding and changing a variable in a software system that spans dozens of source files can be challenging. Another example is changing the signature of a commonly used method. Method calls throughout the application must be located and corrected. These changes are made to improve an application. However, if executed poorly, these changes have the opposite effect. Worst-case scenario: Maintenance might introduce bugs into otherwise pristine applications. Visual Studio 2005 introduces refactoring as a tool to help developers re-engineer code quickly and accurately. Refactoring is a multifaceted tool. It assists in the renaming of variables, changing of method signatures, extrapolating of interfaces, converting fields to properties, and much more.

A Refactoring menu is available in the Visual Studio 2005 user interface that shows the refactoring operations. Table 4-5 list the various refactoring operations. The refactoring menu is also available in the Code Editor using a shortcut menu.

Table 4-5: Refactoring Operations




The Rename operation renames a symbol, such as a variable or method name, throughout an application.

Extract Method

The Extract Method operation creates a new method that encapsulates the selected code.

Encapsulate Field

The Encapsulate Field operation creates a property that abstracts the selected field.

Extract Interface

The Extract Interface operation extracts an interface from a type.

Promote Local Variables To Parameters

The Promote Local Variables To Parameters operation promotes a local variable to a parameter of the current method.

Remove Parameters

The Remove Parameters operation removes a parameter from the parameter list of a function. Call sites for the function are updated to reflect the removed parameter.

Reorder Parameters

The Reorder Parameters operation reorders the parameters of a function. Call sites for the function are updated for the new sequence of parameters.

The Preview Changes dialog box is invaluable because it provides you with an opportunity to preview refactoring changes before applying them. Figure 4-35 displays the Preview Changes dialog box.

Image from book
Figure 4-35: Preview Changes dialog box

Refactoring can span multiple projects in the same solution, which occurs with project-to-project references. A project-to-project reference is a reference in which both the referencing and referenced assemblies are built in projects of the same solution. The Projects window in the Add Reference dialog box inserts a project-to-project reference.

Refactoring Walkthrough

This walkthrough demonstrates some of the features of refactoring, including the renaming of variables and extracting of interfaces. The walkthrough refactors the Airline Seats application. This application manages the first class and coach standby lists of an airline flight. This is the user interface (shown in Figure 4-36) presented to flyers on overhead monitors at the airport gate.

Image from book
Figure 4-36: Airline Seats application

The following steps outline the walkthrough.

  1. The application defines a Node class, which is a generic collection class in the node.cs file. The value of the node is returned from the Info property. The property should be renamed Value, which is probably more intuitive. Select the Info name in the source file. From the shortcut menu, choose the Refactor submenu and the Rename menu command.

  2. The Rename dialog box appears. The selected text is displayed with its location. Three option buttons are presented. The Preview Reference Changes option requests a preview window before the changes are applied. This option is selected by default. The Search In Comments option searches comments for the renamed text. The Search In String option extends the search to literals, such as string literals. Change the text to Value and proceed with the renaming operation. (See Figure 4-37.)

  3. The Preview Changes—Rename dialog box appears. (See Figure 4-38.) You can review the pending changes in this window. Specific changes can be selected or unselected. When acceptable, click Apply, and the specified changes are enacted. If necessary, you can undo refactoring changes using the Undo (Ctrl+Z) feature of Visual Studio.

  4. The capability to extrapolate interfaces from classes is another great feature of refactoring. Manually extracting interfaces from types is a time-consuming process for developers. The Airline Seats application has a Person class that represents the flyer. In the future, other types of people may be added to the application. For that reason, the Person interface is extrapolated for future use. Position the cursor within the class and open the shortcut menu. From the Refactor menu, select the Extract interface menu command. The Extract Interface dialog box appears, as shown in Figure 4-39. Enter the interface name and file name. A list of potential members is presented. You can select which members to include in the interface. As a convenience, Select All and Deselect All buttons are provided.

  5. The Passenger class, which is a form, has two public fields. A tenet of object-oriented programming is that fields should be private. Exposing fields as public properties is more secure.

    public Node<Flyer.Person> coachlist=null;
    public Node<Flyer.Person> fflist= null;
  6. Select the first field. From the shortcut menu, select the Refactoring menu and Encapsulate Field menu command. The Encapsulate Field dialog box appears. (See Figure 4-40.) Enter the property name and accept.

  7. After accepting the Encapsulate Field dialog box, the Preview Reference Changes dialog box appears. This dialog box shows the potential changes. You can accept or reject individual changes.

  8. Repeat steps 6 and 7 to convert the second field to a property. Despite the numerous changes in various parts of the application, you can now compile and run the program successfully.

Image from book
Figure 4-37: Rename dialog box
Image from book
Figure 4-38: Preview Changes—Rename dialog box
Image from book
Figure 4-39: Extract Interface dialog box
Image from book
Figure 4-40: Encapsulate Field dialog box

This is the interface created from the Extract Interface refactoring operation. It is saved to a separate file. In the file, change the namespace containing the interface appropriately. For the sample application, the namespace is changed to Flyer.

interface IPerson
    string FirstName { get; }

    bool FrequentFlyer { get; }
    string ID { get; }
    string LastName { get; }

Refactoring also updated the Person class to inherit the IPerson interface:

public class Person : IPerson
     // partial listing

This is one property created from refactoring a field:

private Node<Flyer.Person> coachlist = null;

public Node<Flyer.Person> Coachlist
    get { return coachlist; }
    set { coachlist = value; }