KnowDotNet Visual Organizer

Writing Bug-Free, Maintainable Code

Create a Framework of Proven Objects

by Les Smith
Print this Article Discuss in Forums

Despite evidence to the contrary, it is possible to consistently write bug-free, easy to read and maintainable code.  But it takes a plan and you must discipline yourself to stick to your plan.  This is the first in a series of articles on designing and writing code that from the time that it goes into production will not require bug-fixes.

Years ago, someone publshed a statistic on how many times a Cobol program had to be compiled before it was put into production.  I do not remember the number, but it was in the hundreds.  Although it would be safe to say that people that frequent this site are not Cobol developers, many that read articles, on this and other .NET informational sites, are guilty of developing in slip-shod patterns that foster the same kind of statistic that I quoted regarding Cobol.

With proper design, coding practices, adherence to a simple set of methodologies, and testing, it is possible to write bug-free code.  I am not necessarily talking about applications that never require modifications, due to incomplete customer requirements and ill-designed specifications.  Requirements will change and that will require changes.  I am talking about disciplines that, when adhered to, will allow for development of applications that will perform according to spec without disastorous results due to bugs that are simply inexcusable.  

This first article will be on the subject of creating an application framework.  Take a cue from the designers of the .NET Framework.  It has literraly thousands of classes, and each of those classes has a myriad of properties and methods. Consider the time saved when you use the flexibility of such Namespaces as the System.Text, System.IO, or System.String Class.  What the designers and developers of the .NET Framework did was to take thousands of Windows APIs, with all of their parameters, return values, and flexibility, and bring them out with wrappers to make them easily accessible to the ordinary developer.  They took the complexity and the danger out of the APIs and made them available to the masses of Visual Basic programmers as well as the thousands of developers that would switch to the new C# language.  

Additionally, they analyzed the mundane tasks that application developers do many times a day and built functions to eliminate multitudes of tasks that we had to "carve out of hard rock."  In doing so, they created "macro" functionality that eliminated so many lines of code for us.  And remember that any one line of code is a potential for one or more bugs.  Therefore, for every line of code that we don't have to write, that's one or more bugs that cannot be introduced into your application.

Where I currently contract, I am charged with creating applications that allow our customers to create batch files to utilize the services that we provide.  The basic services are available through an XML Web Service.  Although many customers choose to interface directly with the Web Service in real-time, many more find it easier to create batch files, composed of delimited text, or their own proprietary XML, or EDI formats, or even Excel Spreadsheets.  Although the applications that I currently build are not on the Enterprise scale (they range between 2,000 to 4,000 lines of code), the principles are the same.

Most of the input data, regardless of format, comes to us over FTP and is normally encrypted with PGP (Pretty Good Protecton) technology.  If we send acknowledgement and results files, we normally return this data the same way the requests came in; PGP and FTP.

Over the months, I have created classes which perform all of the tasks associated with the various technologies with which I must work.  This toolset is now well developed, tested, and proven to work.  As I start a new application, I found myself constantly either sharing these classes through Visual Sourcesafe or adding a reference to multiple DLLs.  Finally, it occurred to me that I had a complete toolset for the type of applications that I need to build and that there was a simple method for packaging that toolset so that I did not have to go to several projects to get references to everythng I need.  The answer is to build a Framework.  For evey application I write, I need the same basic elements in the framework.  They are listed below.

   PGP Wrapper
   FTP Library Wrapper
   XML Builder
   XML Extraction Wrapper
   EMail Wrapper
   Web Service Wrapper

For obvious reasons I will not show the code for each of these classes, but I will show you how to build an application framework so that with one reference, you have the entire toolset brought into your application.  Figure 1 shows that methodology.  In actual practice, there is enough code to justify each class having its own code window, but here I will put it all in one code window.  Figure 1 and 2 will both VB.NET and C# versions of the code.

Figure 1 - Application Framework

Imports System.Web
Imports System.Xml

Namespace AppFramework
  
Public Class EmailWrapper
      
Public Function SendEMail(ByVal subject As String, _
        
ByVal msg As String, ByVal msgTo As String, _
        
ByVal msgFrom As String) As Boolean

      End Function
   End Class

   Public Class XMLBuild
      
Public Function BuildXML(ByVal rd As RequestData) As String

      End Function

      Public Class RequestData

      
