Press "Enter" to skip to content

Effective Java Madde 16: public sınıflarda erişim metotları kullanın, public alanlar değil

Last updated on April 5, 2020

Zaman zaman birkaç tane alanı bir arada tutmaktan başka bir iş yapmayan sınıflar yazma eğiliminde olabilirsiniz:

// Bunun gibi sınıflar public olmamalıdır! 
class Point { 
    public double x; 
    public double y; 
}

Bu tür sınıfların veri alanları direk erişime açık olduğu için, kapsülleme prensibinin (encapsulation) faydalarını kullanamazlar. (Madde 15) API değiştirmeden kod içerisinde değişiklik yapmak zorlaşır, sabit değerler tanımlayamazsınız ve bir alana erişildiğinde müdahale etme şansınız olmaz. Katı görüşlü programcılar bu tür sınıfları lanetli olarak görürler ve bunların yerine private alanları ve public erişim metotları olan sınıflar yazılması gerektiğini savunurlar.

// Erişim metotları kullanılarak alanlar kapsüllenmiştir
class Point {
    private double x;
    private double y;
    
    public Point(double x, double y) {
        this.x = x;
        this.y = y; 
    }
    
    public double getX() { return x; }
    public double getY() { return y; }
    public void setX(double x) { this.x = x; }
    public void setY(double y) { this.y = y; }
}

Katı programcılar public sınıflar söz konusu olduğunda bu söylediklerinde haklılar: eğer bir sınıf paket dışından erişilebiliyorsa o zaman mutlaka erişim metotları sağlayın ki ileride sınıfın iç yapısında değişiklik yapma şansınız olsun. Eğer public bir sınıf veri alanlarını dışarıya açarsa, istemci kodu yayılmış olacağı için değişiklik yapma şansı tamamen kaybolur.

Ancak, eğer sınıf pakete özel (package private) erişime sahipse veya dahili private bir sınıf ise (private nested class), o zaman veri alanlarını dışarıya açma konusunda bir mahsur yoktur. Bu yaklaşım, erişim metotları kullanılmadığı için hem sınıfın kendi içerisinde hem de istemcide daha az görsel kirlilik yaratacaktır. Bu durumda istemci kodu sınıfın gerçekleştirimine bağlı olsa da, paket içerisinde kalmak zorunda olduğu için ileride yapılmak istenebilecek değişikliklere engel olmaz. Dolayısıyla sınıfın kendisi public olmadığı sürece, veri alanlarına erişebilecek istemci kodu paket içerisinde kalmak zorunda olduğu için ileride değişiklik yapma hakkını korumuş oluruz. Dahili private sınıf kullanıldığı durumda ise erişim, dahili sınıfı kapsayan sınıfla sınırlı kalacaktır.

Java platformu içerisinde birkaç sınıf public sınıfların veri alanlarını direk olan dışarıya açmama tavsiyesine uymamaktadır. java.awt paketindeki Point ve Dimension sınıflarını öne çıkan örnekler olarak gösterebiliriz. Bunlar taklit edilmesi gereken örnekler olmaktan ziyade eğitici bir öykü olarak görülmelidir. Madde 67’de anlatıldığı üzere, Dimension sınıfının iç yapısını dışarıya açması, bugün bile bizimle olan ciddi bir performans sorununa yol açmıştır.

public bir sınıfın veri alanlarını dışarıya açması hiçbir durumda iyi bir fikir olmasa da, bu alanlar değiştirilemez olduğu zaman daha az zararlıdır. Örneğin, aşağıdaki sınıf her bir nesnenin geçerli bir zaman değerini temsil edeceğini garanti etmektedir:

//public ama değiştirilemez alanları olan bir sınıf
public final class Time {
    private static final int HOURS_PER_DAY    = 24;
    private static final int MINUTES_PER_HOUR = 60;
    public final int hour;
    public final int minute;

    public Time(int hour, int minute) {
        if (hour < 0 || hour >= HOURS_PER_DAY) {
            throw new IllegalArgumentException("Hour: " + hour);
        }
        if (minute < 0 || minute >= MINUTES_PER_HOUR) {
            throw new IllegalArgumentException("Min: " + minute); 
        }
        
        this.hour = hour;
        this.minute = minute;
    }
    ... // Sınıfın geri kalanı ihmal edilmiştir
}

Özet olarak, public sınıflar değiştirilebilir alanları asla dışarıya açmamalıdırlar. Değiştirilemez alanların ise dışarıya açılması her ne kadar daha az zararlı olsa da ideal değildir. Dahili private veya pakete özel (package private) sınıflar söz konusu olduğunda ise, istemci kodu dışarıya açık olmayacağı için alanlar değiştirilebilir olsa bile bunları dışarıya açmakta bir mahsur yoktur.

Share

Leave a Reply

%d bloggers like this: