13

Recently I began working on a largish mainstream project to deliver a public-facing e-commerce platform for a client I cannot reveal.

I'm working with seasoned developers with many years experience across many projects in the City of London.

It seems everyone is into interfaces in a big way. It's overwhelming and I now doubt everything I've done before, which is to use abstract base classes.

.NET is not COM, it's not an interface-based programming platform. Am I missing something or is this just herd mentality - the years of IProgramming have proliferated as accepted norms in .NET land?

Thanks

Luke

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
Luke Puplett
  • 42,091
  • 47
  • 181
  • 266
  • 5
    There's a good discussion of why they're used so much in both Java and C# here: http://stackoverflow.com/questions/90851/is-it-just-me-or-are-interfaces-overused – Neil Vass Feb 16 '11 at 09:47
  • 3
    Great question, eager to hear the answers - my opinion is that they're overused, or used improperly/redundantly for the most part. – Grant Thomas Feb 16 '11 at 09:48
  • 1
    ".NET is not COM" - quite right, it is in fact ["a better COM"](http://books.google.com/books?id=Kl1DVZ8wTqcC&lpg=PA1&ots=5a7SHDQGWR&dq=The%20CLR%20as%20a%20Better%20COM&pg=PA1#v=onepage&q=The%20CLR%20as%20a%20Better%20COM&f=false) – AakashM Feb 16 '11 at 09:55
  • See also a 3rd possibility Composition over inheritance: http://stackoverflow.com/questions/49002/prefer-composition-over-inheritance – Maslow Feb 16 '11 at 19:05
  • 1
    I also find that base classes can guide the implementer as to how to implement the contract much, much better than an interface. – Luke Puplett Feb 25 '11 at 15:38

7 Answers7

20

Interfaces promote loose coupling, and are easy to mock. They make the separation between API and implementation very clear.

Of course, you can use abstract base classes when there'll be common functionality between different implementations (and there can still be an interface on top of the abstract class if you want) but if everything in the abstract class is abstract, and there are no fields, why use up your one shot at inheritance by way of an abstract class? Where's the benefit?

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Hi Jon, thanks for getting stuck in. I'm surprised at your opinion because it isn't harmonious to the "official" .NET Type Design Guidelines - http://en.csharp-online.net/.NET_Type_Design_Guidelines%E2%80%94Choosing_Between_Class_and_Interface – Luke Puplett Feb 16 '11 at 09:56
  • 2
    @Luke - I don't think that counts as "official" guidelines, and `Stream` is a bad example because the abstract base class has a lot of implementation - i.e. you can implement a `Stream` by overriding a **few** things, or by overriding **lots** of things. – Marc Gravell Feb 16 '11 at 09:59
  • 2
    A book such as that, written by the guys that wrote the BCL, contributed to by "the Gods" of .NET, being discounted so readily makes me sad, Marc. – Luke Puplett Feb 16 '11 at 10:03
  • @Luke: Bear in mind that there are different contexts for different situations. The only argument given in favour of abstract classes is that you can add members to them later... but you can't add *abstract* members of course. I'd also say that for *most* developers, they have control over all client code so they *can* extend interfaces at a later date, by adding to all implementations at the same time. Relatively few people are publishing code to the rest of the world. – Jon Skeet Feb 16 '11 at 10:14
  • Jon, the fact that most interfaces are internal to the entire app (and so can be altered) is the only argument that supports the current trend. But it avoids dealing with their misuse (IMO) that interfaces are for behaviours that can apply to many types. – Luke Puplett Feb 16 '11 at 10:20
  • 1
    @Luke: I don't think it's "the only argument that supports the current trend" - interfaces are also more flexible than abstract classes in terms of inheritance, as they don't "use up" the one chance at inheriting from another class. Imagine if `IComparable` were an abstract class, for example... it would be horrendous. – Jon Skeet Feb 16 '11 at 10:29
  • 3
    @Jon - IComparable is a behaviour - it would never be a base class; I think you're misunderstanding the correct and incorrect use of a base class. I can't believe I'm arguing with you. But I'm on Microsoft's side here. – Luke Puplett Feb 16 '11 at 10:42
  • @Luke: Well you've not given any *examples* of where an interface is being used inappropriately. You've just said you prefer to use abstract classes instead of interfaces. I've said that unless I've actually got *some* concrete behaviour to put in the abstract base class, I prefer the flexibility of interfaces... because if there's nothing concrete, then *all* you're specifying is capabilities, and that's what I believe interfaces are there for. Abstract base classes are good for reusing common state and behaviour, but when I only want to define capabilities, interfaces are great. – Jon Skeet Feb 16 '11 at 10:49
  • In particular, you claim I'm "misunderstanding the correct and incorrect use of a base class" - could you pinpoint what I've said that leads you to that conclusion? – Jon Skeet Feb 16 '11 at 10:50
  • 1
    @Jon - "interfaces are also more flexible than abstract classes in terms of inheritance, as they don't "use up" the one chance at inheriting from another class" -- that, to me, supports my thinking that an interface is a behaviour, that can apply to many types, and so having an interface at the root of all core/shared types is wrong - and is what I am seeing out in the field today. – Luke Puplett Feb 16 '11 at 10:54
  • What do you mean by "at the root of all core/shared types"? Could you give an example? What sort of interface are you thinking of? – Jon Skeet Feb 16 '11 at 11:17
  • 2
    Sure, I'm seeing that anywhere a type is to be shared between libraries, and often where they're not, the programmer begins with an interface. I'm 8 vs. 1 at this contract. There are intefaces for everything --my hunch is that it is a social phenomenon +Unit Testing steering bad architectural decisions. – Luke Puplett Feb 16 '11 at 11:23
  • @Luke: That's still not a very concrete example. What is this type? Is it primarily a data "model" kind of type (in which case I'd often go straight for a concrete class) or a service of some kind? If you made it an abstract base class instead of an interface, what non-abstract members would you include? – Jon Skeet Feb 16 '11 at 11:25
  • @Jon - I can't go into detail, but from discussions here, it seems that people think that any type that is to be shared between assemblies is backed by an interface. They seemed to think that an interface is the only mechanism by which loose coupling can happen and when I've explained how the same principle works for base classes (that they're both contracts to memory references) they then get it. It seems "the collective" is forgetting! – Luke Puplett Feb 16 '11 at 11:51
  • We should close this question since Neil Vass' link to http://stackoverflow.com/questions/90851/is-it-just-me-or-are-interfaces-overused is the same debate. In fact the referred question/rant is exactly how I feel. – Luke Puplett Feb 16 '11 at 11:52
  • @Luke: It's hard to decide whether or not we actually disagree then. Personally I don't find myself using abstract classes very often though - if something represents some sort of service dependency, an interface is appropriate. Other types *tend* to be concrete data classes. There are exceptions of course - and the devil is in the details. – Jon Skeet Feb 16 '11 at 11:52
  • 1
    Had to check back - this is ridiculous. I've even seen interfaces on XAML views!!! It's herd mentality, I swear. Monkey see. Monkey do. – Luke Puplett Jun 23 '11 at 17:04
  • 1
    @LukePuplett why don't you ask the author's of that XAML why they are doing it, instead of spewing forth about a decade+ old language feature. Might solve your question better _and_ save on feather ruffling. – Gusdor Nov 14 '13 at 11:43
  • @Gusdor They gave all the types of misguided answer as we've seen here. And is debate just feather-ruffling to you? – Luke Puplett Nov 15 '13 at 13:48
  • @LukePuplett it is certainly polarising! Arguably, the question was fully loaded - there is no satisfying answer here. – Gusdor Nov 15 '13 at 13:56
  • @Gusdor Some people will read this and find relief that they're not the only ones thinking interfaces are abused in .NET. The .NET team intended for base classes to trump interfaces for polymorphism and interfaces to be used for cross-cutting behaviours. But the common myth I really want to dispel is that interfaces are the de-facto weapon of choice for polymorphism, which is plain wrong. – Luke Puplett Nov 15 '13 at 14:11
  • @LukePuplett As Jon noted above, it really depends if you are providing implementation. – Gusdor Nov 15 '13 at 15:09
  • 2
    @LukePuplett: It seems to me then that you've "asked a question" in order to propagate your own point of view, which isn't really the point of the site. Can interfaces be abused? Absolutely. Can they be *underused* as well? Absolutely. I'm not sure where you get the idea that "The .NET team intended for base classes to trump interfaces for polymorphism" or even what that would mean. But I still maintain there are plenty of benefits from completely separating API from implementation. – Jon Skeet Nov 15 '13 at 15:38
  • @JonSkeet Read the entire page here: http://www.developer.com/design/article.php/10925_3573356_3/Type-Design-Guidelines-for-Reusable-NET-Libraries.htm "DO favor defining classes over interfaces." and "DO use abstract classes instead of interfaces to decouple the contract from implementations." – Luke Puplett Nov 21 '13 at 14:00
  • @LukePuplett: Interestingly I can't find nearly as much evidence of the bias towards abstract classes in the more recent version of the class library design guidelines in MSDN: http://msdn.microsoft.com/en-us/library/ms229036(v=vs.110).aspx I still don't see what the purpose of the question is though. These days I probably wouldn't have bothered answering it - and I suspect it would have been closed as being opinion-based very quickly. Were you actually hoping to learn something, or just get people to agree with you that interfaces are overused? – Jon Skeet Nov 21 '13 at 14:06
  • @JonSkeet At the time, I wanted to see how people felt, how the community felt and to demonstrate that interfaces are not the only way (as my then team believed). This may not help you, Jon, but 99% of programmers aren't as smart as you or probably your colleagues, so there is still very much merit in this question for other programmers. SO is full of opinion, for what else is "best practice" and is partly what the voting system is there for. – Luke Puplett Nov 21 '13 at 14:14
  • @LukePuplett: But you didn't in any way "demonstrate that interfaces are not the only way" - you just denigrated those who like interfaces more than you do, by calling it "herd mentality" and assuming that you're smarter than your colleagues. It would have been a much better question if asked neutrally. I don't see how that helps anyone - and I doubt that this question will actually have changed anyone's mind on anything. While there is room for opinion as *part* of many questions, questions which are *primarily* opinion-based such as this one are generally closed quickly these days. – Jon Skeet Nov 21 '13 at 14:18
  • @JonSkeet Probably the question would be closed these days. We're talking about an almost 3-yo question. Looking back, the question lacks context; I still recall the 'craziness' I was seeing in the code back then but that's not conveyed, no. I was probably frustrated when I wrote it. It's done now. I must add, there's nothing wrong with assuming that you're smarter than your colleagues, else, we should never go for a promotion, take the lead, write a book, blog, answer SO questions, for that would be presumptuous. That's cobblers and I think you're trying to portray me as arrogant. – Luke Puplett Nov 21 '13 at 14:29
  • @LukePuplett: I think it's best to stop the discussion at this point. – Jon Skeet Nov 21 '13 at 14:31
4

Abstract Classes and Interfaces have two different uses.
The first ones are used to provide Father/Child inheritance.
The second ones are used to specify a specific behavior to implementing classes.
I Agree Interfaces are too frequently used for the wrong reasons IMHO.

EDIT :
Besides, the extensive use of interfaces may result in boxing/unboxing issues :
This may occur when a value-type implementing an interface is passed to a method having the interface-type as its parameter. I personnally had to face that issue and refactored the code to get rid of interfaces(though it was convenient for API concerns) to gain performance, as the class at issue was used and passed millions of times during runtime.

Mehdi LAMRANI
  • 11,289
  • 14
  • 88
  • 130
  • This has been my way of thinking to date. Interfaces are behaviours. I am a human (Human.cs) and my many behaviours are interfaces, (IDrink.cs, ISleep.cs, IBeMerry.cs) – Luke Puplett Feb 16 '11 at 09:59
  • 2
    @Luke: Exactly. So what is the advantage of saying "I need concrete object X" or "I need an object that inherits from Y" rather than "I need an object that is capable of A" or "I need an object that is capable of B and C" etc? Surely what you should care about are capabilities rather than implementation details. – LukeH Feb 16 '11 at 10:06
  • @LukeH : You could also inherit from "Mammal" class which inherits from "LivingBeing", and implement just "IThink" and "ILaugh" as specific interfaces, so you do not have to redefine "IBreath" and "IEat". It's a design choice. Depends of whether you have members/defined methods in Parents or just abstract methods (as stated in other posts) – Mehdi LAMRANI Feb 16 '11 at 11:03
  • 1
    Yes, of course, but again that's just an implementation detail. The surface of the API shouldn't care *how* you implement `IThink`, `ILaugh`, `IBreath` or `IEat`, only that you actually *do* implement them. Go wild with (abstract) base classes etc -- whatever mechanism helps you get the job done -- but code your APIs to the interfaces. – LukeH Feb 16 '11 at 11:14
  • @LukeH : Good Point for the API. There's an Interfacing/Design Logic trade-off depending on your priorities. – Mehdi LAMRANI Feb 16 '11 at 14:04
2

It all depends on what you want to achieve. The main difference between interfaces and abstract classes being that a class can inherit multiple interfaces but only a single abstract class. So both have their own purpose.

anothershrubery
  • 20,461
  • 14
  • 53
  • 98
2

Abstract and Interface have their different uses.

A class that is derived "is" something. A class implementing an interface "can do" something.

Classes derive from a base class because they want to specifically inherit the parent's implemented features and behaviour. This can further be chained, because there can be a need for a group in the family to retain a common set of reusable behaviour, while another group branches off to implement a different set of common behaviour.

e.g. the System.Web.UI.Control family of classes - all have common functionality for ASP.NET server controls, but implementations further down the family differ greatly. But they still render HTML to the web page at the end of the day.

Interfaces on the other hand simply define what you expect a implementing class to do, not exactly to resemble. There is no hard definition as to how to achieve those capabilities. In fact the implementations may well be done to achieve wildly different things for the main system, but structured in a templated manner (the Interface) to allow the system to manage them all in a standard way.

e.g. IHttpModule, Providers, System.Runtime.Remoting.Channels, etc.

icelava
  • 9,787
  • 7
  • 52
  • 74
1

Interfaces specify a capability of a type, not an inheritance relationship. "Good" examples of interfaces are those that encapsulate quite general concepts that possibly apply to a wide range of very different concrete types that may have nothing else in common (think of IComparable or IEnumerable).

It is not always easy to decide what is "the right way" to go, using a class hierarchy or an interface-based approach. I consider interfaces to be one possiblity to raise the level of abstraction: Instead of specifing a method that requires its argument to be part of a certain class hierarchy, you just state what abilities the passed object should exhibit (e.g. sortability). This often allows you to formulate algorithms in a more generic way.

Frank
  • 2,738
  • 19
  • 30
0

Using interfaces is very much an OO paradigm. Interfaces can abstract implementation to allow for more comprehensive testing, scalability and more easily build component-based (which makes apps more extensible) applications.

Of course the use of interfaces will vary depending on requirements (eg non-functional: must be able to build unit tests for each layer of an n-tier application).

Multiple devs can work on the same app and not care about how the other devs will implement their components, but know what to send and what to expect back again.

One advantage of base classes over interfaces is you can share functionality in all objects in a particular layer (say for a tiered architecture). Eg. validating common fields or converting a commonly used data type.

Russell
  • 17,481
  • 23
  • 81
  • 125
  • Thanks Russell, but I think Base classes provide this same paradigm. – Luke Puplett Feb 16 '11 at 10:00
  • 1
    They can, however the interface (by design) can be distributed before any implementation takes place. This allows, for example, tests to be created before or parrallel with implementation instead of waiting for the base class to be created. Of course you can do the same with leaving empty base class methods, but that is why its a paradigm/pattern and not a concrete rule. – Russell Feb 16 '11 at 10:05
  • Like the Framework itself, I do the latter. I supply a core lib of base classes. For instance a logging class has all the usual which all call down to a protected virtual WriteLog which is then where the implementation is done in the concrete class. I've never had a problem designing and using good base classes. – Luke Puplett Feb 16 '11 at 10:14
  • Sorry Russell, I voted you up by accident and have cancelled it. I don't think your use of interfaces goes any further than base classes but has all the limitations of interfaces. – Luke Puplett Feb 16 '11 at 10:57
  • Oh ok, my answer was in response to the use of interfaces in .NET, as I read your question as to why interfaces are still used in .NET (as in the title), not why interfaces should be used instead of base classes. – Russell Feb 16 '11 at 11:07
  • No worries. I mean no ill gesture. I just think the collective mind of our community is on the edge of forgetting how to properly write a base class and use it. – Luke Puplett Feb 16 '11 at 11:29
  • Cool, thanks for clarifying. :) In my experience base classes "evolve" throughout a project, every time someone creates a method *Can it be used by all other classes in that layer?* If yes, it is put in the base class. – Russell Feb 16 '11 at 20:47
