Holistic Solution Creation - Part 1

I think the ideas I raised in Never add just one project made so much sense, that I've decided to show what I meant. So sticking with the previous example, lets develop an FTP task for MSBuild.

All familiar with Test Driven Design or Test First Design? No? Well in a nutshell we start with some tests. Of course you need to know what to test. This is where I probably deviate from what most would consider Test Driven Design, as first I like to start with a little Top Down Design.

A framework

I mentioned before that I wanted not just one deliverable. My first task is to create projects for my deliverables. We need

  • A main library
  • Unit tests
  • A Console application
  • An MSBuild Task
  • A GUI that can also create FTP task entries

FTP task Diagram 1

Once we have these projects in place then we can consider where the functionality lives that's shared. It appears that the MSBuild functionality is used in two places as well so a more accurate diagram including dependencies would be

FTP task Diagram 2

Class Diagrams

I think that the Class diagram functionality in VS is great. However I really wish it went a little further. One common problem I've come across in many companies, is developers don't know how to consider the entire code base. In my current company for example, their are many solutions, and each one has its own X.Common project. Most of them define their own DAL abstraction and Logging functionality. That's where the hand drawn diagrams above come in.

Top Down design

Now that are have our basic framework lets consider some functionality that we might require. I previously described my requirements but for v1.0 lets consider the following subset

  • Backup
  • Offline the site (i.e. upload a file as "\app_offline.htm")
  • Upload site
  • Online again (i.e. delete "\app_offline.htm")

I can even go so far as create a framework that will run this for the console application. I am going to delegate the work of processing the command line arguments to an Arguments class. So that leaves us with

static void Main(string[] args)
{
    Arguments arguments = Arguments.Parse(args);
    SiteFtpEngine upload = new SiteFtpEngine();
    upload.Server = arguments.FtpServer;
 
    upload.SiteOffline(Path.Combine(arguments.SourceDirectory, "_app_offline.htm"));
    if (arguments.BackupRequired)
        upload.Backup(arguments.BackupPath);
 
    upload.UploadSite(arguments.SourceDirectory);
    upload.SiteOnline();
}

At this point it also good to consider whether this style of framework works for all applications.

  • A WinForms application might expect to display progress, the BackGroundWorker class explicitly defines a ReportsProgress method to help us.

  • An MSBuild Task will also expect to report progress and do it at three different levels, Information, Warning and Error.

So we need to get messages out of the Functionality and into the Frameworks. One pattern that we can see in WinForms is ideal for this as it works in all other frameworks too. We simply create some events, which along with a little error handling changes our above sample to

static void Main(string[] args)
{
    Arguments arguments;
    try
    {
        arguments = Arguments.Parse(args);
    }
    catch //(Arguments.ArgumentException argEx)
    {
        ShowUsage();
        return;
    }
    SiteFtpEngine upload = new SiteFtpEngine();
    upload.Information += new EventHandler<MessageEventArgs>(ReportProgress);
    upload.Warning += new EventHandler<MessageEventArgs>(ReportProgress);
    upload.Error += new EventHandler<MessageEventArgs>(ReportProgress); 
 
    upload.Server = arguments.FtpServer; 
    upload.SiteOffline(Path.Combine(arguments.SourceDirectory, "_app_offline.htm"));
    if (arguments.BackupRequired)
        upload.Backup(arguments.BackupPath);
    upload.UploadSite(arguments.SourceDirectory);
    upload.SiteOnline();
}

I can even go one better and display this framework in Class Designer, along with the definition of the functionality as we have it so far

Part1

Summary

So far we have taken a more holistic approach to design and considered the impact this should have on our possible applications later. We have considered how the pieces of our code base will fit together and used top down design to give us one possible framework, with considerations for other frameworks in other applications. These considerations have shaped our initial interface for our functional library.

In part 2 we will look at how I think Test First Design plays its part on creating this application and one of the short comings I've come across in TFD/TDD.

Add comment

  Country flag


  • Comment
  • Preview
Loading