views:

127

answers:

6

Hi, What is the best approach for defining Interfaces in either C# or Java? Do we need to make generic or add the methods as and when the real need arises?

Regards, Srinivas

+3  A: 

Once an interface is defined, it is intended to not be changed. You have to be thoughtful about the purpose of the interface and be as complete as possible.

If you find the need, later, to add a method, really you should define a new interface, possibly a _V2 interface, with the additional method.

Addendum: Here you will find some good guidelines on interface design in C#, as part of a larger, valuable work on C# design in general. It generally applies to Java as well.

Excerpts:

Although most APIs are best modeled using classes and structs, there are cases in which interfaces are more appropriate or are the only option.
DO provide at least one type that is an implementation of an interface. This helps to validate the design of the interface. For example, System.Collections.ArrayList is an implementation of the System.Collections.IList interface.
DO provide at least one API consuming each interface you define (a method taking the interface as a parameter or a property typed as the interface). This helps to validate the interface design. For example, List.Sort consumes IComparer interface.
DO NOT add members to an interface that has previously shipped. Doing so would break implementations of the interface. You should create a new interface to avoid versioning problems.

I recommend relying on the broad type design guidelines.

Cheeso
I 100% agree with this, except that IMO it is an ideal situation. In practice I think you'll need to eventually refactor your interfaces to handle things you just didn't think of the first time around. If you're interface is public, like a web service or an API of some sort, then definitely take @Cheeso's advice above and version them out. If it's internal to your project only, I don't think there's anything wrong with changing it as long as there is a formal process for doing so. You shouldn't just change it on the fly all the time.
Alex Beardsley
+1. Of course during development, an iterative approach is normal. You'll add methods and see if that makes sense, then add and remove a few more methods as you gain experience. But at some point you release the code, and from that point on, the interface needs to remain fixed, except in very exceptional conditions.
Cheeso
+1  A: 

To quote Joshua Bloch:

When in doubt, leave it out.

You can always add to an interface later. Once a member is a part of your interface it is very difficult to change or remove it. Be very conservative in your creation of you interfaces as they are binding contracts.

As a side note here is an excellent interview with Vance Morrison (of the Microsoft CLR team) in which he mentions the possibility of a future version of the CLR allowing "mixins" or interfaces with default implementations for their members.

Andrew Hare
A: 

If your interface is part of code that is shared with other projects and teams, listen to Cheeso. But if your interface is part of a private project and you have access to all the change points then you probably didn't need interfaces to begin with but go ahead and change them.

jms
A: 

If the interface is going to be public, I feel that a good deal of care needs to be put into the design because changes to the interface is going to be difficult if a lot of code is going to suddenly break in the next iteration.

Changes to the interface needs to be taken with care, therefore, it would be ideal if changes wouldn't have to be made after the initial release. This means, that the first iteration will be very important in terms of the design.

However, if changes are required, one way to implement the changes to the interface would be deprecate the old methods, and provide a transition path for old code to use the newly-designed features. This does mean that the deprecated methods will still stick around to prevent the code using the old methods from breaking -- this is not ideal, so it is a "price to pay" for not getting it right the first time around.

On a related matter, yesterday, I stumbled upon the Google Tech Talk: How to Design a Good API and Why It Matters by Joshua Bloch. He was behind the design and implementation of the Java Collection libraries and such, and is the author of Effective Java.

The video is about an hour long where he goes into details and examples about what makes a good API, why we should be making well-designed APIs, and more. It's a good video to watch to get some ideas and inspiration for certain things to look out for when thinking about designing APIs.

coobird
A: 

Adding methods later to an interface immediately breaks all implementations of the interface that didn't accidentaly implement those methods. For that reason, make sure your interface specification is complete. I'd propose you start with a (sample) client of the interface, the part that actually uses instances of classes implementing said interface. Whatever the client needs must be part of the interface (obviously). Then make a (sample) implementation of the interface and look what additional methods are both generally usefull and available (in possible other implementations) so they should also be part of the interface. Check for symetry completeness (e.g. if there is an "openXYZ", there should also be a "closeXYZ". if there is an "addFooBar", there should be a "removeFooBar". etc.) If possible, let a coworker check your specification.

And: Be sure you really want an interface. Maybe an abstract base class is a better fit for your needs.

ammoQ
A: 

Well, it really depends on your particular situation. If your team is the sole user/maintainer of that interface, then by all means, modify it as you see fit and forget all about that "best practice blabla" kind of stuff. It is YOUR code after all... Never blindly follow best pracice stuff without understanding its rationale.

Now, if you're making a public API that other team or customer, will work with (think plugins, extension points or things like that) then you have to be conservative with what you put in the interface. As other mentionned, you may have to add _V2 kind of interface int these cases. Microsoft did with several web browser COM interfaces.

The guidelines Microsoft publishes in Framework Design Guidelines are just that: guideline for PUBLIC interface. Not for private internal stuff; tough many of them still apply. Know what applies or not to your situation.

No rule will make up for lack of common sense.

Simon P.