Interfaces – The Good and The Ugly

(there is no bad…just pros and cons)

I want to start off this with a positive spin. Interfaces are great. They help make your life much easier. Using interfaces is real easy too:

public interface IEntity
{
int Id {get;set;}
DateTime DateCreated {get;set;}
DateTime DateUpdated {get;set;}
string CreatedBy {get;set;}
string UpdatedBy {get;set;}
bool Enabled {get;set;}
int DisplayOrder {get;set;}
}


I would apply this interface to a class:

public interface MyEntity : IEntity
{
public MyEntity()
{
IsNew = true;
DateCreated = DateTime.Now;
DateUpdated = DateTime.Now;
}

public string CreatedBy { get; set; }
public DateTime DateCreated { get; set; }
public string UpdatedBy { get; set; }
public DateTime DateUpdated { get; set; }
}

and bingo bongo. Simple usage. What I have done in my lovely homegrown CMS is create a class:

public class MyService<T>
where T : IEntity
{
public bool Save(T entity)
{
// in here you could write some other code to automatically
// save "MyEntity" to the database or some other persistence medium
}

pubic bool Delete(T entity)
{
// in here you'd do some deleting magic.
}
}

and I get complile time errors when I try to save stuff to the database that do not conform to the contracts.

You could take this further and create base classes out of this MyService and MyEntity (ServiceBase and EntityBase) apply these to a whole bunch of other class and a simple clean Entity and Service layered structure starts to appear. Brilliant. Object Orientation, Interfaces and Polymorphism and all those other long words you learn at Uni and never think about again cause your boss doesn’t give you any real world deadlines when building software.

The Good (part II)

Interfaces are 100% necessary for your architecture if you are planning on allowing people to plug their own code in. Usercontrols (in asp.net land) that implement your interfaces e.g. IPlugin, will be easily discoverable by your code, allowing users of you application to choose which plugins they want to appear (in my CMS anyways)

public interface IPlugin
{
string ControlName {get;set;}
string ControlDescription {get;set;}
MyApp.Core.Enums.EditState State { get; set; }
void BuildControl(IControlType mine);
}

Apply this interface to your plugins, put your plugin in a known folder, or compile it up and drop the dll into the Bin folder and your application can run with it – obviously depending on how you built it (it’s not always as simple as people write things in articles).

The Good (part III)

And I 100% totally get interfaces in the need for building plug and play database code, logging code, emailing code, payment gateway code, etc. You never know when you might need to change from Access to SQL Server to MySQL and back*. So if you are writing code that “faces outward” to the world please always use interfaces all the time in these circumstances. Things will work better.

(* In 16 years of programming websites, and all the other years of programming in general, I have never needed to switch an application’s database. When you change the database, generally I have found that the entire app gets rebuilt anyways because of other more important reasons – out of date code being the most common.)

The Ugly

Interfaces get ugly when you start to here about the “decoupling your code” stuff that gets banded around the internet. Every code architecture guru will tell you to decouple you code by using interfaces. This will allow you to change things easily without affecting other code. It will allow you to do everything that is said above. This is correct. What is not correct, in my humble experience of seeing 3rd part code, is giving ever single thing in your entire application an interface. Even code that will never be changed or accessed by external parties I have seen given an interface.

I have been playing with NOP Commerce of late. It’s a fantastic bit of kit and for the tiny price of $50 you can remove their branding and do what you want. Even better you get the full source code and can hack away at it. Even better still they are on the bleeding edge of code with an MVC4 version either out by the time you read this or appearing very very soon. It has been a pleasure to see a couple of people build something that just works.

However they have given everything an interface and you never use concrete classes anywhere. As I said, this can be good. Especially seeing as NOP developers have built a very nice plugin system allowing people to write all the payment gateways you need and many other things. Also because they use IOC and DI you can sort of easily remove 1 implementation of any part of the system and plug in your own, as long as you use the Interfaces found in NOP’s system.

And this is where it gets ugly.

Because everything is an interface when you want to add new functionality you have to change the interface as well as changing the code. If you need to add new properties on to the methods that are already there, you need to change the interface as well. This gets somewhat tiresome after 1000s of client needs and changes in the months of running the system.

For example, there was no need to interface up the Order Reporting Service they have. They only had a handful of methods. If you were to plugin your own Order Reporting Service and used their Interface you’d have to do those same methods again. Unless you added your own interface, but then you’d need to go and change all the code that used their interface to use your interface – defeats the point of the interface. They have used partial interfaces as well. I love the idea of partial classes etc, but partial interfaces to me make no sense. Have they added this to make their code look fancy? You are still going to be changing the interface. And any class that uses that interface will break. So keep it in the same file. But I ramble.

