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.