Policy-based Design in D
I'm still a noob when it comes to templates in D (and in C++ for that matter). I have a basic understanding of what's possible, but when people post complex templates on the NG I'm always left scratching my head. Today, I was working on a project and decided I wanted to implement a certain feature using a policy-based design. So I turned to my test folder (which I recently emptied, I do lots of little D tests to figure things out) and implemented policy.d:
import std.stdio;
class Host(T) : T
{
void doSomething()
{
T.foo();
}
}
class GreetPolicy
{
void foo() { writefln("Hello World!"); }
}
class GreetHost : Host!(GreetPolicy) { }
void main()
{
GreetHost host = new GreetHost();
host.doSomething();
Host!(GreetPolicy) h = new Host!(GreetPolicy);
h.doSomething();
}
I can't stop thinking how cool that is. First, I had no idea if I would be able to let Host subclass(T). Second, I was sure the first example usage would work, since that's how I implement Singletons in D. But, the second useage, I wasn't really sure of. I was quite stoked when the script ran and printed "Hello World" twice. I can't wait to wrap my head around more template magic.
Technorati Tags: D Programming, templates, generics, metaprogramming
June 17th, 2006 - 13:17
Hey Mike,
you might want to use mixins and interfaces for it, since you won’t be able to inherit from more than one class.. you could mix policies in after all
June 17th, 2006 - 14:36
I implemented multiple policies without using mixins by making the templated policies members and instantiating them in a constructor. That’s actually my next post.
June 27th, 2006 - 19:38
Look at some of the articles I have posted on code projects which explains policy based design.
e.g
Generic Pool: Policy based design : http://www.codeproject.com/library/Generic_Pool_Design.asp
Queue Manager: Policy Based Design : http://www.codeproject.com/threads/Queue_Manager.asp
Memory Map Class : Policy Based Design: http://www.codeproject.com/file/Memory_Mapped_Class___PBD.asp
March 2nd, 2007 - 19:18
You said you’re using this for singletons.
Can you provide a short example of that?
Im still searching for a templating mechanism which lets me use the new operator instead of having to acces the instance property.
Also I’m still not sure when to prefer one global object over the singleton pattern, maybe you could write a bit about how you work with singletons in D and cover this? I’d find it very cool
March 3rd, 2007 - 16:40
You said you’re using this for singletons.
Can you provide a short example of that?
It’s not really clear what the way I wrote it, but what I was referring to regarding Singletons was the declaration of the template type. Notice the two styles I used in the example:
The first technique is similar to what I had been using to declare templated Singletons (i.e. class MySingletonClass : Singleton!(MySingletonClass) {}). There are a few different ways to declare Singletons. I might write a post on it. Scott Bilas gives an overview of a few different Singleton styles in a Game Programming Gems article he wrote, An Automatic Singleton Utility, which is also available online. It’s C++ code, but can be translated to D with little difficulty.
Also I’m still not sure when to prefer one global object over the singleton pattern, maybe you could write a bit about how you work with singletons in D and cover this? I’d find it very cool
This really boils down to a matter of personal taste. The Singleton pattern, as simple as it is, is likely the least understood and most abused pattern in the GoF book. Some people insist that “globals are the root of all evil” and use Singletons as a means to avoid them. Some people insist Singletons should only be used for objects of which there should only be one instance. Some people avoid them altogether. I honestly fall into the middle camp (only one instance of an object), since that’s the problem the pattern is intended to solve. But to be honest, for I quite frequently just declare a struct with all static methods rather than using Singletons. It’s the same effect.
This is one of those cases where there really is more than one way to skin the cat. But I believe the circumstances of a project should dictate which technique to use and not the programmer’s preference. For example, if I were writing a library for others to use I would try do reduce the number of global objects exposed to the user. Internally, it doesn’t matter. But exposing globals outside of the library really can be evil, as they pollute the user’s namespace and make the library more difficult to use. I would also be hesitant to use them in projects with large teams, since they increase the chance for error. But, I personally would never use a Singleton solely as a substitute for a global because that’s not what the pattern is intended for.
As a general rule, anytime I have a manager class (GraphicsManager, InputManager, or whatever) I use a Singleton pattern (or the bastardized version I mentioned above — structs with static methods). Beyond that, it’s a case-by-case basis.