Sign in to follow this  
LordShade

[.net] Interfaces, interfaces, interfaces

Recommended Posts

I've been a C++ guy since forever but I've taken the plunge into C# and I'm liking it. Back when I first started writing OO games I'd make derived classes and more derived classes. As you can imagine, the heirarchy trees would get pretty deep. Then along comes COM. I used this for many years in my "job" but during that time I couldn't bring myself to work on game dev in my off hours. I'm sure some of ya know what I mean. Although, during that time, I was beginning to see the power that interface programming could bring to game programming. So I haven't done professional programming for several years now, burnt out, but I'm dipping back into the pool with C#. Recently I have discovered how truly effective interface architecture can be. It's late and I'm rambling. If you find yourself having massively deep heirarchy trees, do yourself a favor and try working in interfaces. You'll be surprised how elegant and yet simple your code becomes. In C#, interfaces are a snap. Granted, I still have a few 'core' classes I'll derive from to inherit functionality but interfaces are superb for things like Physics and Collision/Response. Nothing like coding a whole new object and dropping it into the "universe" and having things just go. :) Happy coding.

Share this post


Link to post
Share on other sites
Interfaces can do some rather crazy things that you wouldn't think would be allowed:


public interface IControlPeerGroup
{
void Add(Control control);
IEnumerable<Control> Peers { get; }
}

public class ControlPeerGroup : List<Control>, IControlPeerGroup
{
public IEnumerable<Control> Peers
{
get
{
foreach (Control control in this)
yield return control;
}
}
}


Notice the IControlPeerGroup interface has an "Add" method that I haven't explicitly implemented in ControlPeerGroup? Somehow, it knows to check the BASE class (List<Control>) for the interface implementation as well. And it works, which is even more scary.

Share this post


Link to post
Share on other sites
I personally like using interfaces and have an abstract implementation class of the interface(or one class that implements multiple interfaces) to help when writing a class that need to expose the interface. That way I don't have to re implement the same interface but if a situation arises where I need to do it differently or whatever, I still have the flexibility. Besides, I think it's cleaner to have other parts of the application only use interfaces it needs and not be tied to a particular base class. Microsoft's XNA 2.0 does things like this as well.

Share this post


Link to post
Share on other sites
Deep inheritance hierarchies are bad mmmkay. Interfaces are good, but little things seem to keep them from being as useful as they should be. Delegate types can't be declared, and they're not duck typed when most of their usage is "give me a type that matches these capabilities."

I find myself using standard abstract base classes more often.

Share this post


Link to post
Share on other sites
I like inheritance and interface combinations. I use inheritance to break up proceedures. ie: I have a base class Initializer that is base for Processor that is base for Renderer. Each class keeps the code seperate from eachother and easier to view and work on. Then I create interfaces so that other, out of assembly (and in assembly) systems can access specific need portions of the object.

I guess I use interfaces like a panel that interfaces a machine and gives access to a specific portion of the machines operation and workings.

And I use inheritance as building blocks for the individual parts of the machine so that it can be broken up into major parts or portions.

I'm a big lover of c#. I used c++ for much of my younger years but can't take my mind off of c#. It's just brilliant. A super language I think. As long as it exposes ways of having the c++ abilities then it can simply replace it all together in my opinion.

But I'm not very learned in c++ and I'm sure others would say otherwise and probably be right.

-Devin

Share this post


Link to post
Share on other sites
Quote:
Original post by Telastyn
Deep inheritance hierarchies are bad mmmkay. Interfaces are good, but little things seem to keep them from being as useful as they should be. Delegate types can't be declared, and they're not duck typed when most of their usage is "give me a type that matches these capabilities."

I find myself using standard abstract base classes more often.


Hmm, I'm not sure I understand this comment. An interface is just an agreement that any object with that interface will support those method calls. You can't define a type in an interface because it is a pure abstract type.

Granted, I still do use inheritance in alot of cases when I need a particular type of functionality and don't want to re-implement it.

ATM, I'm struggling with figuring out how to create an instance of a type if all I know is a string representation of it's name(i.e., Package.Folder.TypeName) and it's module. hehe.

[Edited by - LordShade on April 19, 2008 11:19:07 AM]

Share this post


Link to post
Share on other sites
I want an interface to have an event that takes a string and returns a string.


