Is it the best practice to extract an interface for every class?
Asked Answered
P

13

74

I have seen code where every class has an interface that it implements.

Sometimes there is no common interface for them all.

They are just there and they are used instead of concrete objects.

They do not offer a generic interface for two classes and are specific to the domain of the problem that the class solves.

Is there any reason to do that?

Pean answered 14/6, 2010 at 11:19 Comment(2)
The lack of a generic interface suggests to me that there is no commonality between those classes - interfaces are only useful for classes to implement a specific contract. The CSLA.NET does use empty interfaces for polymorphic behaviour, which all business classes derive from, but that is an excessively OO-designed framework.Jentoft
@Downvoter: Please leave a reason to why you downvoted.Pean
J
42

After revisiting this answer, I've decided to amend it slightly.

No, it's not best practice to extract interfaces for every class. This can actually be counterproductive. However, interfaces are useful for a few reasons:

  • Test support (mocks, stubs).
  • Implementation abstraction (furthering onto IoC/DI).
  • Ancillary things like co- and contra-variance support in C#.

For achieving these goals, interfaces are considered good practice (and are actually required for the last point). Depending on the project size, you will find that you may never need talk to an interface or that you are constantly extracting interfaces for one of the above reasons.

We maintain a large application, some parts of it are great and some are suffering from lack of attention. We frequently find ourselves refactoring to pull an interface out of a type to make it testable or so we can change implementations whilst lessening the impact of that change. We also do this to reduce the "coupling" effect that concrete types can accidentally impose if you are not strict on your public API (interfaces can only represent a public API so for us inherently become quite strict).

That said, it is possible to abstract behaviour without interfaces and possible to test types without needing interfaces, so they are not a requirement to the above. It is just that most frameworks / libraries that you may use to support you in those tasks will operate effectively against interfaces.


I'll leave my old answer for context.

Interfaces define a public contract. People implementing interfaces have to implement this contract. Consumers only see the public contract. This means the implementation details have been abstracted away from the consumer.

An immediate use for this these days is Unit Testing. Interfaces are easy to mock, stub, fake, you name it.

Another immediate use is Dependency Injection. A registered concrete type for a given interface is provided to a type consuming an interface. The type doesn't care specifically about the implementation, so it can abstractly ask for the interface. This allows you to change implementations without impacting lots of code (the impact area is very small so long as the contract stays the same).

For very small projects I tend not to bother, for medium projects I tend to bother on important core items, and for large projects there tends to be an interface for almost every class. This is almost always to support testing, but in some cases of injected behaviour, or abstraction of behaviour to reduce code duplication.

Jentoft answered 14/6, 2010 at 11:46 Comment(2)
The public (non-separate) interface of a class also defines a contract.Fat
I never said it didn't. I was referring in the context of the consumer using the interface as a type, not the concrete implementation's type in their code. This means that their code could receive any other type so long as the contract remains the same. In your situation the implementation of a particular concrete type would need to change, instead of providing a new type. The -1 is a little uncalled for.Jentoft
T
63

No.

Interfaces are good for classes with complex behaviour, and are especially handy if you want to be able to create a mock or fake implementation class of that interface for use in unit tests.

But, some classes don't have a lot of behaviour and can be treated more like values and usually consist of a set of data fields. There's little point in creating interfaces for classes like this because doing so would introduce unnecessary overhead when there's little point in mocking or providing alternative implementations of the interface. For example, consider a class:

class Coordinate
{
  public Coordinate( int x, int y);
  public int X { get; }
  public int y { get; }
}

You're unlikely to want an interface ICoordinate to go with this class, because there's little point in implementing it in any other way than simply getting and setting X and Y values.

However, the class

class RoutePlanner
{
   // Return a new list of coordinates ordered to be the shortest route that
   // can be taken through all of the passed in coordinates.
   public List<Coordinate> GetShortestRoute( List<Coordinate> waypoints );
}

you probably would want an IRoutePlanner interface for RoutePlanner because there are many different algorithms that could be used for planning a route.

Also, if you had a third class:

class RobotTank
{
   public RobotTank( IRoutePlanner );
   public void DriveRoute( List<Coordinate> points );
}

By giving RoutePlanner an interface, you could write a test method for RobotTank that creates one with a mock RoutePlanner that just returns a list of coordinates in no particular order. This would allow the test method to check that the tank navigates correctly between the coordinates without also testing the route planner. This means you can write a test that just tests one unit (the tank), without also testing the route planner.

You'll see though, it's quite easy to feed real Coordinates in to a test like this without needing to hide them behind an ICoordinate interface.

