Refactoring VB in Visual Studio 2005

Two primary factions have polarized Visual Basic: VB6 programmers and OOP programmers. VB6 programmers want VB to be really easy to use; OOP programmers say VB needs to be as powerful a language as C# or C++, or VB is just a toy. VB can't be a hobbyist's language and a full-blown object-oriented language at the same time, and Microsoft can't figure out which constituency to satisfy. So right now, VB is trying to be both. For example, VB.NET includes multithreading and operator overloading, but the IDE doesn't support VB refactoring. Adding the My feature panders to VB6 programmers, whereas adding operator overloading appeals to OOP programmers. However, Microsoft recognizes that excluding IDE Refactoring support in VB was an oversight and has made Refactor! for VB.NET available as a free download.

What is Refactoring? To paraphrase Martin Fowler, Refactoring is a constructive means of improving the internal structure of code without changing its external behavior. (Martin Fowler is the public voice of Refactoring; William Opdike is considered the inventor.)

Where do I stand? Toy languages are for toy makers. Toy makers have their place (especially at Christmas time), but I have real business solutions to solve and can create toys with business-grade tools but cannot create business-grade tools with toys.

You don't have to agree with my perspective, but you should know about Refactoring because even cobbled together applications can become very complex; Refactoring is a disciplined way to restore existing code without changing its behavior. Both restructuring and maintaining behavior are critical tenets of Refactoring.

Reasons to Refactor

Refactoring guides you through "uncomplicating" code without breaking or changing it. Each Refactoring has a stated motivation, steps that indicate how to complete the Refactoring, and the desired outcome. Some Refactorings are based on existing techniques whereas others are based on new techniques, but all Refactorings have been named and clearly documented.

An example of a common Refactoring is Encapsulate Field. Encapsulate Field means to take public variables, make them private, and then provide access to them through functions. This Refactoring is so well established that it has been codified as a modern property. That said, some programmers still use public fields, even though this practice generally is eschewed. (My article "Write Macro Code Generators with VS 2005" demonstrates how you can implement Encapsulate Field with VB Macros.)

Visual Studio .NET 2005 supports Refactoring in C# but not in VB.NET 2005. However, VB developers don't have to write their own Refactoring tools anymore thanks to a neat tool called Refactor! for Visual Basic, a free download from Microsoft. While you can complete any Refactoring manually, tools make them easier, more foolproof, and quickerplus, they can be fun to use. (Lord knows work needs to be more fun.)