I think they have over used interfaces because they love IOC and DI, and who doesn’t…it’s great. IOC and DI makes it easy in your code to have all your service classes available when you need them because they are instantiated at the same time your object is created:

{from NOP commerce}

public CommonController(IPaymentService paymentService, IShippingService shippingService,
IShoppingCartService shoppingCartService,
ICurrencyService currencyService, IMeasureService measureService,
ICustomerService customerService, IWebHelper webHelper,
StoreInformationSettings storeInformationSettings, CurrencySettings currencySettings,
MeasureSettings measureSettings, IDateTimeHelper dateTimeHelper,
ILanguageService languageService, IWorkContext workContext,
IPermissionService permissionService, ILocalizationService localizationService)
{
this._paymentService = paymentService;
this._shippingService = shippingService;
this._shoppingCartService = shoppingCartService;
this._currencyService = currencyService;
this._measureService = measureService;
this._customerService = customerService;
this._webHelper = webHelper;
this._storeInformationSettings = storeInformationSettings;
this._currencySettings = currencySettings;
this._measureSettings = measureSettings;
this._dateTimeHelper = dateTimeHelper;
this._languageService = languageService;
this._workContext = workContext;
this._permissionService = permissionService;
this._localizationService = localizationService;
}

DI takes over and instantiates the concerete classes you have defined in the dependency resolver and applies them to the property in place of the Interface. Thus you know what you are going to get. Basically the point of interfaces.

However because this over use of interfaces, in my humble opinion, their constructors get large and cumbersome. What’s worse, again in my humble opinion, because each of these classes are getting instianted automagically via DI then in the constructor of each of these classes, all the other services the class getting instantiated needs get instantiated. Wow. There is a lot of things going on just for 1 controller class. And if all you were doing was posting back to a simple action method that uses none of these automatically instantiated classes, you’ve made your server work hard, and killed some trees! And 1 simple operation you may have added a couple MB of code into memory… not very efficient.

But IOC and DI is awesome. It’s not their fault.

Conclusion

Be careful when building applications. Interfaces are awesome, extremely useful and for many things totally necessary. My recommendations on using them are this:

1. If your code is going to be used by external sources to allow them to extend it then interface it up. That way you can guarantee your software will react properly when someone adds something new e.g plugins or changing the logging mechanisms.

2. If you have a set of rules that you need code to follow e.g. all objects must have an interger id, a date created field and a created by field then the use of a interface will make things so much easier:

if(_object is IMyInterface)
{
// do stuff
}
else
{
throw new Exception("I can't use this pile of crap!")
}

or

public class MyObjectService : ServiceBase<MyObject>
{

}

with ServiceBase being

public class MyService<T>
where T : IEntity

then you get compile time warnings that the object you are trying to use in the application isn’t correctly built, or won’t be able to be saved in the standard predefined way.

3. Or if you want to use IOC and DI because it makes coding faster as you don’t need to write tonnes of lines of code instantiating service classes or database classes etc. Your classes will be available as they will be instantiated at the time the constructor is run. But be careful. Don’t do it too much as you will annoy people like me that want nice simple clean coding.

4. Don’t use interfaces if you can guarantee it will be changed. An interface should only be changed as a last resort. So if your developers need to change them often, then an interface is not the right thing to use. Consider using a base class and base methods.

Let me know what you think. Or if am talking ass.

7 thoughts on “Interfaces – The Good and The Ugly”

  1. Constructor overload can be a problem with DI. That example above is nuts. They should be using something like a service factory to resolve required services. Saying that, I wrote something similar a couple of years ago and we’re just refactoring it now.

    Like yourself, I’ve never had to change the underlying persistence layer without rewriting other code. But I’d still write every bit of repository/business service to a contract just because it makes writing unit tests so much simpler.

    Being able to mock a Save method in IDataContext is a lot less complicated than having to create dummy DataContext classes in your tests (if you’ve ever written tests against EF you’ll know that pain). And it’s infinitely better than writing unit tests that actually start writing to the DB (one of the legacy projects I’ve worked on has tests that span several tiers – nightmarish).

    The partial stuff I only find useful if the two parts are the stuff that’s been written by hand and the other auto-generated. I’ve never understood any reason for it to exist outside of that. I’d never heard of partial interfaces before and I don’t think I’ll be rushing to try them out.

  2. It’s one thing I rarely write is unit tests…tests are only as good as the person writing them, and am shit at writing them!

Leave a Reply

Your email address will not be published.