KategorilerNesne Yönelimli ProgramlamaProgramlama PrensipleriYazılım Mimarisi

Interface Segregation Prensibi Örnekli Anlatım

SOLID prensiplerinin “I”si, Interface Segregation Prensibi(ISP) yani Arayüz Ayırma Prensibi bir Interface’in(arayüzün) onu kullanan Class’ların(sınıfların) ihtiyaçlarına göre bölünmesi gerektiğini anlatan tasarım prensibidir. Prensibin amacı sınıfların ihtiyacı olmayan metotları içermek zorunda kalmamasıdır.

Daha basit bir şekilde ifade etmek gerekirse, Interface Segregation Prensibine göre bir Interface öyle bir şekilde tasarlanmalı ki bu Interface‘i kullanan sınıfların sadece ihtiyaçları olan metotları uygulamaları gereksin, ihtiyaçları olmayan metotları barındırmak zorunda olmasın.

Peki bunu nasıl yaparız?

Bunun en güzel yolu küçük ve özgün Interface‘ler oluşturmak. Interface‘lerin iyi tanımlanmış tek bir sorumluluğunun olması, büyük bir Interface oluşturup sınıfların ihtiyaçları olmayan metotlar içermeye zorlanmasına engel olur.

Yani kısacası büyük her şeyi içeren Interface‘ler oluşturmaktansa küçük spesifik Interface‘ler oluşturmak daha doğru bir yaklaşım olacaktır, böylece her sınıf için o sınıfa uygun olan Interface‘ler tercih edilebilir.

ISP’nin bize başka ne gibi faydaları var?

  • Küçük ve özelleşmiş Interface‘lerin anlaşılması ve bakımı daha kolaydır.
  • Sistemin esnekliği arttırır, yeni bir Interface oluşturarak yeni özellikler ekleyebilirsiniz, böylece var olan Interface‘lerde değişiklik yapılmadığından bunları kullanan sınıfları ihtiyaçları olmayan metotlar kullanmak zorunda bırakmazsınız.
  • Küçük Interface‘ler yeniden kullanıma daha uygundur, böylece kod tekrarlarından kaçınabilirsiniz.

Bir de örnekle ne hakkında konuştuğumuza bir bakalım:

İlk olarak nasıl olmaması gerektiğini bir örnekle görelim. İki çeşit kullanıcımız olduğunu düşünelim, birisi Author(yazar) diğeri de Reader(okuyucu), bu iki kullanıcı tipimiz için de IUser Interface‘ini kullanalım.

public interface IUser
{
    void Login();
    void Logout();
    void ReadPost();
    void WritePost();
}

public class Author : IUser
{
    public void Login()
    {
        // Login kodu
    }

    public void Logout()
    {
        // Logout kodu
    }

    public void ReadPost()
    {
        // Readpost kodu
    }

    public void WritePost()
    {
        // WritePost kodu
    }
}

public class Reader : IUser
{
    public void Login()
    {
        // Login kodu
    }

    public void Logout()
    {
        // Logout kodu
    }

    public void ReadPost()
    {
        // ReadPost kodu
    }
    
    // Reader tipindeki kullanıcı post oluşturamayacağından burada Reader sınıfı ihtiyacı olmayan bir metodu uygulamak zorunda kaldı.
    public void WritePost()
    {
        // WritePost kodu
    }
}

Örnekte de gördüğümüz gibi IUser Interface‘inde bulunan WritePost metoduna Reader sınıfında ihtiyaç yoktu, ancak genel, bütün tiplere hitap etmeyen bir Interface tasarımı yaptığımızdan Reader sınıfı bu metodu uygulamak zorunda kaldı.

Peki bunu nasıl daha iyi yapabilirdik ve Interface Segregation Prensibine uyabilirdik?

İşe IUser Interface‘imizi bölerek başlayabiliriz, tüm kullanıcı tiplerimiz için ortak olan özellikleri IUser Interface‘inde bırakıp bir kullanıcı tipine özel olan özellikleri ayırarak sorunumuzu çözebiliriz. Bizdeki örneği baz alırsak da Login, Logout ve ReadPost metotları kullanıcı tiplerimiz için ortak özellikler, ancak WritePost metodu Author tipindeki kullanıcılara özel bir özellik.

public interface IUser
{
    void Login();
    void Logout();
    void ReadPost();
}

public interface IAuthor
{
    void WritePost();
}

public class Author : IUser, IAuthor
{
    public void Login()
    {
        // Login kodu
    }

    public void Logout()
    {
        // Logout kodu
    }

    public void ReadPost()
    {
        // Readpost kodu
    }

    public void WritePost()
    {
        // WritePost kodu
    }
}

public class Reader : IUser
{
    public void Login()
    {
        // Login kodu
    }

    public void Logout()
    {
        // Logout kodu
    }

    public void ReadPost()
    {
        // Readpost kodu
    }
}

Burada WritePost metodunu ayırıp IAuthor Interface‘ini oluşturarak ve Author sınıfında IUser Interface‘inin yanında IAuthor Interface‘inden de kalıtım alarak tasarımımızı ihtiyacımıza göre düzenledik ve ISP‘ye uygun hale getirdik.

Önceki yazılar:

Solid Prensipleri
Single Responsibility Prensibi
Open-Closed Prensibi
Liskov Substitution Prensibi

Sonraki yazılar:

Dependency Inversion Prensibi

Bir Cevap Yazın