Menu
Coddy logo textTech

Singleton Kalıbı

Coddy'nin Java Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 65 / 87.

Singleton Deseni, bir sınıfın uygulamanız boyunca yalnızca bir örneğe sahip olmasını sağlayan ve bu örneğe küresel bir erişim noktası sunan bir oluşturucu (creational) tasarım desenidir. Bu, yapılandırma yöneticileri, bağlantı havuzları veya günlükleme (logging) servisleri gibi paylaşılması gereken kaynaklar için kullanışlıdır.

Bu desen, yapıcıyı (constructor) private yaparak çalışır ve doğrudan örneklemeyi engeller. Bunun yerine, statik bir metot tek örneğe erişimi kontrol eder:

public class DatabaseConnection {
    private static DatabaseConnection instance;
    
    // Özel yapıcı (constructor) doğrudan örneklemeyi engeller
    private DatabaseConnection() {
        System.out.println("Connection created");
    }
    
    // Global erişim noktası
    public static DatabaseConnection getInstance() {
        if (instance == null) {
            instance = new DatabaseConnection();
        }
        return instance;
    }
    
    public void query(String sql) {
        System.out.println("Executing: " + sql);
    }
}

getInstance() fonksiyonuna yapılan her çağrı aynı nesneyi döndürür. Örnek, yalnızca ilk kez istendiğinde oluşturulur; buna lazy initialization (tembel başlatma) denir:

DatabaseConnection db1 = DatabaseConnection.getInstance();
DatabaseConnection db2 = DatabaseConnection.getInstance();

System.out.println(db1 == db2);  // true - aynı örnek

Bir Singleton'ın temel bileşenleri şunlardır: örneği tutan bir private static alan, bir private yapıcı (constructor) ve örneği döndüren bir public static metot. Bu kombinasyon, nesneyi kaç kez isterseniz isteyin, her zaman aynı nesneyi almanızı garanti eder.

challenge icon

Görev

Kolay

Singleton Desenini kullanarak bir uygulama için yapılandırma yöneticisi oluşturalım! Yapılandırma yöneticiniz, uygulamanızın tüm bölümlerinin, erişim talebi kaç kez yapılırsa yapılsın aynı ayarları paylaşmasını sağlayacaktır.

Kodunuzu iki dosya halinde düzenleyeceksiniz:

  • AppConfig.java: Uygulama yapılandırma ayarlarını yöneten bir Singleton sınıfı oluşturun. AppConfig sınıfınız şunlara sahip olmalıdır:

    Tek örneği tutmak için private static bir alan.

    appName adında private bir String alanı ve maxUsers adında private bir int alanı.

    appName değerini "MyApplication" ve maxUsers değerini 100 olarak başlatan, ardından AppConfig initialized yazdıran private bir yapıcı (constructor).

    Örneği yalnızca henüz mevcut değilse oluşturan (lazy initialization) ve ardından onu döndüren public static bir getInstance() metodu.

    Uygulama adını güncelleyen bir setAppName(String name) metodu.

    Maksimum kullanıcı sayısını güncelleyen bir setMaxUsers(int max) metodu.

    App: [appName], Max Users: [maxUsers] yazdıran bir displaySettings() metodu.

  • Main.java: Singleton yapınızın doğru çalıştığını gösterin! İki girdi alacaksınız: yeni bir uygulama adı (String) ve yeni bir maksimum kullanıcı değeri (tamsayı).

    Öncelikle, AppConfig sınıfından bir örnek alın ve bunu config1 adlı bir değişkende saklayın. Varsayılan değerleri göstermek için displaySettings() metodunu çağırın.

    Ardından, config1 üzerinde setAppName ve setMaxUsers metodlarını çağırarak girdi değerlerinizi kullanarak ayarları güncelleyin.

    Başka bir örnek alın ve bunu config2 içinde saklayın. config1 üzerinden yapılan değişikliklerin yansıtıldığını kanıtlamak için config2 üzerinde displaySettings() metodunu çağırın.

    Son olarak, config1 == config2 karşılaştırmasını yaparak her iki referansın da aynı nesneyi işaret edip etmediğini yazdırın: Same instance: [true/false].

Sırasıyla iki girdi alacaksınız: yeni uygulama adı (String) ve yeni maksimum kullanıcı sayısı (tamsayı).

Bu meydan okuma, Singleton Deseninin temel faydasını göstermektedir: Yapılandırmayı kaç kez isterseniz isteyin, her zaman aynı paylaşılan duruma sahip aynı örneği alırsınız!

Kopya kağıdı

Singleton Deseni (Singleton Pattern), bir sınıfın uygulama boyunca yalnızca bir örneğe sahip olmasını sağlayarak bu örneğe küresel bir erişim noktası sunar.

Temel Bileşenler:

  • Tek örneği tutan bir private static alan
  • Doğrudan örneklemeyi önlemek için bir private yapıcı (constructor)
  • Örneği döndüren bir public static metot

Temel Uygulama:

public class DatabaseConnection {
    private static DatabaseConnection instance;
    
    // Özel yapıcı doğrudan örneklemeyi önler
    private DatabaseConnection() {
        System.out.println("Connection created");
    }
    
    // Küresel erişim noktası
    public static DatabaseConnection getInstance() {
        if (instance == null) {
            instance = new DatabaseConnection();
        }
        return instance;
    }
    
    public void query(String sql) {
        System.out.println("Executing: " + sql);
    }
}

Kullanım:

DatabaseConnection db1 = DatabaseConnection.getInstance();
DatabaseConnection db2 = DatabaseConnection.getInstance();

System.out.println(db1 == db2);  // true - aynı örnek

Örnek yalnızca ilk kez istendiğinde oluşturulur; buna geç yükleme (lazy initialization) denir. getInstance() yöntemine yapılan her çağrı aynı nesneyi döndürerek uygulama genelinde paylaşılan bir durum sağlar.

Kendin dene

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Girdileri oku
        String newAppName = scanner.nextLine();
        int newMaxUsers = scanner.nextInt();
        
        // TODO: AppConfig'in ilk örneğini al ve config1 içinde sakla
        
        // TODO: Varsayılan değerleri göstermek için config1 üzerinde displaySettings() metodunu çağır
        
        // TODO: config1 üzerinde setAppName ve setMaxUsers kullanarak ayarları güncelle
        
        // TODO: Başka bir örnek al ve config2 içinde sakla
        
        // TODO: Değişikliklerin paylaşıldığını kanıtlamak için config2 üzerinde displaySettings() metodunu çağır
        
        // TODO: Her iki referansın da aynı nesneyi işaret edip etmediğini yazdır:
        // config1 == config2 kullanarak "Same instance: [true/false]"
    }
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler