tags:

views:

112

answers:

6

I am in the process of converting all my parameters, return types, classes to all use Interfaces instead ie. IUser instead of User.

Besides the extra code required to maintain this, are their any negatives to this approach?

+3  A: 

This isn't an uncommon approach, especially if you do a lot of mocking; however, it has issues with:

  • data-binding support (especially when adding rows to tables)
  • xml serialization (including comms WCF, asmx, etc), or contract-based serialization in general

You need to figure out whether the advantages of mocking etc outweigh these issues. It might be that you use IUser in most scenarios, but (for example) at the comms layer it may be simpler to use raw DTOs rather than interfaces.

Note that I'm applying the above to classes. If you involve structs, then remember that in most cases this will involve boxing too.

Marc Gravell
+1 Good points - I hadn't thought about databinding. In WPF at least, this can be alleviated by using abstract base classes instead of interfaces. In general, however, I would say that the advantage is loose coupling, which spans much more than just mocking, although it includes that as well.
Mark Seemann
A: 

avoid the ISuck prefix.

edit: the ISuck convention is a manifestation of the Systems Hungarian notation applied to type names.

just somebody
Been drinking tonight, are we?
Lasse V. Karlsen
no, not this night.
just somebody
not just this night? ;p
leppie
.NET-developers expect interfaces to start with an I, it's part of the official .NET naming convention. A good API is an API with no surprises, where everything looks like and behaves like you'd expect.
Tommy Carlier
+3  A: 

Overall, this will give you all the advantages associated with loose coupling, so in general I consider this a huge win. However, since you asked about disadvantages, here are some minor ones I can think of:

  • There's more code involved becase you have both the interface declaration and at least one implementation (you already mentioned this, so I'm just including it for completeness sake).
  • It becomes more difficult to navigate the code because you can't just Go to Definition to review what another method does (although I'm told that Resharper helps in this regard).
  • In some cases there may be more in a contract than mere semantics, and an interface can't capture that. The classic example from the BCL is that if you implement IList, you must increment the Count property every time you add an item. However, nothing in the interface forces you, as a developer, to do this. In such cases, abstract base classes may be worth considering instead.
  • Interfaces are brittle when it comes to adding new members. Once again, you may consider abstract base classes instead.
Mark Seemann
Definitely agree with your second point. I've had really bad experiences with codebases which had too much abstraction, where everything and its dog was abstracted out into an interface. It was just impossible to tell what was going on. (And to add insult to injury, the excessive abstraction didn't even deliver on loose coupling. Interfaces are not magic pixie dust for loose coupling.)
itowlson
Agreed: interfaces are required for loose coupling, but don't guarantee it.
Mark Seemann
+2  A: 

I once went through a phase of this, but in practice found that for anemic data objects (i.e. POCOs) the interfaces weren't required.

In practice it can be useful to have interfaces to define a contract for behaviour, but not necessarily for attributes.

In general I'd suggest you let your unit testing guide you. If you have rich objects throughout your application then you'll most likely need interfaces. If you have POCOs, you most likely will only need them for controller-style classes.

Jeremy McGee
+1  A: 

Interfaces are very good thing, but applying them to all artifacts is overkill. Especially in java you would end up with two distinct files (interface + implementation). So (as always), it really depends :)

Regarding 'interface or not-to-interface'

  • I would not have domain-objects have interfaces (e.g. User). In my view for code comprehension it is rather confusing (for domain objects interface often would define getter methods). Recently it was a real pain to get unit-tests in place and having domain-object-interfaces. I had to mock all these getters and getting test-data into the domain-object mocks was rather cumbersome.
  • The opposite is true for coarse grained services and api interfaces. For them I always have an interface from start on.
  • In more internal-module encapsulated scenarios I start without interface and after some code-evolution if necessary react and do an extract-interface refactoring.

'I' prefix for interface artifact names

I also used to work with the Ixxx prefix but I (happily) got rid of it nowadays for following reasons:

  • It is difficult to keep up all this 'I' naming convention in an evolving codebase, especially if you refactor a lot (extract-interface, collapse-interface etc.)
  • For client code it should be transparent whether the type is interface or class based
  • The 'I' can make you lazy about good interface and classnames.
manuel aldana
+1  A: 

Not so much a disadvantage but a warning. You would find that to achieve good component de-coupling you will need to use a Dependency Injection framework (that is if you want to keep your sanity and have some sort of idea what your interfaces map to).

What also tends to happen is that non-trivial classes sometimes naturally convert into more than one interface. This is especially true when you have public static methods (i.e. User.CreateAdminUser). You will also find that it's harder to get an interface to hold state AND do stuff. It's frequently more natural for an interface to be either one or the other.

If you get stuck in the process, do take a minute a do some research into what's an appropriate paradigm that you are trying to implement. Chances are someone has solved this particular design pattern before. Considering this is a big refactoring job, you might as well take extra time and do it properly.

Igor Zevaka