czwartek, 21 listopada 2019

SOLID - I jak Interface segregation principle

Czwarta zasada - interface segregation principle porusza temat tworzenia interfejsów i zarządzania nimi.
Zgodnie z definicją encyklopedyczną ISP mówi o tym, że klient nie powinien być zmuszony do implementowania metod, których nie potrzebuje. Łatwiej tę zasadę zrozumieć na przykładzie.

    public interface IMapper
    {
        CustomerDetails MapCustomerDetails(CustomerDetailsDto customerDetailsDto);
        Address MapAddress(AddressDto addressDto);
        Email MapEmail(EmailDto emailDto);
        Phone MapPhone(PhoneDto phoneDto);
    }

Interfejs IMapper zawiera kilka metod mapujących dane klienta (adres, email, telefon, dane osobowe). Załóżmy, że potrzebujemy mapować nowe dane np. informacje o pracy:

    public interface IMapper
    {
        CustomerDetails MapCustomerDetails(CustomerDetailsDto customerDetailsDto);
        Address MapAddress(AddressDto addressDto);
        Email MapEmail(EmailDto emailDto);
        Phone MapPhone(PhoneDto phoneDto);
        IJob MapJob(JobDto jobDto);
    }

Proste! Kolejna metoda i po kłopocie :) Wydawałoby się, że wszystko jest w porządku. Niestety prawdopodobnie złamaliśmy zasadę ISP z przynajmniej dwóch powodów. Pierwszym problemem jest zmuszenie klienta do implementacji nowej metody. Jeżeli klas implementujących jest więcej będziemy musieli zaimplementować nową metodę w każdej z nich. Drugą kwestią jest re-używalność interfejsu. Niestety ale często możemy spotkać się z następującym zjawiskiem:

    public class Mapper : IMapper
    {
        public CustomerDetails MapCustomerDetails(CustomerDetailsDto customerDetailsDto)
        {
            //code
        }

        public Address MapAddress(AddressDto addressDto)
        {
            //code
        }

        public Email MapEmail(EmailDto emailDto)
        {
            throw new System.NotImplementedException();
        }

        public Phone MapPhone(PhoneDto phoneDto)
        {
            throw new System.NotImplementedException();
        }
    }

Widząc throw new System.NotImplementationException(); powinna się zapalić się czerwona lampka. Jeżeli interfejs posiada 4 metody, a nasza klasa implementuje tylko dwie z nich, oznacza to, że nasz interfejs nie jest re-używalny. W takim przypadku najlepszym wyjściem jest podzielenie tego interfejsu.
Małe interfejsy, posiadające małą ilość składowych jest dużo łatwiej implementować. Skomplikowany interfejs prowadzi do sytuacji gdzie większość metod jest pomijana.

Podsumowując, ISP mówi o:

  • tworzeniu małych, zwinnych interfejsów
  • eliminacji zależności, które komplikują kod

Można się w tym momencie zastanowić czy wzorzec Fasady łamie założenie ISP? Moim zdaniem, jak i wielu innych publikacji nie. Trzeba mieć na uwadze, że pomimo iż do fasady dodajemy metody, to większość z tych metod jest delegowana do zależności.

Brak komentarzy:

Prześlij komentarz