S.O.L.I.D – 4. Zasada segregacji interfejsów (I – Interface segregation)

SOLID – Zasada segregacji interfejsów – przedostatnia z wytycznych SOLID. Reguła ta oznajmia nam, aby nie tworzyć interfejsów z metodami, których nie używa klasa. Interfejsy powinny być jak najmniejsze i konkretne  klasy nie powinny implementować metod których nie potrzebują. Nie powinno dojść do sytuacji, gdy któraś z klas pochodnych nie wykorzystuje zaimplementowanej w interfejsie metody. Wyobraźmy sobie, że mamy interfejs, który jest używany w kilkunastu innych projektach, jednak w każdym projekcie używana jest tylko jedna metoda tego interfejsu. Gdy zajdzie potrzeba zmiany tego interfejsu spotkamy się z problemem ingerowania w każdy projekt. Nie powinniśmy zmuszać klasy do implementowania metod, których nie potrzebuje. Lepiej zdefiniować większą liczbę małych i lekkich interfejsów. Zobrazujmy to na przykładzie w PHP.

interface Car
{
     public function engineOn();
     public function move();
     public function automaticAirConditioning();
     public function cruiseControl();
}

class Fiat126p implements Car
{
     public function engineOn()
     {
          //turn on engine
     }

     public function move()
     {
          //move this car
     }

     public function automaticAirConditioning() {}

     public function cruiseControl() {}
}

class AudiA7 implements Car
{
     public function engoneOn()
     {
          //turn on engine
     }

     public function move()
     {
          //move this car
     }

     public function automaticAirConditioning()
     {
          //temperature is too high, turn on air conditionig please
     }

     public function cruiseConstrol()
     {
          //we are on highway, turn on cruise control
     }
}

W powyższym przykładzie mamy klasy Fiat126p oraz AudiA7, które implementują interfejs Car. O ile Audi posiada i korzysta ze wszystkich funkcji, o tyle przypomnijmy sobie, czy Maluch korzystał z takich udogodnień jak klimatyzacja automatyczna czy tempomat? Może zdarzyły się jakieś pojedyncze przypadki, ale pomińmy je i załóżmy, że nie. A więc klasa Fiat126p nie potrzebuje implementować metod z których nie będzie korzystać i powinna implementować nie wszystkie a tylko kilka z nich. W tym wypadku najlepiej po prostu rozdzielić większy interfejs na pomniejsze, co obrazu poniższy przykład.

interface Car
{
     public function engineOn();
     public function move();
}

interface AdditionalFunctions
{
     public function automaticAirConditioning();
     public function cruiseControl();
}

class Fiat126p implements Car
{
     public function engineOn()
     {
          //turn on engine
     }

     public function move()
     {
          //move this car
     }
}

class AudiA7 implements Car, AdditionalFunctions
{
     public function engineOn()
     {
          //turn on engine
     }

     public function move()
     {
          //moce this car
     }

     public function automaticAirConditioning()
     {
          //temperature is too high, turn on air conditioning please
     }

     public function cruiseControl()
     {
          //we are on highway, turn on cruise control
     }
}

Dzięki powyższemu rozwiązaniu implementujemy tylko te metody, które są nam niezbędne. Rozdzielenie interfejsów na mniejsze zapewnia nam dużo większą elastyczność. Wydzielamy osobne funkcjonalności do osobnych interfejsów a klasy implementują tylko te interfejsy, które są potrzebne. Unikamy wymuszania implementacji metod, które w danej klasie nie są używane. Starajmy się odchudzić interfejsy, jak tylko się da.

Dziękuję za zapoznanie się artykułem dotyczącym przedostatniej wytycznej SOLID – Zasada segregacji interfejsów.
Zapraszam do kolejnego artykułu. Pochylimy się nad kolejną wytyczną jaką jest zasada odwrócenia zależności.