The remainder of this section demonstrates three Refactorings using Refactor! for Visual Basic .Net 2005 version 1.0.31: Encapsulate Field, Extract Method, and Create Overload. (For a complete discourse on Refactoring, see Martin Fowler's Refactoring: Improving the Design of Existing Code from Addison-Wesley.)

Refactoring: Encapsulate Field

The motivation for Encapsulate Field is the belief that public data is bad—think having-your-heart-outside-your-ribcage bad. To complete Encapsulate Field, change a public field to a private field and add accessor methods for reading and writing the value of the now private field. The getter and setter in VB.NET are really just convenience notations for methods that permit you to externally treat a property like a field while calling methods. The methods mean you can wrap checks around the field.

Suppose you have a public field called HeartRate that modulates a patient's heart beats per minute. Bad code could set HeartRate to 500 and, like Emeril says, "Bam!" the patient is dead. To prevent HeartRate from being set too high, you could protect it behind property methods. You could right-click on the field HeartRate, select Refactor!, and Encapsulate Field. You would see changes to your IDE similar to those in Figure 1. You then would use the down arrow to move the target picker (the red arrow and line) to the insertion point and press Enter. The revised code would look like Listing 1.

Figure 1: Refactor! Uses Very Good Cues to Guide Your Use of the Tool

Listing 1: The HeartRate Field Has Been Encapsulated by Refactor!

Imports System.ServiceProcess

Public Class WillRefactor

   Private HeartRate As Integer
   Public Property HeartRate1() As Integer
      Get
         Return HeartRate
      End Get
      Set(ByVal value As Integer)
         HeartRate = value
      End Set
   End Property

End Class

In the revised code in Listing 1, HeartRate cannot be changed without using the public property HeartRate1. To ensure that HeartRate isn't set too high, you could add some conditional code to the Set method.

Refactoring VB in Visual Studio 2005

Refactoring: Extract Method

One of the most common problems with code is having functions that are too long. Small functions can be reused and more easily re-orchestrated into new behaviors. Long, monolithic functions often can be used only under very tight constraints. To make code more reusable, you can extract chunks of code into named methods. In addition to these named methods being more reusable, the names more clearly explain the purposes of the methods.

To use Extract Method, select a fragment of code that you'd like to convert to a named method, right-click over the selected code, and pick Refactor!|Extract Method. To demonstrate, I use a simple for loop that writes HeartRate to the Console 100 times.

If you have only one available Refactoring, use One Key Refactoring by typing Ctrl+~, which invokes the Refactoring and shows an Action Hint (see Figure 2). Again, move the target picker above or below its current location and press Enter. After pressing Enter, the method PseudoLongMethod and the new extracted method are revised, as shown in Listing 2.

[Refactoring2.jpg]

Figure 2: The Currently Available Refactoring and the Action Hint, Extract Method

Listing 2: The Method PseudoLongMethod Is Refactored, Making BunchOfCode a Separate Method

Imports System.ServiceProcess

Public Class WillRefactor

   Private HeartRate As Integer
   Public Property HeartRate1() As Integer
      Get
         Return HeartRate
      End Get
      Set(ByVal value As Integer)
         HeartRate = value
      End Set
   End Property

   Public Sub PseudoLongMethod()

      ' a bunch of code
      BunchOfCode()
   End Sub

   Private Sub BunchOfCode()
      Dim I As Integer
      For I = 1 To 100
         Console.WriteLine(HeartRate)
      Next
   End Sub

End Class

Refactoring: Create Overload

Suppose that BunchOfCode were defined to accept a Count parameter. (Count is used as the upper limit for the loop.) Further suppose that in some cases a default value is known. You can right-click BunchOfCode (see Listing 3) and select Refactor!|Create Overload to create a new method that overloads BunchOfCode and calls the original method with a default value (see Listing 4).

Listing 3: A New Version of Bunch of Code with a Single Parameter

Private Sub BunchOfCode(ByVal count As Integer)
   Dim I As Integer
   For I = 1 To count
      Console.WriteLine(HeartRate)
   Next
End Sub

Listing 4: The Old and New Overloaded BunchOfCode Method Created by Refactor!

Private Sub BunchOfCode(ByVal count As Integer)
   Dim I As Integer
   For I = 1 To count
      Console.WriteLine(HeartRate)
   Next
End Sub

Private Sub BunchOfCode()
   Dim lCount As Integer = 0
   BunchOfCode(lCount)
End Sub

Refactored Code Is Good Code

Refactoring is important not because the underlying techniques are all new, but because the techniques are described and the motivation and desired outcomes are clearly state. Refactoring can improve the internal structure without changing the external behavior of existing code. It removes the subjectivity of what is good code and what is less-good code: Refactored code is deemed good, and code that is not Refactored is deemed less good. (Perfect code probably does not exist.)

More important than whether code is good or bad is whether it works. Refactoring increases the likelihood that code will continue to work as it grows and evolves.



Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Managing your company's financials is the backbone of your business and is vital to the long-term health and viability of your company. To continue applying the necessary financial rigor to support rapid growth, the accounting department needs the right tools to most efficiently do their job. Read this white paper to understand the 10 essentials of a complete financial management system and how the right solution can help you keep up with the rapidly changing business world.

  • With 81% of employees using their phones at work, companies have stopped asking: "Is corporate data leaking from personal devices?" and started asking: "How do we effectively prevent corporate data from leaking from personal devices?" The answer has not been simple. ZixOne raises the bar on BYOD security by not allowing email data to reside on the device. In addition, Zix allows employees to maintain complete control of their personal device, therefore satisfying privacy demands of valued employees and the …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds