Programming to Interfaces simplification

Frustrated c1514843 at drdrb.com
Mon Feb 24 13:24:00 PST 2014


On Monday, 24 February 2014 at 18:59:32 UTC, Steven Schveighoffer
wrote:
> On Mon, 24 Feb 2014 11:36:50 -0500, Frustrated 
> <c1514843 at drdrb.com> wrote:
>
>> http://dpaste.dzfl.pl/c25655e2dfe9
>>
>> The code above simplifies using interfaces as the programming
>> object. It allows one to program the derived classes as if they
>> were not part of an abstraction by mapping the abstracted 
>> virtual
>> methods to concrete methods.
>>
>> e.g.,
>>
>> class WindowsGui : iGui
>> {
>> 	WindowsButton _button;
>> 	@property WindowsButton button(WindowsButton b) { return
>> (_button = b); }
>> 	
>> 	mixin(Fixup!(WindowsGui, iButton, WindowsButton));
>> }
>>
>> instead of
>>
>> class WindowsGui : iGui
>> {
>> 	WindowsButton _button;
>>          @property iButton button(iButton b)
>>          {
>>              assert(cast(WindowsButton)b !is null, `Invalid 
>> object
>> type dependency mismatch! Type: `~b.classinfo.name~` Type
>> Expected: WindowsButton`);
>>              auto bb = cast(WindowsButton)b;
>>              // do work with bb.
>>          }
>> }
>
> Nice work!
>
>> One problem with the template is that b.classinfo.name returns
>> the interface instead of the actual class.
>
> Hm... classinfo (now typeid) should get the most derived type 
> from an instance. This may be a factor of it being an interface 
> instance vs. a class instance. A simple test:
>
> Stevens-MacBook-Pro:~ steves$ cat testinterface.d
> import std.stdio;
>
> interface I
> {
> }
>
> class C : I
> {
> }
>
> void main()
> {
>     I i = new C;
>     writeln(typeid(i).name);
>     writeln(typeid(cast(Object)i).name);
> }
> Stevens-MacBook-Pro:~ steves$ ./testinterface
> testinterface.I
> testinterface.C
>
> Looks like that is the case. Note that classinfo is not part of 
> the language any more, and will likely be deprecated. typeid is 
> the correct mechanism to get the TypeInfo of a derived class.
>
> I'm thinking this is incorrect, typeid should get the derived 
> class type IMO. It shouldn't be that difficult or costly for 
> the compiler to do.
>

Thanks. Now the correct type is known. One could, for example, 
look for wrappers/adapters/etc to get a linuxbutton into a 
windowsbutton(if so desired, throw a well informed error, etc.

Hopefully though, now you see the point. It is a runtime contract
that you make since you can't specify it at compile time(since D
doesn't supports it).

In any case the mixin needs some work and testing. Would just
like to get the proper class name for the type. It is, at the
very least, a proof of concept.

Unfortunately the main downside is the vtable is twice as big. 
Final or static methods could be used for this. If the compiler 
could manage such a system it could do the job better. (There 
would be no extra functions needed and the calls would be faster)




The issue is this: I want to program to interfaces(requiring the 
class(WindowsGui) to use base interfaces(iButton) to satisfy the 
interface.

The problem is this compile time contract is to generic and makes 
coding the classes more verbose. The mixin reduces the verbosity 
and provides a runtime contract(we enforce it using asserts in 
this case).

The benefit of the mixin is that coding WindowsGui is simpler and 
more direct and it's dependency on WindowsButton(not iButton) is 
known at compile time(But enforced at runtime by assert). Would 
you not agree? Everything else is essentially identical.


More information about the Digitalmars-d-learn mailing list