Part 2: Interfaces are not worth the classes they are written on - Justin Lovell's Blog
in

dotnet.org.za

South African .NET Developer Portal

This Blog

Syndication

News

Search My Blog

<input class="BlogSearch" type="text" name="searchBox" id="blogSearchText" value="" onkeypress="return blogSearch(event, this);"> <input type="button" value="Search" onclick="return blogSearch2('blogSearchText');" class="BlogSearchButton">
Powered by Google

Justin Lovell's Blog

The Grumpy Coder

Part 2: Interfaces are not worth the classes they are written on

Wow! In my last blog post about interfaces and base classes, I got quite a bit of comments which I think my primary point has been overlooked. I’m just going to repeat myself to ensure my intentions are made clear: I’m not against the idea of interfaces. I’m just against the idea of making the contract of the “workable” class in every single factory, strategy and so forth patterns as an interface.

 

Maybe I should stop everyone and stop treating everything literally in the phrase “program to interfaces.” I’m not sure where to begin citing through all of my thoughts to be written down but allow me to respond to Peter’s comment. I’m just going to quote some bits and pieces for making reading easier for you guys and girls. (My sincere apologies to Peter if I take anything out of context – I did try to take every care to ensure that this won’t be the case and if you feel that I have done so, let me know so I could try rectifying it).

 

Peter Munnings:

An interface and a base class are two totally different things and are used for two totally different reasons. Yes there may be some overlap in that if you create an abstract method in a base class it "looks" like an interface method, but they are different.

 

To say the one is better than the other is like saying as the previous responder said "grass houses are better than igloos". It all depends where and for what you are using them.

 

In the physical code and in the physical compilation of the code, yes they are completely different with some overlap. But after looking at the end product and comparing the two, I fail to see your point in comparison to the end product. Allow me to elaborate: your interface defines members of what the class must implement. With an abstract class, it will tell the inheritor to which members it must implement and the possibility leaving some members optional to “implement” (or should I say “define”). However, it will still have public members for client code to interact with. And this is where I define that both have defined a contract (or the “interface”) at the end of the day.

 

With that aside, allow me drive home my point of not treating that one phrase to the literal meaning and point out the similarities between the two. Programming to a base class and programming to an interface both concur:

 

  1. Not knowing what the concrete class is.
  2. Only ever knowing what the concrete class’s contract is.

And that is the end of the road between the similarities because that is EXACTLY what the interface can only do and nothing more. The other things that base classes can do are:

 

  1. The public methods may only be a set of code which uses other members (abstract or virtual) to compile its action and/or return value. To be fair to the interface approach, there is nothing stopping the implementer doing the same thing but the advantage with base classes that the possibility of writing less code with protected members which are used cleverly enough. With the interface approach, unfortunately, all the members are kept public. [I will sit through one of the projects that I’ve done and see maybe if I can post an online code example from it].
  2. The base class can ensure that it is only interacted under a certain context. (Very unlikely but is possible).
  3. Providing overloads are as easy as counting one to three. For example, if you have optional parameters or default parameters, it would be convenient to have that on the base class – having that with the interface approach will require a lot of manual labor.
  4. Shall I continue?

If you would like to use other situations on the comparison of what I’m doing with interfaces vs. base classes, then the shelter example is great. I can treat the grass house like a base class and the igloo as the interface. I could put that grass house almost anywhere else in the world without much modification to the “design.” However, an igloo can only stay in an ice desert (essentially what the Polar Regions are) because it would obviously melt when there is moisture in the air and/or when the temperature is high enough. There is nothing stopping me placing a grass house where the igloo can exist but for me to provide that warmth to inhabit it, I would need to use more grass. Back in the software world, yes sometimes interfaces are better in terms of practicality but base classes can do exactly what interfaces have to offer. At a later stage in this post, I will defend interfaces since I do use them.

 

Peter Munnings:

The fundamental difference between an interface [and a base class] is that interfaces define contracts between classes whereas base classes define the "look and feel" of a class.

 

