What does that function do, really?

Recently, I had the chance to read a blog by one of my former coworkers on the topic of code duplication and functional programming. I found the ideas there interesting; in many applications that I deal with there are certain repeated processes. For example, functions try a certain statement, catch a possible exception and log the information to the event log. Pretty standard process. So in reading this blog I came to a simple conclusion. There are at least two types of code that are duplicated: Functional Code and Procedural Code (not to be confused with functions and procedures). One of them is often refactored and reused… one of them is not. Take the following code example:


public class DataManager 
{

      public
 void SaveData()
      {
            try
            {
                  //Do something
             }
             catch(Exception ex)
             {           
                   EventLogger logger = new EventLogger();
                   logger.LogException(ex);

             }
       }
}


Functional Code


Functional code is code that accomplishes a certain task. In this example, I have intercepted an exception in the system and I am going to log it to the event log. So I write a class with a method that takes messages in and inserts them into the event log. This code fulfills a function in this system — it ensures that messages it receives are persisted in the designated medium (the event log, in this case). Duplicate code here is easily refactored into an object that provides an interface to the event log, with methods for managing events and it acts as an application boundary for the system. The segments of code within the try, and within the catch are functional code segments.


Procedural Code


Procedural code is code that governs how your functional code is implemented. This code fulfills a process of the system — it ensures that when an exception occurs, the appropriate piece of functional code is executed. In the above example, this is the code that manages when your event logging class is used — it is the code that tries a statement, catches some exception, and invokes the logger.  It’s something seen repeated in a lot of functions in a lot of applications.


Reading the above blog, I thought it was a neat way to refactor this into a reusable process. But, I felt that while the procedural code had been abstracted a bit, calls to it would still be scattered through my systems, and I was hoping to remove it from my implementation all together.


So why is this important? By refactoring functional code into reusable objects, you can change the internal implementation of that object without impacting the rest of your system. But what about the steps your system takes in order to fulfill that function? What if you want to amend that process to do additional steps before logging that exception?


Often times this sort of code is placed upon the object that is performing the function itself. Let’s amend my original example of event logging to include message formatting. In our modified example, the object’s behavior is defined as accepting a message, formatting that message, and then logging it. While the formatting of the message is clearly procedural — it is a step the system takes to prepare for logging — many people will dump it with functional code. Take for example, the following sample:


public class EventLogger
{
      public
void LogException(Exception exception)
      {
            string 
message =  new ExceptionFormatter().FormatExceptionMessage(exception);
            this.
WriteToEventLog(message);
      }
}


Alternatively, you could pass the appropriate formatter to the function:


public class EventLogger
{
      public void LogException(Exception exception, IExceptionFormatter formatter)
      {
            string 
message =  formatter.FormatExceptionMessage(exception);
            this.
WriteToEventLog(message);
      }
}


This intially seems to make sense to do. The first example reduces code duplication because the presumption is that all error messages will need to be formatted before being logged. However, from the standpoint of the consumer of this class, one would expect this method to take an exception and send it to the event log. One would not be aware that formatting would be occuring on the message. This design produces unexpected behavior from the standpoint of the consumer and becomes an implicit and non self-documenting aspect of the object. Although it clearly logs messages to the event log, it also has unclear additional behavior. Furthermore, if a developer implements the second sample, the consumer also has to be aware of exception formatting in order to log messages, resulting in a more difficultly consumed interface. One could simply rename the method in either sample to “FormatAndLogMessage”, but honestly this addresses the symptom of the problem, and not the problem itself.


The Seperation of Concerns


What I’m getting around to is that there is a clear seperation of concerns here. Event Logging should not be concerned with Message Formatting. These are seperate concerns and the functional code to fulfill each concern should be ignorant of the other. This would imply that the procedural code in first sample should somehow be amended in the try/catch to perform message formatting before logging. If logging were performed like this throughout the system, this approach would actually increase code duplication instead of solve it! Furthermore, one would expect a function like SaveData() would simply do as it says — save the data. However in our above sample, the seperation of concerns is apparently violated by the fact that SaveData() not only saves information, it logs exceptions to the event log!


Fortunately, there is a way to resolve this issue in a relatively simple manner, reducing procedural code duplication and seperating concerns within our functional code segments while producing a readable, self-documenting interface. This can be accomplished declaratively by use of attributes.


[Loggable] and [LogException]


Assume for a moment that the above scenario could be implemented in this fashion:


[Loggable] 
public class DataManager 
{
      [LogException]

      public void SaveData()
      {
             //Do something
 
     }
}


This implementation is a much simpler, more elegant way to address the problem. In this example, there is no procedural code within SaveData(), only functional code. Exception logging has been abstracted away from our codebase and reclassified as a system concern. This is a good thing — it allows our code to focus purely on the needs of the business instead of having to also manage the needs of the system. In this implementation we have extended the way in which the system is expected to address exceptions during execution declaratively, augmenting the way in which our code executes without affecting the way our code is implemented.


So what about exception formatting? Using this approach, we should easily be able to extend our design to address this concern as well.


[Loggable] 
public class DataManager 
{
      [FormatException, LogException]

      public void SaveData()
      {
             //Do something
 
     }
}


or, if you prefer to use more than one formatter:


[Loggable] 
public class DataManager 
{
      [FormatException(typeof(ExceptionFormatter)), LogException]

      public void SaveData()
      {
             //Do something
 
     }
}


This allows us to identify both exception message formatting and exception logging as procedural aspects of our system and abstract those concepts away from our functional code declaratively, producing less code to maintain through code reuse and more readable code by focusing our written code on what is important — the functionality.


So how useful is this? Fairly useful, in my opinion. It would allow developers to draw clear distinctions declaratively between system needs and business needs. Operations like event logging, operation retrying and using transactions are some easy examples of where this could be implemented to reduce code duplication. The key is knowing when and what types of procedural code make good candidates for this sort of approach.


In my next post, I will show how the procedural code in our first sample is abstracted into attribute usage and implemented in .NET to produce the final examples, touching on something I came across while trying to figure out how to accomplish this — Aspect Oriented Programming.

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://www.lostechies.com/blogs/joe_ocampo/ Joe Ocampo

    Excellent post Marcus. I am curios where you are going to take this from an AOP. I would have thought you were going to go with a dependency injection pattern of some kind utilizing an IoC framework.

    But since you are relying on the attribute to be more at a system level and allowing the domain entities to be decorated, you would…. OK I am ranting I will just wait to see how you did it. Nice Post!

  • http://jefflouella.com/mp3/fussball/fussball-live.php

    Gute Arbeit hier! Gute Inhalte.