Taranto answered 14/6, 2010 at 12:11 Comment(4)
+1 for Coordinate class example. Interfaces for DTOs are most of time not a good idea.Statue
+1 for this summary: "Interfaces are good for classes with complex behavior... But, some classes don't have a lot of behavior and can be treated more like values and usually consist of a set of data fields. There's little point in creating interfaces for classes like this..."Yukikoyukio
Does the mock point still make sense? With mocking libraries, it's possible to mock even an implementationPreadamite
@L3n I think so. Just because you can doesn't always mean you should. Code needs to clearly express its intent. IRoutePlanner seems useful to me because I can reason about the RobotTank in isolation and know it needs a route planner without my brain needing to get bogged down with the implementation of the route planner. Well chosen interfaces can help you chop a program up into parts that are easier to work with. For example, in a team of programmers, two of you may design an interface. Then, one programmer can make use of it, while other can write a class that implements it.Taranto
J
42

After revisiting this answer, I've decided to amend it slightly.

No, it's not best practice to extract interfaces for every class. This can actually be counterproductive. However, interfaces are useful for a few reasons:

  • Test support (mocks, stubs).
  • Implementation abstraction (furthering onto IoC/DI).
  • Ancillary things like co- and contra-variance support in C#.

For achieving these goals, interfaces are considered good practice (and are actually required for the last point). Depending on the project size, you will find that you may never need talk to an interface or that you are constantly extracting interfaces for one of the above reasons.

We maintain a large application, some parts of it are great and some are suffering from lack of attention. We frequently find ourselves refactoring to pull an interface out of a type to make it testable or so we can change implementations whilst lessening the impact of that change. We also do this to reduce the "coupling" effect that concrete types can accidentally impose if you are not strict on your public API (interfaces can only represent a public API so for us inherently become quite strict).

That said, it is possible to abstract behaviour without interfaces and possible to test types without needing interfaces, so they are not a requirement to the above. It is just that most frameworks / libraries that you may use to support you in those tasks will operate effectively against interfaces.


I'll leave my old answer for context.

Interfaces define a public contract. People implementing interfaces have to implement this contract. Consumers only see the public contract. This means the implementation details have been abstracted away from the consumer.

An immediate use for this these days is Unit Testing. Interfaces are easy to mock, stub, fake, you name it.

Another immediate use is Dependency Injection. A registered concrete type for a given interface is provided to a type consuming an interface. The type doesn't care specifically about the implementation, so it can abstractly ask for the interface. This allows you to change implementations without impacting lots of code (the impact area is very small so long as the contract stays the same).

For very small projects I tend not to bother, for medium projects I tend to bother on important core items, and for large projects there tends to be an interface for almost every class. This is almost always to support testing, but in some cases of injected behaviour, or abstraction of behaviour to reduce code duplication.

Jentoft answered 14/6, 2010 at 11:46 Comment(2)
The public (non-separate) interface of a class also defines a contract.Fat
I never said it didn't. I was referring in the context of the consumer using the interface as a type, not the concrete implementation's type in their code. This means that their code could receive any other type so long as the contract remains the same. In your situation the implementation of a particular concrete type would need to change, instead of providing a new type. The -1 is a little uncalled for.Jentoft
C
19

Let me quote OO guru, Martin Fowler, to add some solid justification to the most common answer in this thread.

This excerpt comes from the "Patterns of Enterprise Application Architecture" (enlisted in the "classics of programming" and\or the "every dev must read" book category).

[Pattern] Separated Interface

(...)

When to Use It

You use Separated Interface when you need to break a dependency between two parts of the system.

(...)

I come across many developers who have separate interfaces for every class they write. I think this is excessive, especially for application development. Keeping separate interfaces and implementations is extra work, especially since you often need factory classes (with interfaces and implementations) as well. For applications I recommend using a separate interface only if you want to break a dependency or you want to have multiple independent implementations. If you put the interface and implementation together and need to separate them later, this is a simple refactoring that can be delayed until you need to do it.

Answering your question: no

I've seen some of the "fancy" code of this type myself, where developer thinks he's SOLID, but instead is unintelligible, difficult to extend and too complex.

Callis answered 26/1, 2016 at 19:45 Comment(5)
I've seen several developers say that having an interface for every behavior class is excessive and bad design -- but still haven't seen any of them explain how to do unit testing otherwise.Ashla
@EtienneCharland - please check out: arlobelshee.com/tag/no-mocksCallis
@EtienneCharland simple, you just test in production!Mocambique
@Callis about that article, he still ends up using mocks in the end. The problem he addressed is that the code was tied to the particular UI of a console. The way I solve this is simply by imagining the code might also run on a Windows forms, and that later I might add a Web interface. Then the code automatically restructures itself like he suggests. His article is a lot of talks but is a bit misleading because the mock is still needed and isn't the issue.Ashla
@Mocambique With Chicago School of TDD (BDD without Gerkin) you don't need mocks (or just few of them), but still you cover all requirements with tests.Callis
R
5

There's no practical reason behind extracting Interfaces for each class in your project. That'd be an over-kill. The reason why they must be extracting interfaces would be the fact that they seem to implement an OOAD principle "Program to Interface, not to Implementation". You can find more information about this principle with an example here.

Reciprocation answered 14/6, 2010 at 12:2 Comment(0)
C
4

