Home:ALL Converter>Interface segregation principle usage

Interface segregation principle usage

Ask Time:2014-06-10T21:19:15         Author:MistyK

Json Formatter

This situation happened to me many times and I have no idea how to solve it.

Interface segregation principle was made to prevent situations, when some interface implementations don't use it's functionality - that's obvious. There is often situation that I have a list of interfaces and I want to do something with them. Let's look at example without ISP:

  public interface IPerson
    {
           void Run();
           void Eat();
    }

public class AbcPerson : IPerson
{
       void Run(){};
       void Eat(){};
}

public class XyzPerson : IPerson
{
       void Run(){};
       void Eat(){};
}

List<IPerson> People {get;set;}

And I want to run with every person.

      foreach(var person in People)
      {
         person.Run();
      }

Now I want to eat with all of them.

          foreach(var person in People)
          {
             person.Eat();
          }

Now if I would like to use ISP I should change code to:

        public interface IRunnable
        {
               void Run();
        }
        public interface IEatable
        {
               void Eat();
        }

    public class AbcPerson : IRunnable,IEatable
    {
           void Run(){};
           void Eat(){};
    }

    public class XyzPerson : IRunnable,IEatable
    {
           void Run(){};
           void Eat(){};
    }

How should I make my list of people? Should I make two lists of Runable and Eatable and add objects(ugly) or maybe second approach- create one list and cast them if it's possible(ugly)? I have no idea what is the best convention to do that.

This example maybe is not the best example I could imagine but I hope you know what I mean.

EDITED: I changed interfaces and classes and principle name.

Author:MistyK,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/24142103/interface-segregation-principle-usage
Eric Scherrer :

If there is a thing in your system that runs and eats then define it as an interface:\n\npublic interface IHungryRunner : IRunnable, IEatable\n{ }\n\n\nassuming that IRunnable and IEatable will ever be used standalone, otherwise just keep them together.\n\nYou could also maintain separate lists of IRunnables and IEatables instead of trying to lump them together.",
2014-06-10T13:25:24
Rune :

Every rule, convention and design pattern in software architecture should be taken with a grain of salt. You need to think about why something is considered a rule / convention / design pattern in order to know when to apply it.\n\nAccording to Wikipedia:\n\n\n The reason it is important to keep a class focused on a single concern\n is that it makes the class more robust. Continuing with the [...generate a report and print it...] example, if there is a change to the report compilation process, there\n is greater danger that the printing code will break if it is part of\n the same class.\n\n\nThe point here is that the process of generating a report is inherently independent from the process of printing the report. Thus, these operations should be allowed to change separately.\n\nIn your Connect() / Disconnect() example I would assume that the cohesion of these two operations is so great that if one changes, it is very likely that the other operation needs to change as well. Thus, combining Connect() and Disconnect() in one interface doesn't violate SRP.\n\nOn the other hand, if the operations are Eat() and Run(), you will need to consider the cohesion of these two operations.\n\nIn the end: be pragmatic! Do you expect splitting Eat() and Run() into separate interfaces to provide any benefits for the foreseeable future? If not, you risk violating another design principle: YAGNI.",
2014-06-10T13:37:18
yy