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 Pattern, bir sınıfın uygulamanız boyunca yalnızca bir instance'a sahip olmasını ve bu instance'a genel bir erişim noktası sunulmasını sağlayan bir oluşturucu tasarım kalıbıdır. Bu, configuration manager'lar, connection pool'ları veya logging service'leri gibi paylaşılması gereken kaynaklar için kullanışlıdır.

Bu desen, constructor'ı private yaparak direct instantiation'ı engeller. Bunun yerine, bir static method tek instance'a access'i kontrol eder:

public class DatabaseConnection {
    private static DatabaseConnection instance;
    
    // Private 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() için yapılan her çağrı aynı nesneyi döndürür. Instance yalnızca ilk kez istendiğinde oluşturulur. Buna lazy initialization denir:

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

System.out.println(db1 == db2);  // true - same instance

Bir Singleton'ın temel bileşenleri şunlardır: instance'ı tutan bir private static field, bir private constructor ve instance'ı döndüren bir public static yöntem. Bu birleşim, nesneyi kaç kez istersen iste, her zaman aynı nesneyi almanı garanti eder.

challenge icon

Görev

Kolay

Singleton Deseni kullanarak bir uygulama için yapılandırma yöneticisi oluşturalım! Yapılandırma yöneticiniz, uygulamanızın bu yapılandırmaya kaç kez erişmeye çalıştığından bağımsız olarak uygulamanızın tüm bölümlerinin aynı ayarları paylaşmasını sağlayacak.

Kodunuzu iki dosyaya ayıracaksınız:

  • 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ı:

    Tek bir instance'ı tutacak private static bir field.

    appName adlı private bir String field ve maxUsers adlı private bir int field.

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

    Instance'ı yalnızca henüz mevcut değilse oluşturan (lazy initialization), 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'ın doğru çalıştığını gösterin! İki input alacaksınız: yeni bir uygulama adı (String) ve yeni bir maksimum kullanıcı değeri (integer).

    İlk olarak bir AppConfig instance'ı 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 metotlarını çağırarak input değerlerinizi kullanıp ayarları güncelleyin.

    Başka bir instance alın ve bunu config2 içinde saklayın. config1 üzerinden yapılan değişiklikleri yansıttığı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 aynı nesneyi gösterip göstermediğini Same instance: [true/false] biçiminde yazdırın.

İki input'u şu sırayla alacaksınız: yeni uygulama adı (String) ve yeni maksimum kullanıcı sayısı (integer).

Bu challenge, Singleton Deseni'nin temel faydasını gösterir: Yapılandırmaya kaç kez erişmeye çalışırsanız çalışın, her zaman aynı paylaşılan duruma sahip aynı instance'ı elde edersiniz!

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'e kaydet
        
        // TODO: Varsayılan değerleri göstermek için config1 üzerinde displaySettings() çağır
        
        // TODO: config1 üzerinde setAppName ve setMaxUsers kullanarak ayarları güncelle
        
        // TODO: Başka bir örnek al ve config2'ye kaydet
        
        // TODO: Değişikliklerin paylaşıldığını kanıtlamak için config2 üzerinde displaySettings() çağır
        
        // TODO: Her iki referansın da aynı nesneye işaret edip etmediğini yazdır:
        // "Same instance: [true/false]" using config1 == config2
    }
}
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

Kendi başına pratik yap: Online Java derleyicisi