Having the interface and coding to the interface makes it a ton easier to swap out implementations. This also applies with unit testing. If you are testing some code that uses the interface, you can (in theory) use a mock object instead of a concrete object. This allows your test to be more focused and finer grained.

It is more common from what I have seen to switch out implementations for testing (mocks) then in actual production code. And yes it is wroth it for unit testing.

Candlepin answered 14/6, 2010 at 12:4 Comment(1)
I second you. without interfaces swapping implementations is just like building it from scratch !May
S
3

I like interfaces on things that could be implemented two different ways, either in time or space, i.e. either it could be implemented differently in the future, or there are 2 different code clients in different parts of the code which may want a different implementation.

The original writer of your code might have just been robo coding, or they were being clever and preparing for version resilience, or preping for unit testing. More likely the former because version resilience an uncommon need-- (i.e. where the client is deployed and can't be changed and a component will be deployed that must be compatible with the existing client)

I like interfaces on things that are dependencies worth isolation from some other code I plan to test. If these interfaces weren't created to support unit tests either, then I'm not sure they're such a good idea. Interface have a cost to maintain and when it comes time to make an object swappable with another, you might want to have an interface apply to only a few methods (so more classes can implement the interface), it might be better to use an abstract class (so that default behaviors can be implemented in an inheritance tree).

So pre-need interfaces is probably not a good idea.

Selfmastery answered 14/6, 2010 at 12:10 Comment(0)
V
2

If is a part of the Dependency Inversion principle. Basically code depends on the interfaces and not on the implementations.

This allows you to easy swap the implementations in and out without affecting the calling classes. It allows for looser coupling which makes maintenance of the system much easier.

As your system grows and gets more complex, this principle keeps making more and more sense!

Velar answered 14/6, 2010 at 11:23 Comment(1)
DI principle has some applications, but not with "every class".Callis
A
2

I don't think it's reasonable for Every class.

It's a matter of how much reuse you expect from what type of a component. Of course, you have to plan for more reuse (without the need to do major refactoring later) than you are really going to use at the moment, but extracting an abstract interface for every single class in a program would mean you have less classes than needed.

Abdominous answered 14/6, 2010 at 11:48 Comment(0)
S
1

Interfaces define a behaviour. If you implement one or more interfaces then your object behaves like the one or other interfaces describes. This allows loose coupling between classes. It is really useful when you have to replace an implementation by another one. Communication between classes shall always be done using interfaces excepting if the classes are really tightly bound to each other.

Spherics answered 14/6, 2010 at 11:24 Comment(1)
Interfaces define the protocol for sending messages between objects. The do not define behavior. If they did they'ed just be objects. The loose coupling comes from their ability to narrow the set of methods exposed (role interfaces) as well as from allowing that behavior to be swapped.Marv
A
1

There might be, if you want to be sure to be able to inject other implementations in the future. For some (maybe most) cases, this is overkill, but it is as with most habits - if you're used to it, you don't loos very much time doing it. And since you can never be sure what you'll want to replace in the future, extracting an interface on every class does have a point.

There is never only one solution to a problem. Thus, there could always be more than one implementation of the same interface.

Arrogant answered 14/6, 2010 at 11:24 Comment(2)
It can be taken to an extreme though - there are some classes in a project that simply don't need to be interfaced out.Qualmish
@Andrew: That is why I said that this is overkill in some (most) cases.Arrogant
S
1

It might seem silly, but the potential benefit of doing it this way is that if at some point you realize there's a better way to implement a certain functionality, you can just write a new class that implements the same interface, and change one line to make all of your code use that class: the line where the interface variable is assigned.

Doing it this way (writing a new class that implements the same interface) also means you can always switch back and forth between old and new implementations to compare them.

It may end up that you never take advantage of this convenience and your final product really does just use the original class that was written for each interface. If that's the case, great! But it really didn't take much time to write those interfaces, and had you needed them, they would've saved you a lot of time.

Sharpeyed answered 14/6, 2010 at 11:24 Comment(1)
For the record, Future Dan doesn't really agree with this answer. I now think so much up-front effort is probably excessive, and I suspect the alleged benefit of "saving time" later is overstated. Refactoring is seldom that big of a deal. Besides, lots of extra interfaces add to complexity and bloat. By default, I would now advise to avoid over-engineering things this way unless there's a tangible, direct benefit to it.Sharpeyed
R
1

The interfaces are good to have since you can mock the classes when (unit-) testing.

I create interfaces for at least all classes that touches external resources (e.g. database, filesystem, webservice) and then write a mock or use a mocking framework to simulate the behavior.

Riki answered 14/6, 2010 at 11:57 Comment(0)
S
0

Why do you need interfaces? Think practically and deeply. Interfaces are not really attached to classes, rather they are attached to services. The goal of interface is what you allow others to do with your code without serving them the code. So it relates to the service and its management.

See ya

Springer answered 14/10, 2010 at 8:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.