Self-Configuration of Classes With Delegates
March 11th, 2007 | by Aldacron |Sometimes you need to execute different code paths depending upon certain runtime parameters. For example, in graphics applications it is quite common to create different rendering paths based upon the graphics API features supported by the user’s graphics card. In simple cases, this can be handled with an if…else block, or perhaps a switch. More complex cases need more. In C, you might set function pointers during app startup. In C++ or Java, you might use different implementations of an interface or of an abstract class. In D, you can do many of the same things as other languages. You can also put all of your variable code paths in one class, rather than subclasses or different interface implementations, and let instances configure themselves in the constructor using delegates.
Here’s a simple example that configures an instance of a class based upon the value of a static counter:
// selfdelegate.d
import std.stdio;class Printer
{
public:
this()
{
if(count++ == 0)
print = ¬hingPrinter;
else
print = &somethingPrinter;
}
void delegate() print; // delegate configured during instantiation
private:
void nothingPrinter()
{
writefln(”Nothing.”);
}
void somethingPrinter()
{
writefln(”Something”);
}
static int count = 0;
}void main()
{
Printer p1 = new Printer;
Printer p2 = new Printer;
p1.print();
p2.print();
}
Here’s a sample execution:
C:\projects\D\tests>dmd -run selfdelegate
Nothing.
Something
If you have many methods that need to be configured, you may prefer to use a factory and instantiate different implementations of an interface. That approach limits you to some extent, however.
For example, consider an OpenGL renderer interface that has three implementations: an advanced version, an intermediate version requiring at least version 1.x of OpenGL, and a legacy version for OpenGL 1.1. What if the user’s graphics card doesn’t support a few of the extensions used by the advanced version, but does support most of them? With the set up described, you’d have no choice but to fall back to the intermediate or legacy version. Wouldn’t it be better if you could make use of the advanced features that are supported and use fallbacks only for those that aren’t? There are several different ways to mix and match like that. Using delegates for a class to configure itself at runtime is one you might not have thought of.
Technorati Tags: D Programming Language, delegates