Czwarta z zasad SOLID to zasada segregacji interfejsów – Interface Segregation Principle.  Mówi ona o tym, że żaden klient (klasa) nie powinien być zmuszany do polegania na interfejsach, z których nie korzysta. Kilka mniejszych, dedykowanych interfejsów jest lepsze niż jeden zbyt ogólny. Nie powinniśmy stosować tych tzw. fat interfaces – zawierających deklaracje metod, które niekoniecznie powinny być implementowane przez każdego z użytkowników. Jako przykład złamania zasady ISP niech posłuży kwestia organizacji spotkań biznesowych lub w ogóle wydarzeń publicznych. Stwórzmy więc interfejs Tasks z zadaniami do rozdysponowania umieszczonymi w metodach provideFood, provideEquipment, decorateRoom.

Tasks.java

package organizer.event;

public interface Tasks {
    void provideFood();
    void decorateRoom();
    void provideEquipment();
}

FoodManager.java

package organizer.event;

public class FoodManager implements Tasks{

    @Override
    public void provideFood() {
        //provide wide range of snacks and dishes
    }

    @Override
    public void decorateRoom() {
        throw new TypeOfWorkNotSupportedException();
    }

    @Override
    public void provideEquipment() {
        throw new TypeOfWorkNotSupportedException();
    }
}

DecoratingManager.java

package organizer.event;

public class DecoratingManager implements Tasks{

    @Override
    public void provideFood() {
        throw new TypeOfWorkNotSupportedException();
    }

    @Override
    public void decorateRoom() {
        //provide flowers,decorations etc.
    }

    @Override
    public void provideEquipment() {
        throw new TypeOfWorkNotSupportedException();
    }
}

TechnicalManager.java

package organizer.event;

public class TechnicalManager implements Tasks{

    @Override
    public void provideFood() {
        throw new TypeOfWorkNotSupportedException();
    }

    @Override
    public void decorateRoom() {
        throw new TypeOfWorkNotSupportedException();
    }

    @Override
    public void provideEquipment() {
        //provide technical equipment of the room e.g. computer with projector, sound system etc.
    }
}

Interfejs Tasks implementują klasy odpowiedzialne za poszczególne zadania. Jednak żadna z tych klasa nie potrzebuje implementować wszystkich metod w interfejsie. W przypadku zmiany interfejsu np. dodania metody od zapewnienia oprawy muzycznej wydarzenia, potrzebne będzie dodanie implementacji tej metody we wszystkich klasach implementujących dany interfejs, a więc zmiany będą obejmować wiele miejsc w naszym kodzie. Aby temu zapobiec rozbijmy interfejs Tasks na poszczególne interfejsy dedykowane odpowiednim zadaniom: FoodTasks, DecorationTasks, EquipmentTasks. Każda klasa niech implementuje interfejs związany z zadaniem, którym się zajmuje. Zachowana zostanie więc zasada segregacji interfejsów – ISP. W ten sposób w przyszłości zmiany dotyczące np. wyboru menu lub zmian charakteru dekoracji obejmą jeden interfejs i jedną klasę, która go implementuje – mamy tutaj do czynienia także z zasadą jednej odpowiedzialności – SRP.

FoodTasks.java

package organizer.event;

public interface FoodTasks {
    void provideFood();
}

DecorationTasks.java

package organizer.event;

public interface DecorationTasks {
    void decorateRoom();
}

EquipmentTasks.java

package organizer.event;

public interface EquipmentTasks {
    void provideEquipment();
}

FoodManager.java

package organizer.event;

public class FoodManager implements FoodTasks {

    @Override
    public void provideFood() {
        //provide wide range of snacks and dishes
    }
}

DecorationManager.java

package organizer.event;

public class DecoratingManager implements DecorationTasks {

    @Override
    public void decorateRoom() {
        //provide flowers,decorations etc.
    }
}

TechnicalManager.java

package organizer.event;

public class TechnicalManager implements EquipmentTasks {

    @Override
    public void provideEquipment() {
        //provide technical equipment of the room e.g. computer with projector, sound system etc.
    }
}

PODSUMOWANIE

Dzięki zastosowaniu zasady segregacji interfejsów – ISP, nasz kod jest odpowiednio posegregowany, a tym samym łatwiejszy do zarządzania i utrzymywania. Ponadto osiągamy tzw. „high cohesion” czyli wysoką spójność kodu. Zasada ta jest powiązana również z zasadą Single Responsibility Principle oraz Liskov Substitution Principle omawianymi w poprzednich wpisach.