Dealing with Legacy Code Part 2: Extract the API out of your interfaces


Think about the following situation:

There is an interface / class interface / function in your application used by others which conains non-standard enums / types / whatever coming from an external API like OpenGL, DirectX, some kind of commercial API. The underlying code strongly uses this API. So using parts of this API was straight forward. Instead of having a strong encapsulation your API was spreaded all oer your codebase. Unfortunately the Product-Manager generates this requests: we need to exchange the underlying API because of whatever … Easy, just change this one API below your code and … wait a minute. There are all these symbols coming from the old API. WTF!

It looks like:

enum class API1Enum {
  feature1,
  feature2
};

class MyInterface {
public:
  void enableFeature( API1Enum myEnum ) = 0;
};

// Implementation for API1
class MyAPI1Impl : public MyInterface {
  void enableFeature( API1Enum myEnum ) {
    // handle the enum from the API1
    switch (myEnum) { ... }
  }
};

For the first implementation this concept works fine. Now you get a new API to wrap, just implement the interface, right?

class MyAPI2Impl : public MyInterface {
  // Damned, API1 does not exist anymore ...
  void enableFeature( API1Enum myEnum ) {
    ..
  }
};

Solution: Wrap the enum as well:

Of course you can introduce another app-specific enum, wrap the API by using it and you are fine:

// From the API
enum class API1Enum {
  feature1,
  feature2
};

// defined in your app
enum class AppEnum {
  Appfeature1,
  Appfeature2,
  AppNotSupported
};

// change your interface
class MyInterface {
public:
  void enableFeature( AppEnum myEnum ) = 0;
};

// Introduce functions for translation
static API1Enum translateAPI1( AppEnum type ) {
  switch( type ) {
    case AppEnum::Appfeatue1; return API1Enum::feature1;
    case AppEnum::Appfeature2: return API1Enum::feature2;
  }
  // error handling
}

static API2Enum translateAPI2( AppEnum api2_type ) {
  // do it for API2
}

class MyAPI1Impl : public MyInterface {
  void enableFeature( AppEnum myEnum ) {
    // translate AppEnum and handle it for API1
    switch (translateAPI1(myEnum)) { ... }
  }
};

class MyAPI2Impl : public MyInterface {
  void enableFeature( AppEnum myEnum ) {
    // translate AppEnum and handle it for API1
    switch (translateAPI2(myEnum)) { ... }
  }
};

What you are doing:

  1. Introduce an APP-specific enum
  2. Use this enum instead of the API-specific enum
  3. Introduce translation functions to translate the AppEnum to the API1Enum / API2Enum
  4. For the API-specific implementations: translate the AppEnum into the API-specific enum

Optimizations?

You can use lookup-tables instead of the translation-functions. But as a first step translation-functions a much easier to debug.

C#: Use System.Diagnostics.Trace and DbgView within a WPF-Application


One of my favorite tools to debug MFC-Applications was the Win32-call:

::OutputDebugString( "Test\n" );

You can use it to trace information withing your application during runtime without a log-file. You only have to run the tool DbgView to monitor these log-entries ( if you want to try it out you can download DbgView here. )

Because I am currently working with C# in my job I wanted to use this tool as well for WVF-applications. And of course there is a corresponding API-method in the .NET-framework called:

Trace.WriteLine( string msg );

You can find the documentation here.

It is easy to use. Just insert your Trace-log-entries in your code. When you want to take a look into your application you can start DbgView to see, what is ongoing. Just make sure, that you have defined

#define TRACE

at the beginning of your source-file. Here is a small example:

#define TRACE

using System.Diagnosics;

class Test {
    static int main() {
        Trace.WriteLine("Hello, world!" );
        Exit(0);
    }
}

C#: Calling a generic from a generic with surprises


I am currently working on C# wit generics. The base concept seems to be the same as in C++ ( which I really like honestly spoken ).
And I tried to use specialization. There was a class which needs to deal with special data types. And for some special cases you need a type-specific semantic, because bool cannot be added for example. So I tried to do something like this:

public class MyGeneric<T> {
  T mValue;
  public MyGeneric<T>() {}
  public OnMethod( T v ) {
    mValue = v;
  }
  public OnMethod(bool v ) {
    mValue = !v;
  }

  static main() {
    MyGeneric<int> i = new MyGeneric<int> i();
    i.OnMethod(1); // Will call the generic method
    MyGeneric<bool> b = new MyGeneric<bool> i();
    b.OnMethod(true); // Will call the specialized method for bool
  }
}

Looks greate, I thought. problem soled I thought. Let’s integrate it into your application and continue to live a happy life again I thought. I was so wrong …

Because when calling a generic method from a generic method this specialization will not work:


public class MyCaller<T> {
  MyGeneric<T> mClassToCall;
  ...
  public void MethodCaller<T>( T v ) {
    mClassToCall.OnMethod( v );
  }
}
public class MyGeneric<T> {
  T mValue;
  public MyGeneric<T>() {}
  public OnMethod( T v ) {
    mValue = v;
  }
  public OnMethod(bool v ) {
    mValue = !v;
  }

  static main() {
    MyCaller<bool> boolCaller = new MyCaller<Bool> i();
    boolCaller.MethodCaller(true); // Will call the generic method public OnMethod( T v )
  }
}

This will not call the specialization. You need to add special traits to deal with this situation.

The solution is simple: use a type trait to detect which specialization is the right one for you and do the switch during runtime.