I would half disagree. Abstract base classes define what the inheritors’ contracts are. And the only time the “look and feel” becomes so apparent, in my opinion, is when a class’s contract becomes vague. As stated in my previous post, interfaces which are used on classes by not-so-experienced developers run the risk of making the class’s contract vague. Having base classes, you can ensure contracts do not become vague (please read later to see what I mean).

 

I do have one thing to admit now where there is a subtle difference between base classes and interfaces. (It is so minor but I do have the urge to mention it). By right, in .NET, every single object inherits from the System.Object class. So by right, all interfaces should be expected to derive from System.Object. I would have to tell you right here that you are wrong. In C#, it makes the same assumption as what I just mentioned because it is guaranteed. But all the strict VB.NET coders will tell you otherwise. When they interact with an interface, they don’t see the GetType or the ToString methods which are defined by System.Object. Essentially, interfaces are not guaranteed to be an object… like in the C++ world.

 

Peter Munnings:

If I was writing a consumer of an Orchestra Application I would want to know what IMusician looked like - that would define my interaction with the musicians in the orchestra. The Musician Base class would define what each of the child musician classes would look like (even if the whole thing is Abstract). It would be pointless making the musician base class available to me as a consumer - I want the Interface so I can write my consumer classes.

 

With all of what was mentioned above, there are no differences for the consumer when it comes to programming to base class or an interface because you are essentially “programming to an interface.” The key difference of the advantages lies directly on the declarer (the framework/component) if they use base classes.

 

I never said that I was against every interface in the first place. They do have their uses… but let me tell you in a nutshell that interfaces should not define business protocols; they should either enhance it or perform in utility operations. Defining IMusician is essentially declaring a business protocol – you will probably have actions/methods on there such as Play, Stop and Pause and have properties such as Speed, Melody and Volume. A good example of a utility interface, and although somewhat unrelated to Peter’s example but very efficient, is IDisposable – it has one simple method which allows the class to help manage resources.

 

A good example of example, and related to Peter’s example, of an enhancement interface is ISolo which can have two methods: GoSolo and ResumeNormal methods (mind the later terminology – I’m not a big music fan).

 

The reason that I’m against interfaces being used to describe business protocols are for the sole reason that the following situation may occur. Experienced developers won’t fall in this trap but I want to show how others do. Let’s assume that our application evolves a bit and allows actors. So we define an interface called IActor. Now let’s say that we evolve the application to support musicals. Since a musical actor is an actor and a musician, the not-so-experienced developer will implement both of these interfaces (IMusician and IActor) on a single class.

 

Maybe the better choice is to implement the IActor and in its methods amidst the physical actions the actor may take up, call the music-related brokers (that control volume, tune and the physical song data). Maybe it would be better to have another two interfaces added which can enhance the IActor: ISingable and IDancer since not all actors sing and neither do all actors dance but with some actors, they may take on the two roles. Maybe… and it goes on the context of the problem but my point is that implementing two or more “major contracts” is 98% of the time, the wrong foot to start off to. Having a base class forces the hand to play on implementing only one major contract on the objects.

 

The only time that I would find exception to ‘my rule’ is under a distributed system. No matter what methodology (SOA, MSMQ, and so forth); the application server will only be touched by experienced developers so my rule becomes obsolete because my reasoning is not backed up. But this is another field altogether to discuss here but I just want to acknowledge that there are times that my rule is under exception.

 

Before I start asking questions, I would like to just ‘demonstrate’ my methodology in response to Scott Dukes comment.

 

Scott Dukes:

I feel that it is generally better to separate the interface from the implementation. This gives me the flexibility to create a completely divergent implementation without affecting any of my existing (implementation) classes.

 

A good example of this can be found in the System.Collections namespace. If you look at DictionaryBase you will see this in practice. It is an abstract class which implements IDictionary, ICollection and IEnumerable interfaces. It is quote: "provided to make it easier for implementers to create a strongly typed custom collection."

 

Then look at the Hashtable class. You will see that although it implements the same interfaces (plus some others) it is not inherited from DictionaryBase.

 

I am in complete agreement with you that the System.Collections namespace is an ideal study point. Ok, with what I just discussed, IEnumerable is just an enhancement upon the collection or the dictionary by exposing an enumerator for iterating through the collection or dictionary. I think we will have complete agreement over here, no?

 

