KnowDotNet

It's Always Time to Refactor- Part II

Program wilth Refactoring Principles in Mind

by Les Smith

Why should I refactor my code?  In fact, what is refactoring, and why should it concern me?  Part II.  In the first article on refactoring, I listed several goals to keep in mind while initially developing or subsequently refactoring code.  In this article I will tackle more of those goals.

Eliminate Duplicate Blocks of Code


Inevitably, you will repeat the same functionality, and literally the exact same code blocks over and over again.  To combat this problem, you must practice my first rule in the first article.  That was to "Keep your code modular."  I have begun to develop classes of Shared Methods.  In VB.NET, you can accomplish this with modules, and in practice Shared Classes or classes of Shared methods are the same thing as Modules.  However, C# programmers sometimes criticize the use of modules (they don't exist in C#), and I have no argument with that.  For if I force myself to use classes of Shared methods rather than modules, then when I am writing in C#, I have no problem getting along without modules.  In C# we use classes of Static methods, which is analogus to Shared methods in VB.NET.  In any case, these classes provide a neat repository for stashng methods that are used from everywhere without having to instantiate an instance of the class.

Caution; if you are using Shared, in VB.NET, or Static, in C#.NET, keep in mind that they are not thread safe.  On the mainframe, we used to say they are not reentrant.  In other words these methods are not safe to use in a multi-threaded application.  There you must instantiate an instance object so that each thread has its own data with which to work.  An alternate method of giving your Shared/Static methods a personal copy of data to work with is to pass all of the needed data by reference.  Just don't have any local variables in a Shared or Static method if it is to be used in a multi-threaded application.

For the sake of the size of your code, search for repeated code blocks and place one copy somewhere all your code can call it.

Keep Performance in Mind, Especially in Loops


No where is the requirement for "tight" code more needful than in loops.  First, always use
Option Strict On!  Why?  First, because the compiler will find bugs at compile time that you won't have to find at run-time.  Secondly, in this respect, VB.NET programmers should adhere to the same standard that C# developers have.  In C#, the Option Strict is always On and there is no way to turn it off.  Thirdly, with Option Strict On, you cannot do late binding.  If you have used VB at least as long as I have, about 12 years now, you will have used late binding and like it.  But late binding causes the CLR to do work at run-time that could have been done at compile time.  You complile a set of code once to build the application, but at run-time some blocks of code get executed millions of times.  If you are not using Option Strict On, get over the slight inconveniences it will cause when you first turn it on and soon the small number of style changes you will have to adapt to will become second nature.

Use System.Text.StringBuilder.  I won't go into a lengthy discussion here, but Strings are
immutable.  Once they are created, they cannot be physically changed.  In earlier versions of Visual Basic, the fixed length string was a feeble attempt to allow you to change strings in place.  But, that feature is gone in .NET and replaced with a much superior object called the StringBuilder.  Get away from the following code sequences.

         line = vbCrLf
         line &= "    " & .SubItems(3).Text & " " & _
            .SubItems(4).Text & " " & .SubItems(1).Text & _
            " {" & vbCrLf
         line &= "        get {" & vbCrLf
         line &= "            return " & _
            .SubItems(0).Text & ";" & vbCrLf
         line &= "        }" & vbCrLf
         line &= "        set {" & vbCrLf
         line &= "           " & .SubItems(0).Text & _
            " = value;" & vbCrLf
         line &= "        }" & vbCrLf
         line &= "    }" & vbCrLf

Obviously, this line is superior ( it creates one string)

         line &= "    " & .SubItems(3).Text & " " & _
            .SubItems(4).Text & " " & .SubItems(1).Text & _
            " {" & vbCrLf
to these lines, which creeate three strings.

         line = "        }" & vbCrLf
         line &= "        set {" & vbCrLf
         line &= "           " & .SubItems(0).Text & _

But the following version is best.

         Dim sb As New System.Text.StringBuilder(500)
         line = vbCrLf
         sb.Append("    " & .SubItems(3).Text & " " & _
           .SubItems(4).Text & " " & .SubItems(1).Text & " {" & vbCrLf)
         sb.Append("        get {" & vbCrLf)
         sb.Append("            return " & .SubItems(0).Text & ";" & vbCrLf)
         sb.Append("        }" & vbCrLf)
         sb.Append("        set {" & vbCrLf)
         sb.Append("           " & .SubItems(0).Text & " = value;" & vbCrLf)
         sb.Append("        }" & vbCrLf)
         sb.Append("    }" & vbCrLf)
         line = sb.ToString()

NET Refactors
Refactor Strings feature can convert the first set of code to the last set with two clicks of the mouse.

Well, I will finish my thoughts on refactoring, at least for now.  In the next article,Refactoring Part III,I will cover two additional subjects on Refactoring.

Check out the many features of
NET Refactor.