public interface foo{
delegate string DelegateType(string parameter);
event DelegateType fooEvent;





oops, error. The Func<T> stuff makes that easier but is 3.0 only, and it requires that the delegate specifically match the type, not just the signature.

Plus these don't work:


public interface SomethingWithAName{
string Name;
};

public class Joe{
public string Name = "Joe";
}

public class Bob{
public string Name{
get{
return("Bob");
}
set{}
}
}

SomethingWithAName Someone;

Someone = new Joe();
Someone = new Bob();





And they should. Even if the interface.Name was a property, you can't assign Bob to it since it doesn't explicitly inherit from the interface. This is (imo) very detrimental to their usage.


Quote:

ATM, I'm struggling with figuring out how to create an instance of a type if all I know is a string representation of it's name(i.e., Package.Folder.TypeName) and it's module. hehe.


System.Reflection.ModuleInfo and System.Activator

Though umm... icky.

Share this post


Link to post
Share on other sites
You cannot declare a delegate inside of an interface, but there is no reason you cannot declare it outside of the interface:


public delegate string DelegateType(string parameter);
public interface foo{
event DelegateType fooEvent;
}


the only difference is the external naming of the delegate. (DelegateType vs. foo.DelegateType)

You cannot declare fields in an interface, but there is no reason that you cannot declare properties:

public interface SomethingWithAName{
string Name{get;set;}
};


Fields themselves are an implementation detail and do not belong in an interface.

With C# 3 you can also make extension methods that apply to interfaces, something that may seem trivial, but it can be used to patch some of the holes that the lack of multiple inheritance left in the language.

Share this post


Link to post
Share on other sites
I'm with Telastyn. I only use interfaces when I'm absolutely certain it's something that's going to be multiply inherited. Otherwise I prefer the greater power of abstract classes.

For example, whenever possible I like to use the abstract class to enforce consistent behavior in different implementations. For example the abstract base class may check that a methods arguments are valid, rather than assuming different implementations will do so.

Share this post


Link to post
Share on other sites
Interfaces are nice. They remind me of Haskell type classes. Not watered down but with a different focus that makes them more flexible for traditional OOP programming but less flexible in terms of typeful programming.

Share this post


Link to post
Share on other sites
Quote:
Original post by turnpast
You cannot declare a delegate inside of an interface, but there is no reason you cannot declare it outside of the interface:


Ooh, didn't know that was possible. Don't remember ever seeing it done, but it seems to work.

Quote:

Fields themselves are an implementation detail and do not belong in an interface.


Right, an implementation detail. Why should the interface care if something by that name is a field or a property? As long as it looks like a T and quacks like a T then the interface should be able to use it.

Quote:

With C# 3 you can also make extension methods that apply to interfaces, something that may seem trivial, but it can be used to patch some of the holes that the lack of multiple inheritance left in the language.


Oh yeah, that is super swanky. I was a bit surprised finding after 3.0 came out that it works, but sweet that it does.

Share this post


Link to post
Share on other sites
Quote:
Original post by Telastyn
Quote:

Fields themselves are an implementation detail and do not belong in an interface.

Right, an implementation detail. Why should the interface care if something by that name is a field or a property? As long as it looks like a T and quacks like a T then the interface should be able to use it.


I think I agree with you. It should not matter how the interface is satisfied so long as it is satisfied. Sadly it does not seem to work that way. Still in C# 3.0 you can just declare an automatic property without bothering with the field and get something similar.

Share this post


Link to post
Share on other sites
For my game, IIRC, I used inheritance three times. Once for components (abstract class) and once for states(interface) and once for systems(interface). The rest of the design is composition based. I might go with a more interface aproach later on when I'm going with dll development but that will be a implementation detail, not a design plan.

hth

Share this post


Link to post
Share on other sites
I second the use of component based systems. I recommend you to read http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/

Interfaces are also great when you want to do Unit Testing and Test Driven Development (TDD) in general.

Also Inverse of Control/Dependency Injection may be worth some research,
it is a quite complex topic though.

Share this post


Link to post
Share on other sites
Quote:
Original post by turnpast
Quote:
Original post by Telastyn
Quote:

Fields themselves are an implementation detail and do not belong in an interface.

Right, an implementation detail. Why should the interface care if something by that name is a field or a property? As long as it looks like a T and quacks like a T then the interface should be able to use it.


I think I agree with you. It should not matter how the interface is satisfied so long as it is satisfied. Sadly it does not seem to work that way. Still in C# 3.0 you can just declare an automatic property without bothering with the field and get something similar.

Unfortunately, there are cases when fields and properties DO NOT act the same. For example, you cannot pass a property by reference (Something I have wished I could do before). So even though it might seem like both are ducks, one has a clipped wing and if you throw it off the cliff you will not like the result.

Share this post


Link to post
Share on other sites
Quote:
Original post by Telastyn

System.Reflection.ModuleInfo and System.Activator

Though umm... icky.


Ya, icky is right. But what is cool is let's say I have a website that has a bunch of wizard type input forms and I would like to change the sequence of the pages in the forms. Instead of hard coding this in a C# file I can save the module/type names in a database with an order column, modify the row data and my wizard changes display order.

Share this post


Link to post
Share on other sites
Quote:
Original post by Telastyn
Quote:

Fields themselves are an implementation detail and do not belong in an interface.


Right, an implementation detail. Why should the interface care if something by that name is a field or a property? As long as it looks like a T and quacks like a T then the interface should be able to use it.

It should care because they (fields and properties) are two different framework constructs. They're not 'one in the same', just as a class (object type) and a struct (struct type) are not. It would be bad taste to just have something (the compiler and then later other programmers) assume what you're trying to do, it raises ambiguous cases, something they were trying to minimize when designing C#.

I can dress up like a duck for halloween and go around quacking like one, but I'm not going to fly south for the winter...

Share this post


Link to post
Share on other sites
Quote:
Original post by intrest86
Unfortunately, there are cases when fields and properties DO NOT act the same. For example, you cannot pass a property by reference (Something I have wished I could do before). So even though it might seem like both are ducks, one has a clipped wing and if you throw it off the cliff you will not like the result.


Quote:

It should care because they (fields and properties) are two different framework constructs.


Indeed. Again, an implementation detail that curtails interfaces' usefulness a lot (compared to some mythical dream language).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this