Kodlama : Static Sınıf Kötü müdür?

Kısa Cevap : Hayır, eğer kötü olan birşey varsa o da sadece static member olabilir.

Bu yazıda bir çoğumuzun duyduğu hatta hala bir çok yazılımcının kullanmaktan çekindiği Static Sınıf ve Static Member’lara bakacağız.

Eminim tecrübeli yazılımcıların bir çoğu Static Sınıf nedir dediğinizde hepsinin vecereceği ortak bir yanıt vardır ama bir çoğu aslında bu yanıtı tecrübesine ve sezgilerine yada kulaktan duyma bilgilerle ortaya çıkardığı derlemeye dayandırır. Zannetmiyorum ki hepsi msdn’de bu konunun başlığını okumamıştır.

Efsaneler

Bir çok yazılımcı efsanesi var,

  1. Static sınıf kötüdür
  2. Static member daha kötüdür
  3. Multi thread uygulamada static sorun çıkarır
  4. Entity Framework veya bir sınıfı static tanımlamış aman tanrım !

Msdn Tanımı

Öncelikle msdn’deki tanımı bir inceleyelim. (Kaynak : msdn)

A static class is basically the same as a non-static class, but there is one difference: a static class cannot be instantiated. In other words, you cannot use the new operator to create a variable of the class type. Because there is no instance variable, you access the members of a static class by using the class name itself.

Burada da anlaşılacağı üzere static sınıfın iki temel özelliği vardır,

  1. Initiate edilemez
  2. Member’lara doğrudan ulaşılır

Ayrıca aynı makalede şu ifadeleri de okuyalım

As is the case with all class types, the type information for a static class is loaded by the .NET runtime when the program that references the class is loaded. The program cannot specify exactly when the class is loaded. However, it is guaranteed to be loaded and to have its fields initialized and its static constructor called before the class is referenced for the first time in your program. A static constructor is only called one time, and a static class remains in memory for the lifetime of the application domain in which your program resides.

Göreceğiniz üzere aslında tanım çok basit. Ayrıca .Net Framework Applicaiton Domain seviyesinde size static sınıfın hafızada bir kopyasını oluşturacağını garanti ediyor ve kendi içerisinde constructor bir defa çağrılıyor. Böylece ortaya sadece 1 adet oluşturulmuş uygulama domain’i seviyesinde ortak bir sınıf çıkmış oluyor.

Peki tüm bunlar iyi de ne anlama geliyor?

Bir çok yazılımcı bu ortaklık kelimesine takılmış durumda. Oysa makalede “common” kelimesini ararsanız tanım içerisinde geçmediği gibi sadece tek bir yerde geçer o da “..static sınıfların ortak kullanımı initiate edilmiş obje ile uygulama domain’i içinde değer saklamak..” diye başka bir şey anlatır.

Multi Thread’ler ve Static Sınıflar

Şimdi asıl can alıcı noktaya gelelim. Multithread bir uygulamamız var ve static bir sınıf kullanıyoruz ne olucak bu iş ? Burada size çok net kısa bir yanıt dönüp sonra daha detaylı anlatmaya çalışacağım.

Microsoft’un bir çok finans uygulamasında kullandığı System.Math sınıfını incelediniz mi? Bu sınıf Static bir sınıftır ve içerisinde bir çok static metod barındırır. System.Math sınıfı bir çok finansal uygulamada hesaplama yapmak için kullanılır. Yani özetle eğer Multithread uygulamalar static sınıf metodlarını çağırırken değişkenlerin hesaplanmasında sorun olsaydı o zaman muhtemelen bir çok büyük finansal firmada karışıklıklar ortaya çıkardı !!

Static Metod ve Static Member ayrımı

İşte tam bu noktada elma ile armut’u bir birinden ayıralım. Static sınıflar kendisine doğrudan ulaşabileceğimiz birer metodlardır. Buna ister aynı anda 2 thread ulaşsın ister tek bu metodlar 2 ayrı thread arasında ortak bir değer karışıklığına neden olmaz. Her thread adete kendi metodu gibi o Static Metod’u kullanır.

Ancak ististası aşağıda,

Static Member yani Application Domain seviyesinde ister static bir sınıf içinde olsun ister static olmayan bir sınıf içerisinde olsun eğer elinizde “public static int _deger” gibi bir değişkeniniz varsa işte o zaman bu multithread uygulamalarda bu size sorun yaratabilir.

Static memberlar Application Domain seviyesinde doğrudan ulaşılabilir (özellikle ortak demiyorum ama evet ortak) alanlar olduğu için özel bir önlem almaz iseniz thread safe bir yapıda olmadıkları için bir thread’in yaptığı değişikliği bir başka thread okuyabilir.

Örnek

Elinizde şöyle bir kod parçası var ise,

Public static int Çarp(int a , int b) 
{
  int c = a * b;
  return c;
}

Burada hiç bir zaman sorun yaşamazsınız. Unutmayın Microsoft System.Math sınıfındaki metodlar da bundan farklı değil. Metod içindeki değişkenler o thread’e özeldir. Farklı thread’ler de kullansa her thread’in değişkeni ona özel olacaktır.

Ama eğer elinizde aynı metod şu şekilde ise

private static int c;

Public static int Çarp(int a , int b) 
{
  c = a * b;
  return c;
}

O zaman sorun yaşayabilirsiniz. Çünkü c değişkeni farklı thread’ler tarafından erişilebilir ve değiştirilebilir bir durumdadır.

Özet

Özetle en tecrübeli yazılımcıların bile tam emin olmadıkları yada çeşitli efsaneleri destekledikleri durumlarda bile düşünmeniz gereken detay bu çerçevede ele alınmalıdır.

Bu durumda,

  1. .Net Core uygulamalarında AddSingleton EntityFramework sınıfı tanımlamak
  2. Static bir sınıf tanımlamak
  3. Static bir connection tanımlamak

Gibi durumlar tamamiyle ilgili sınıfın içerisindeki hangi memberların Static Member olarak ele alındığına bağlı olarak değişir.Static Sınıf kötü değildir Static Member ve kullanım şekli durumu değiştirebilir.

Eğer hala öyle olmadığını ve hala “nasıl olur ya?!” diyorsanız testini yapmak çok basit. Test edin ve sonuçları görün 🙂 ben yaptım..

Reklam

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Connecting to %s