www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Equivalents to policy classes in D

reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
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
Apr 02 2012
next sibling parent "Henry Robbins Gouk" <henry.gouk gmail.com> writes:
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());
}
Apr 02 2012
prev sibling next sibling parent Jacob Carlborg <doob me.com> writes:
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
Apr 03 2012
prev sibling parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
Thanks to all for the useful suggestions here.  I'll have a play with the ideas 
suggested and come back if problems arise ... :-)
Apr 04 2012