0

In general, why should you strive for three to five members per interface?

And then, what's wrong with something like this?

interface IRetrieveClient
{
    Client Execute(string clientId);
}

interface ISaveClient
{
    bool Execute(Client client);
}

interface IDeleteClient
{
    bool Execute(string clientId);
}

When I see the this, it screams "Antipattern!" because the interface isn't accomplishing anything, especially when the designer of the application intends for each interface to have a one-to-one relationship with the class that implements it.

Read: Once an interface is implemented, it is never reimplemented again. Now, I didn't design this system and it seems to me like what they wanted to do was implement some version of the command pattern, but when speaking to the developers, they don't seem to get it.

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
  • Why should you strive to some number of members in interface? `IDisposable` for example – Sergey Berezovskiy Jun 20 '13 at 13:01
  • 2
    I would say an interface should have as many or as few members as it makes sense for your application design. In this case, if your application design had implementations that could retrieve/read only for 3rd parties, or write-only, then it makes sense. Also note that you could create combination interfaces this way too (e.g., `interface IChangeClient : ISaveClient, IDeleteClienet`) EDIT: That said, if your application design doesn't require the restriction that some implementations can't do some of those things, then it may be an unnecessary complexity to split it into 3 interfaces. – Chris Sinclair Jun 20 '13 at 13:01
  • IDisposable makes complete sense, and so does the command pattern, but I don't know why you wouldn't expose something like this through an IClient with get, save, and delete members. – user2505193 Jun 20 '13 at 13:09
  • In this exact case it seems you can easily have just one interface as it won't violate SRP (see my answer). But having only one method does not seem like any problem or "Antipattern" to me – Ilya Chernomordik Jun 20 '13 at 13:27
  • You should read up on the Interface Segregation Principles from the SOLID Principles. Explains this the best. – Dennis van der Stelt Jun 24 '13 at 21:14

4 Answers4

1

One area where I've used the single-method-per-interface pattern quite extensively is with generics together with some generic dispatch infrastructure.

For example:

public interface IValidateEntities<T>
{
    bool Validate(T entity);
}

Then when it is necessary to do something with an entity of some type, we can use reflection to find out which implementation to invoke (results of reflection usually cached in advance).

I gave a presentation on this pattern a while back and it's available for viewing here:

http://www.infoq.com/presentations/Making-Roles-Explicit-Udi-Dahan

Udi Dahan
  • 11,932
  • 1
  • 27
  • 35
  • 1
    Love that presentation. Especially with reflection you sometimes can even have an interface without even a single method, so that you have some marker. You can of course also agree on conventions so that the naming provides the same kind of 'marker'. Just like NServiceBus did with messages in unobtrusive mode. – Dennis van der Stelt Jun 24 '13 at 21:15
0

This looks entirely reasonable to me. I'm perfectly happy to have a small number of methods (or indeed one method) per interface.

Note that the benefit of combining interfaces is that you can (say) selectively present different views of a class by casting appropriately. e.g. you can construct/modify a class and then present it (narrow it) via a more restricted interface (e.g. having a read-only interface)

e.g.

interface Readable {
   Entity get();
}

interface Writeable {
   void set(Entity e);
}

A class can implement both interfaces such that you can mutate it, and then you can present it to clients simply as a Readable object, such that they can't mutate it. This is possible due to subdividing the interfaces.

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
0

You should be careful to use general rules and apply them too strictly. There is nothing wrong with your approach per se, if that is what you need.

But you might want to think of the following alternative:

interface IClient
{
     Client Retrieve(string clientId);
     bool Save(Client client);
     bool Delete(string clientId);
}

The advantage of this approach is that when you use injection, you only have to register one instance, and you only have one interface in your constructor.

So if it logically belongs together, I would keep it in one interface, because it reduces cluttering and is less complex.

L-Four
  • 13,345
  • 9
  • 65
  • 109
0

The important thing in the design is to keep to what Robert Martin calls single responsibility principle. In your case I think what L-Three proposed is quite reasonable as client will have one responsibility - talk to database (or service, e.t.c.). So if you see that methods in IClient will become totally different for some reason and are breaking SRP then you can split it many interfaces and I don't think if an interface has only one method it's a problem. For instance a good example is an interface called IKeyGenerator that generates keys in a thread safe manner. That interface has just GetNextKey() method which is perfectly enough.

Ilya Chernomordik
  • 27,817
  • 27
  • 121
  • 207