Functionality v Framework

This is going to sound so simple, so bear with me, but at the moment its becoming my personal mantra.

There is a difference between the functionality of a system and the framework it runs in.

Lets take a simple example, we have a process at work. Basically it gets a list of files from a database copies the files over and updates a different database to point to the new files. It is currently hosted in a windows service. Can you separate the functionality from the framework?

Functionality

It gets a list of files from a database copies the files over and updates a different database to point to the new files

Framework

Hosted as a service

Why does this matter?

Well the problem is that I also need to run the functionality on ad-hoc basis with some special parameters. So what do we do, well simply we split the functionality from the framework, put the functionality in a separate assembly, call it once from the service and again separately from a console application or a WinForms GUI.

But that’s only the first level

We can consider the same at a method level, where we have a for loop with a code body. It is impossible to test a single iteration of the logic in the for body without going through the framework.

            foreach (string name in _list.Keys)
            {
                progress.DoOne("Adding " + name);

                TableRow tr = resultsTable.AddRow();
                tr.AddCell().Value = name;
                Dictionary<DateTime, TestResult> data = _list[name];
                //now add cells
                foreach (DateTime dt in _dates)
                {
                    TableCell cell = tr.AddCell();
                    if (data.ContainsKey(dt))
                    {
                        switch (data[dt])
                        {
                            case TestResult.Fail:
                                cell.Value = "Fail";
                                cell.BGColor = Color.Red;
                                break;

                            case TestResult.Pass:
                                cell.Value = "Ok";
                                cell.BGColor = Color.Green;
                                break;

                            case TestResult.Untested:
                                cell.Value = "";
                                cell.BGColor = Color.Yellow;
                                break;

                        }
                    }
                }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

What is more is that we can ONLY call this functionality with its framework. We can refactor the body of a for loop out to a method that takes parameters or even a Visitor pattern. This lets us call it separately, for example we can now Unit Test the functionality.

At the class level we can also refactor so that we separate the multi-threading code out and leave the business logic. This lets us host the logic with or without the threading. So maybe, once again we can unit test the logic separately, or host in different applications as before.

So what does this mean?

I think it might be time for Al’s First law (see Haacked’s law).

The greatest barrier to reuse and testing is a mix of functionality and framework in the same unit.

I wonder if there will ever be 2nd?

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s