views:

42

answers:

4

Hello everyone!

I have inherited a project that has an awkwardly big interface declared (lets call it IDataProvider). There are methods for all aspects of the application bunched up inside the file. Not that it's a huge problem but i'd rather have them split into smaller files with descriptive name. To refactor the interface and break it up in multiple interfaces (let's say IVehicleProvider, IDriverProvider etc...) will require massive code refactoring, because there are a lot of classes that implement the interface. I'm thinking of two other ways of sorting things out: 1) Create multiple files for each individual aspect of the application and make the interface partial or 2) Create multiple interfaces like IVehicleProvider, IDriverProvider and have IDataProvider interface inhertit from them.

Which of the above would you rather do and why? Or if you can think of better way, please tell.

Thanks

A: 

Is it correct that most if not all of the classes which implement this single big interface have lots of methods which either don't do anything or throw exceptions?

If that isn't the case, and you have great big classes with lots of different concerns bundled into it then you will be in for a painful refactoring, but I think handling this refactoring now is the best approach - the alternatives you suggest simply push you into different bad situations, deferring the pain for little gain.

One thing to can do is apply multiple interfaces to a single class (in most languages) so you can just create your new interfaces and replace the single big interface with the multiple smaller ones:

public class BigNastyClass : IBigNastyInterface
{
}

Goes to:

public class BigNastyClass : ISmallerInferface1, ISmallerInterface2 ...
{
}

If you don't have huge classes which implement the entire interface, I would tackle the problem on a class by class basis. For each class which implements this big interface introduce a new specific interface for just that class.

This way you only need to refactor your code base one class at a time.

DriverProvider for example will go from:

public class DriverProvider : IBigNastyInterface
{
}

To:

public class DriverProvider : IDriverProvider
{
}

Now you simply remove all the unused methods that weren't doing anything beyond simply satisfying the big interface, and fix up any methods where DriverProvider's need to be passed in.

David Hall
Thank you all for answers. Since i don't want to spend any time at all refactoring (not at the moment at least) i'll just break up the big interface into multiple smaller ones and aggregate them into one using inheritance, leaving the name of aggregated interface the same as of the big one.
Dimitri
+1  A: 

This book suggests that interfaces belong, not to the provider, but rather to the client of the interface. That is, that you should define them based on their users rather than the classes that implement them. Applied to your situation, users of IDataProvider each use (probably) only a small subset of the functionality of that big interface. Pick one of those clients. Extract the subset of functionality that it uses into a new interface, and remove that functionality from IDataProvider (but if you want to let IDataProvider extend your new interface to preserve existing behavior, feel free). Repeat until done - and then get rid of IDataProvider.

Carl Manaster
A: 

This is difficult to answer without any tags or information telling us the technology or technologies in which you are working.

Assuming .NET, the initial refactoring should be very minimal.

The classes that implement the original interface already implement it in its entirety.

Once you create the smaller interfaces, you just change:

public class SomeProvider : IAmAHugeInterface { … }

with:

public class SomeProvider : IProvideA, IProvideB, IProvideC, IProvideD { … }

…and your code runs exactly the way it did before, as long as you haven't added or removed any members from what was there to begin with.

From there, you can whittle down the classes on an as-needed or as-encountered basis and remove the extra methods and interfaces from the declaration.

Jay
A: 

I would do the latter. Make the individual, smaller interfaces, and then make the 'big' interface an aggregation of them.

After that, you can refactor the big interface away in the consumers of it as applicable.

kyoryu