Singleton Design Pattern ve Flutter üzerinde Kullanımı

Alperen Ekin
HardwareAndro
Published in
3 min readJun 22, 2020

--

Design Pattern’ler nesne yönelimli programlamanın temel taşlarındandır. Bu Pattern’lerden, Creational Design Pattern kolunda yere alan Singleton Pattern ise günümüz programlarında çokça görülen yapılardandır.

Peki Nedir Bu Singleton?

Singleton design pattern bir sınıftan sadece bir adet nesne yaratılmasını garanti etmek ve o sınıfın nesneye ait operasyonları kontrol etmek için temel bir nokta olmasına dayanır. Böylece Singleton sınıfa dair işlemlere herhangi bir başka sınıf tarafından erişilebilir ancak yeni bir nesne yaratılmasının da aynı zamanda önüne geçilmiş olur. Bu yönüyle static nesnelere benzetebiliriz ancak static nesneler program ayağa kalkmasıyla birlikte programa yük olarak bindiğinden, Singleton yapısı bu yükü azaltmamıza da yardımcı olur. Kısacası Singleton sınıflardan nesneler, sınıf üzerinden bir kere oluşturulur ve sonraki işlemlerde bu nesne üzerinden devam edilir. Singleton yapılar database gibi temel işlemlerde kullanışlıdır.

Sadece “1” nesne.

Singleton Sınıfların Temel Özellikleri Nelerdir?

  • Singleton sınıfların dışarıdan nesnesini oluşmasını istemediğimiz için Constructor’ları private olarak belirtilmelidir.
  • Singleton sınıfta kendine ait bir statik instance’ı vardı ve bu instance dışardan static bir getter method ile erişilebilir olmalıdır.
  • Genellikle Singleton sınıf Constructor’ları parametre almazlar.
  • Sadece bir adet instance oluşturmak istediğimiz için multi-thread dillerde Singleton sorunlar yaratabilir ancak Flutter bildiğimiz üzere tek thread üzerinden işleyen bir dil.
  • Singleton dizayn eager ve lazy olarak iki farklı şekilde kullanılabilir.

Flutter’da Singleton Pattern Kullanımı

Genel olarak Singleton’ı açıkladığımıza göre artık bir örnek üzerinde inceleyebiliriz. Ben bir Shared Preferences örneği üzerinden kullandım ancak Network Manager, Database gibi örneklerle de genişletmek mümkün. Kısaca özetleyecek olursak Shared Preferences programa ait istenilen bazı değerleri key-value ikilisi olarak depolamak amacıyla kullanılır.

class SharedPrefHelper {
static SharedPrefHelper _prefInstance =SharedPrefHelper._init();
SharedPreferences _sharedPreferences;

static SharedPrefHelper get prefInstance => _prefInstance;

SharedPrefHelper._init(){
SharedPreferences.getInstance().then((value){
_sharedPreferences = value;
});
}

static Future createInstance() async {
if(prefInstance._sharedPreferences == null){
prefInstance._sharedPreferences =
await SharedPreferences.getInstance();
}
return;
}

Örnekte görüldüğü üzere, öncelikle private bir Constructor’ımız var, ve bu Shared Preference değerinin atanmasını sağlıyor. Getter methodu ise sınıf üzerinden işlem yaparken bize yardım olacak. CreateInsance methodu ise Shared Preference’ın kullanıma hazır olup olmadığını, hazır değil ise hazır hale gelmesini sağlıyor.

bool checkContains(SharedPrefKeys key){
return _sharedPreferences.containsKey(key.toString());
}
bool getBool(SharedPrefKeys key) {
return _sharedPreferences.getBool(key.toString());
}

Future<void> setBool(SharedPrefKeys key, bool value) async {
await _sharedPreferences.setBool(key.toString(), value);
}

void remove(SharedPrefKeys key){
_sharedPreferences.remove(key.toString());
}

Sınıfın devamında ise Shared Preference’a ait işlemleri görüyoruz Singleton yapıyı oluşturduktan sonra ise kullanımı oldukça basit.

SharedPrefHelper.createInstance();

Diyerek Instance’ın oluşturulması işini garanti altına alıyoruz.

SharedPrefHelper.prefInstance.setBool(SharedPrefKeys.IS_MORNING, value);

Devamında ise sınıfa ait Instance’ı kullanarak sınıf üzerinden işlem yapabiliyoruz. Örnekte Shared Preference’da IS_MORNING key değerine ,value’yu atamış olduk.

Lazy Loading ve Eager Loading

Eager Loading işlemi yapıldığında Singleton sınıfın instance’ı, sınıfın kendisinin oluşmasıyla birlikte direkt olarak oluşur.

static SharedPrefHelper  _prefInstance =SharedPrefHelper._init();
SharedPreferences _sharedPreferences;

Buradaki yapı da Eager Loading’e bir örnektir. Programın yapısı gereği instance’a programın başlangıcından itibaren ihtiyaç olduğu için burada Eager olarak kullandık. Ancak eğer böyle bir ihtiyaç olmasaydı instance gereksiz bir biçimde yüklenmiş olacaktı ve hafıza da yer kaplayacaktı. Bu nedenle kullanılırken ihtiyacı göze almakta fayda var.

Lazy Loading’e göre dizayn edilmiş bir Singleton yapı da ise instance sınıfla birlikte değil, ihtiyaç duyduğunda createInstance methodu’nun çağırılması ile yüklenecekti ve hafıza sorunu yaratmayacaktı.

Singleton yapısını Shared Preference üzerinden uygulama temasında değişiklik yapma ve kaydetme işlemlerini yaptığım uygulama da bulabilirsiniz.

Singleton Design Patern’i mümkün olduğunca açıklamaya çalıştım. Başka yazılarda görüşmek dileğiyle. 🙋‍♂️

--

--