As far as the difference of ICollection and IDictionary, I really don’t have a solid answer because this is really border-line. In fact, I can’t even argue the decision of not going with base classes nor argue the vice-versa. I’ve seen classes behave as a dictionary and a collection at the same time. The testimony to this is the DataTableCollection class. But I digressed from my motive of not mixing “major contracts” together because that is exactly what they have done: only implemented the ICollection interface; not the two (IDictionary and ICollection).

 

But I would assume the main reason for going interface driven is because of remoting (Web services, and so forth). Can anyone think of any reason why to go with interfaces over base classes in the System.Collections namespace?

 

And yes, I’m in full agreement with Scott that sometimes, I do go with the hybrid approach myself. But for 70-85% of the time, I find base classes to be sufficient, faster and easier to code to over interfaces just because of the pure “work-load.”

 

I think I’m would have to stop over here because this post is a whopping 2100+ words. I’m also stopping so that I can get a chance for some feedback at this moment because I’ve been holding and revising this post for too long. Any comments, suggestions, and/or debates – I welcome any insight. And if you have a book suggestion, it will be much appreciated because at the end of the day, I will protest till I have the full truth and understanding of the complex subject… if you know what I mean. :-)

Published Apr 25 2005, 07:58 PM by justin
Filed under:

Comments

 

Brian Wilson said:

Justin, great blog! Here are some of my thoughts...

The big advantage of using interfaces is
that they extend the use of polymorphism beyond the class hierarchy.

I looked up two examples that maybe we could discuss. People, please have a look and let me know how you would implement the examples below!!!

- imagine you are responsible for writing an ATM application for a bank. Thru your application you will allow users to Deposit, Withdraw and check their Balance for Checking accounts and Savings Accounts. No matter what
kind of account your application handles, it needs to execute those three
operations. You can sure derive Checking and Savings from an abstract
BankAccount that contain the necessary members. Now imagine that in the
future, your ATM application may also be used to access Credit Card accounts
and that the CreditCard class is not in the same inheritance hierarchy as
the BankAccounts. You still need to force it to have the Deposit, Withdraw
and Balance members. An interface is the perfect solution here.

- another example. You are probably aware of the Sort method for the Array class. It sorts data in a single dimension array. Remember that arrays can be of any type: integers, strings, Animals, BankAccounts, etc. The Sort
method does not care about the data type. It access the underlying object thru the IComparable interface. Therefore, to make your classes sortable, you need to implement the IComparable interface. This has nothing to do with inheritance.




April 26, 2005 8:42 AM
 

Brian Wilson said:

Wanted to make one more point:

C# does not support multiple inheritance of implementation eg. C++ style multiple inheritance. So you are limited to extending from a single class. Interfaces are much more flexible in that you can implement more than one interface.

If you have a well defined contract that will be implemented by many classes use an interface. If the contract is evolving, as you illustrated quite often, consider using a base class. Use a base class if you need to
include implementation details.

One last thing, re: base classes versus interfaces. Consider this example:

Lets say you wanted to make a Plugin architecture to your application where 3rd party developers could develop components for your app to use at runtime. Would you be willing to give them the class or would you
rather just tell them about the interface? :-)
April 26, 2005 8:59 AM
 

Craig Nicholson said:

Too many words... eish.. need to schedule time to read this post. :p
April 26, 2005 11:39 AM
 

Justin Lovell said:

I'll get back to you with another blog post... the response is 900 words thus far. :-/.
April 28, 2005 9:41 AM
 

TrackBack said:

April 29, 2005 8:18 AM
 

TrackBack said:

April 29, 2005 8:56 AM
 

Hilton Giesenow said:

Hi Justin,

Just a quick cross-blog post to let you know I'm really enjoying this discussion, thanks for some great coverage of the topic.
April 29, 2005 11:31 AM
 

TrackBack said:

April 30, 2005 11:22 PM
 

TrackBack said:

April 30, 2005 11:25 PM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add
Powered by Community Server (Commercial Edition), by Telligent Systems