Thread overview
Equivalents to policy classes in D
Apr 03, 2012
Henry Robbins Gouk
Apr 03, 2012
Jacob Carlborg
April 02, 2012
Hello all,

I'm coming to D from a background programming in C and C++, though I wouldn't describe myself as an expert in either.

One of the C++ techniques I picked up over the last couple of years was the use of policy classes, and I'm wondering how D addresses this issue of combining various small components together to implement a given interface.

D's interfaces seem an obvious starting point, but from the documentation I've read, it seems like each implementation has to be written separately.  So, if I have an interface,

  interface FooBar {
    void foo();
    void bar();
  }

... I can of course write two different implementations,

  class FooBarOne : FooBar {
    override void foo() {
      // Foo function implementation
      ...
    }
    override void bar() {
      // Bar function implementation
      ...
    }
  }

  class FooBarTwo : FooBar {
    override void foo() {
      // Foo function implementation
      ...
    }
    override void bar() {
      // Bar function implementation
      ...
    }
  }

... but suppose that I'd like the foo() function to be identical in both; how do I avoid rewriting the code?

In C++ I'd think of a policy class,

  template <class Foo, class Bar>
  class FooBar : public Foo, public Bar {
    ...
  };

and then have,

  typedef FooBar<FooGeneric,BarOne> FooBarOne;

  typedef FooBar<FooGeneric,BarTwo> FooBarTwo;

... but I don't see how to do something equivalent with D's interfaces and implementations.  Can anyone advise?

Thanks and best wishes,

    -- Joe
April 03, 2012
I'm not all that familiar with policy classes but, if I understand what you are asking correctly, you can provide implementations in interfaces if the methods are final or static.

Is this the sort of thing you mean?

import std.stdio;

interface Foo
{
	final string foo()
	{
		return "foo";
	}
}

interface Bar
{
	final string bar()
	{
		return "bar";
	}
}

template IsInterface(T)
{
	enum IsInterface = is(T == interface);
}

class Policy(T, U) if(IsInterface!T && IsInterface!U) : T, U
{

}

alias Policy!(Foo, Bar) FooBar;

void main()
{
	auto fb = new FooBar();
	writeln(fb.foo(), " and ", fb.bar());
}
April 03, 2012
On 2012-04-03 01:15, Joseph Rushton Wakeling wrote:
> Hello all,
>
> I'm coming to D from a background programming in C and C++, though I
> wouldn't describe myself as an expert in either.
>
> One of the C++ techniques I picked up over the last couple of years was
> the use of policy classes, and I'm wondering how D addresses this issue
> of combining various small components together to implement a given
> interface.
>
> D's interfaces seem an obvious starting point, but from the
> documentation I've read, it seems like each implementation has to be
> written separately. So, if I have an interface,
>
> interface FooBar {
> void foo();
> void bar();
> }
>
> ... I can of course write two different implementations,
>
> class FooBarOne : FooBar {
> override void foo() {
> // Foo function implementation
> ...
> }
> override void bar() {
> // Bar function implementation
> ...
> }
> }
>
> class FooBarTwo : FooBar {
> override void foo() {
> // Foo function implementation
> ...
> }
> override void bar() {
> // Bar function implementation
> ...
> }
> }
>
> ... but suppose that I'd like the foo() function to be identical in
> both; how do I avoid rewriting the code?
>
> In C++ I'd think of a policy class,
>
> template <class Foo, class Bar>
> class FooBar : public Foo, public Bar {
> ...
> };
>
> and then have,
>
> typedef FooBar<FooGeneric,BarOne> FooBarOne;
>
> typedef FooBar<FooGeneric,BarTwo> FooBarTwo;
>
> ... but I don't see how to do something equivalent with D's interfaces
> and implementations. Can anyone advise?
>
> Thanks and best wishes,
>
> -- Joe

Maybe you could use template mixins to implement "foo".

mixin template Foo ()
{
    void foo () {}
}

class FooBarOne : FooBar
{
    mixin Foo;
}

-- 
/Jacob Carlborg
April 04, 2012
Thanks to all for the useful suggestions here.  I'll have a play with the ideas suggested and come back if problems arise ... :-)