End Class
   End Class
   Public Class PGPWrapper
      
Public Function DecryptFile(ByVal encryptedFile As String, _
          
ByVal passPhrase As String) As String

      End Function
      Public Function EncryptFile(ByVal plainText As String, _
          
ByVal userID As String) As String

      End Function
   End Class
   Public Class FTPWrapper
      
Public Function UploadFile(ByVal fileName As String) As Boolean

      End Function
      Public Function DownLoadFiles(ByVal workDir As String) As Integer

      End Function
   End Class
End
Namespace

C# Version

using System.Web;
using System.Xml;

namespace AppFramework
{
  
public class EmailWrapper
   {
      
public bool SendEMail(string subject, string msg, string msgTo, string msgFrom)
      {

      
return false;
      }
   }

  
public class XMLBuild
   {
      
public string BuildXML(RequestData rd)
      {

      
return null;
      }

      
public class RequestData
      {

      }
   }
  
public class PGPWrapper
   {
      
public string DecryptFile(string encryptedFile, string passPhrase)
      {

      
return null;
      }
      
public string EncryptFile(string plainText, string userID)
      {

      
return null;
      }
   }
  
public class FTPWrapper
   {
      
public bool UploadFile(string fileName)
      {

      
return false;
      }
      
public int DownLoadFiles(string workDir)
      {

      
return 0;
      }
   }
}


Figure 2 shows a simple illustration of how to use the new framework that I have built.   To make the framework a part of my new application, I need only add a reference and then Import the framework as shown in the first line of code in Figure 2.

Figure 2 - Using the Application Framework

Imports MyAppFramework.AppFramework
Imports System.IO
Public Class Form1
  
Private workDir As String

   Private Sub Test()
      
Dim em As New EmailWrapper
      
Dim ftp As New FTPWrapper
      
Dim xb As New XMLBuild
      
Dim pgp As New PGPWrapper
      
Try

         ' download files from ftp
         Dim count As Integer = ftp.DownLoadFiles(workDir)

        
Dim di As New DirectoryInfo(workDir)
        
Dim files() As FileInfo = di.GetFiles("*.pgp")

        
' decrypt the files
         For Each file As FileInfo In files
            
Dim plainText As String = _
               pgp.DecryptFile(file.FullName,
"my private password")

            
' process the files
            ProcessFile(plainText)

            
'........
         Next
      Catch ex As System.Exception
         em.SendEMail(
"App Error", ex.ToString, _
            
"les@knowdotnet.com", "MYAppDontReply.com")
      
End Try
   End Sub
End
Class

C# Version

using MyAppFramework.AppFramework;
using System.IO;
public class Form1
{
  
private string workDir;

  
private void Test()
   {
      EmailWrapper em =
new EmailWrapper();
      FTPWrapper ftp =
new FTPWrapper();
      XMLBuild xb =
new XMLBuild();
      PGPWrapper pgp =
new PGPWrapper();
      
try
      {

        
// download files from ftp
        
int count = ftp.DownLoadFiles(workDir);

        DirectoryInfo di =
new DirectoryInfo(workDir);
        FileInfo[] files = di.GetFiles("*.pgp");

        
// decrypt the files
        
foreach (FileInfo file in files)
        {
        
string plainText = pgp.DecryptFile(file.FullName, "my private password");

        
// process the files
          ProcessFile(plainText);

        
//........
        }
      }
      
catch (System.Exception ex)
      {
        em.SendEMail("App Error", ex.ToString(), "les@knowdotnet.com", "MYAppDontReply.com");
      }
   }
}

Remember, the code of the framework has been tested and proven and may be hundreds or thousands of lines of code that become part of my application.  My application will only have the new code that is germaine to the particular requirements of the new application.  The framework will provide the bulk of the code and it is already guaranteed to work.  This means that each new application begins with hundreds or thousands of bug-free lines of code as a foundation.  With that kind of a framework upon which to build, I already have a great start building a bug-free application.

My next article in this series will focus on Refactoring the code as I go to ensure that the non framework code that I must write will be modular, easy to read, easy to debug and maintain.

Ask a Question, or give your feedback on my articles or products by going to the KnowDotNet Forum or by clicking on My Blog.
  


Writing Add-Ins for Visual Studio .NET
Writing Add-ins for Visual Studio .NET
by Les Smith
Apress Publishing