Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How would you refactor this smelly code? (Logging, Copy and Paste, .Net 3.5)

I've got code like this:

Logger logger = new Logger();
System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
logger.LogInformation("Calling SomeObject.SomeMethod at " + DateTime.Now.ToString());
stopWatch.Start();
// This is the method I'm interested in.
SomeResponse response = someObject.SomeMethod(someParam);
stopWatch.Stop();
logger.LogInformation("SomeObject.SomeMethod returned at " + DateTime.Now.ToString());
logger.LogInformation("SomeObject.SomeMethod took " + stopWatch.ElapsedMilliseconds + " milliseconds.");

I need to wrap similar code around a lot more objects and their methods to do some performance profiling. I'm not allowed to use 3rd party plugins or software, etc.

I'd really rather not write this same code around all of these method calls this all of this logging code. How would you refactor this to eliminate some of my coding effort?

If I'm not being very clear, please ask questions in the comments and I will try to clarify.

Thanks for any help!!

like image 664
Tad Donaghe Avatar asked May 08 '09 16:05

Tad Donaghe


People also ask

How do you fix code smells?

Take a God object, separate its data and functions according to what problems they exist to solve, then turn those groupings into objects. If you have a God object, it may be better off as a composition of many smaller objects.

What is the most common cause of refactoring problems?

The most common cause of refactoring problems is not in the code -- it's a lack of proper tools. Refactoring nearly always includes renaming variables and methods, changing method signatures, and moving things around. Trying to make all these changes by hand can easily lead to disaster.

When looking at the code for a program what are some indications that it should be refactored?

The best time to consider refactoring is before adding any updates or new features to existing code. Going back and cleaning up the current code before adding in new programming will not only improve the quality of the product itself, it will make it easier for future developers to build on the original code.


2 Answers

You can refactor the code to accept a method pointer instance (aka System.Action).

public void CallWithLogTiming (Action theAction)
{
  Logger logger = new Logger();
  System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
  logger.LogInformation("Calling SomeObject.SomeMethod at " + DateTime.Now.ToString());
  stopWatch.Start();

// This is the method I'm interested in.
  theAction();

  stopWatch.Stop();
  logger.LogInformation("SomeObject.SomeMethod returned at " + DateTime.Now.ToString());
  logger.LogInformation("SomeObject.SomeMethod took " + stopWatch.ElapsedMilliseconds + " milliseconds.");
}

Then you can call it by creating a lambda expression. Since myResponse is a captured variable, it will be populated when this Action is run and myResponse will be available for use later in this scope.

SomeResponse myResponse = null;
CallWithLogTiming( () => myResponse = someObject.SomeMethod(someParam) );
like image 182
Amy B Avatar answered Nov 15 '22 17:11

Amy B


For simplicity sake, you could use generics, like so (off the top of my head):

public T MyLogMethod<T,S>(Func<S, T> someFunction, S someParameter) {}

Func(S,T) where S is the parameter type of the method, and T is the return type.

like image 37
Jonas Avatar answered Nov 15 '22 19:11

Jonas