Search code examples
solid-principles

SOLID : SRP + ISP


I am trying to understand SOLID principles. I think I understand well the Liskov Substitution Principle, but I have some problems for other ones.

One example. I have two interfaces : Engine and car stereo. The problem is : For a car, we have 6 glasses.

So, my car implements interfaces Engine and Car Stereo.

But for the 6 glasses, should I implement them, or should I put them on an array of glasses knowing there are 4 laterals glasses which are able to be up or down and 2 windshields (glasses inherited by both).

The problem with the first one is, I can't implement 4 times the same glasses.

So the second one seems to me good but I am afraid that break SRP, I am not sure to understand what "Responsibilities" exactly are.


Solution

  • The correct design practise is to

    code to interface rather than class.

    In light of this principle I'd recommend to use a interfaces like IWindow, ISurface, IWindShield with a hierarchy like below

    interface ISurface
    {
      //surface specific properties which ideally should be DI-ed
      public SurfaceType SurfaceType {get; set;}
      public decimal Opacity {get;set;}
      public decimal Thickness {get; set;}
    }
    

    and

    interface IWindow:ISurface
    {
      //Window behavior specific properties and methods
      public void lowerWindow();
      public WindowHeight WindowLevel(){get;set;}
      public void shutWindow();
      // ...and more such window specific behavior
    }
    

    and

    interface IWindShield:ISurface
    {
      //WindShield behavior specific properties and methods
      public bool IsFogged(){get;set;}
      public bool IsClean(){get;set;}
      // ...and more such window specific behavior
    }
    

    Finally when assembling a car with all its functionality (presumably using a Builder pattern), you can have an array in the Car class of type ISurface type like below

    class Car
    {
       string carName;
       Engine carEngine;
       Stereo carStereo;
       List<ISurface> carGlasses;
       .....
       // other Car parts
       // this is a typical builder pattern example
    }
    

    this is build using a CarBuilder type class say MyCarBuilder where

    interface CarBuilder
    {
      public Car MyCar {get; set;}
      void AddEngine();
      void AddStereo();
      void AddGlasses();// this is what works on adding ISurface List items
      // and other car building methods
    }
    

    and the real builder class

    class MyCarBuilder:CarBuilder
    {
        //... implements all methods of building your custom car
    }