-1

Programming to interfaces is core OO principle. It enables you to build in Dependency inversion/inversion of control - ie implementations don't directly depend on other implementations - instead, they depend on other Types . What this does is make it easy to plug in/plug out parts of your system. It also enhances testability of the system, since its easy to provide mocks conforming to an interface if all your implementation cares about is the interface. Also, having a system described in terms of a few interfaces also makes it easier to understand the overall policies of the system. Trying to divine this from a bunch of base classes that have implementation details just makes it a little more harder.

Abstract base classes are really nothing more than a way to share implementation that is common between multiple subclasses. But beware of avoiding the interface and directly binding to an abstract base class - what you're doing by that is setting in stone that you not only bind to the interface of the abstract base, but will also always carry around the implementation. There are many times when what seems like a given today is turned around 180 degrees in a few months/years and this the kind of 'permanent' decision that you shouldn't take lightly. The cost of always having an interface is much less, in my opinion.

So in effect, have an interface to document a Type, and if among the implementors of the type you see a lot of potential code reuse, create an abstract base that inherits from the interface. THe abstract base could also introduce pure virtual hook methods that are really the implementation details that and provide convenience and code reuse.

Finally, you might be frustrated if your interfaces arent right - in that case, they just make things harder (ie you have all the additional work of interfaces and none of the advantages and then they feel plain wrong) - but given by what you're saying, this doesn't look like to be the case.

Full disclosure - I'm not a .NET developer. I'm a java/python developer though I have decent exposure to .NET. There's far more .NET developers at my workplace than Java devs - and we have these discussions quite a bit. As an aside, I find this sentiment that interfaces are overused more prevalent in the .NET world rather than among Java devs - but that's just my perspective.

Raghu
  • 1,140
  • 1
  • 14
  • 22
  • Your initial assertion makes it sound like you can only do IoC with interfaces, which is wrong and what I see everywhere. You can have a constructor wanting a BaseBirthdayService and then 'inject' (urgh) your concrete FacebookBirthdayService which has been instantiated in a library that isn't referenced by the library in which the ctor is declared. Btw, if you've put a lot of implementation in the base class, then you're writing bad base classes. – Luke Puplett Apr 16 '12 at 20:37
  • hmm - thought the trade off with abstract bases was clarified in the second para, but maybe not:). It's a long term commit that is not easy to get out of and all you get is some implementation reuse. Consider what happens if your BaseBirthdayService has public non virtual methods because it seems like a good idea today. It could change and you'd be stuck. To avoid that, if you make all your public methods virtual, them IMO you're better off defining an interface and making the contract crystal clear. – Raghu Apr 24 '12 at 08:00