Casey Crookston
Casey Crookston

Reputation: 13955

Interface Segregation Principle - How to call a method that is defined in a separate interface?

So we have had an interface that's been around for a long time. Let's call it IFoo. It has a lot of methods defined in it, and there are about 10 classes that implement it.

All along, when we need to create an instance of one of those classes, we've used a simple factory pattern:

IFoo foo = FooFactory.Create(...);

Then, of course, we have access to all of the methods defined in IFoo:

foo.Method1();
foo.Method2();
etc.

But now, we have some methods that need to be in some of the ten classes, but not all of them. So in keeping with the Interface Segregation Principle, it's my understanding that we should create a new Interface: IBar.

So the classes that need the methods that will be defined in IBar will look like this:

public class something: IFoo, IBar
{
     ...
}

So far so good. But what I'm unsure of how is how to then access these methods. Because when we use the same factory method:

IFoo foo = FooFactory.Create(...);

foo does not have any of the methods that are in IBar.

The factory method looks like this (this is a scaled down version to make things easier for this post):

public static IFoo Create(string className)
{
     Type type = Type.GetType(className);
     return (IFoo)Activator.CreateInstance(type);
}

So anyway, I'm unclear on how to modify all of this to have access to the methods in IBar as well.

Upvotes: 0

Views: 221

Answers (1)

Vadim Martynov
Vadim Martynov

Reputation: 8892

If you just try to use type conversion, your code will not be resistant to changes and may breaks during refactoring. In order to choose a solution you need to answer the following questions:

  • What is IFoo and IBar? Why do you separate this interfaces and when should they be used? It's questions about motivation to use interface-segregation principle. If you have 2 really different use cases it's OK but you should not to use it just to comply with the rules. It's ok to have interface with many methods. if you decide that IFoo and IBar are in fact one interface then just combine them to IFooBar interface.
  • OK. We decided that we really have two interfaces. Next question is why class Something implements both of these interfaces? Does it breaks Single responsibility principle? If so then you need to separate this class to class Foo : IFoo and class Bar : IBar and creates new factory for class Bar to use it in cases you need to call BarMethod(). You may have duplicate code problem or reusing shared resource problem.
  • If you have duplicate code problem so just use inheritance to solve it.
    public class SomeBase { /* common code */ }
    public class Foo : SomeBase, IFoo { /* IFoo impementation */ }
    public class Bar : SomeBase, IBar { /* IBar impementation */ }
  • If you have reusing shared resource problem so can solve it with dependency injection. For example, you'll add BarFactory and both FooFactory and BarFactory uses SharedResourceRepository that stores and allow access to the shared resources. If you use IoC-Container, then the problem is solved by its configuration.
  • OK. We decided that we really have one class. Next question is why do you need to retrieve an instance of IFoo to use its IBar methods? It definitely breaks object oriented design and each solution will only be a hack. You should create BarFactory and solve single instance problem with Singletone, IoC-containers or so on.

Upvotes: 1

Related Questions