İlkay İlknur

just a developer...

Immutable Nesne Kavramı

Son zamanlarda .NET ve C# tarafinda adını sıklıkla duyduğumuz eski bir kavram immutability kavramı. Bu yazımızda istedim ki hem .NET Framework içerisindeki Immutable tiplere kısaca bir bakalım hem de C# ile kendi immutable tiplerimizi nasıl yazarız konusuna değinelim.

"Immutable" kelimesinin Türkçe karşılığı "Değişmez". Peki immutable(değişmez)  object ne demek ? Bir tip Immutable dediğimizde aklımıza ne gelmeli ?

Immutable nesnelerin state'i object yaratıldıktan sonra değiştirilemez. Siz nesneyi yaratırken içerisinde bulunacak olan değerleri verirsiniz ve sonrasında bu değerleri değiştiremezsiniz. Eğer bir Immutable nesnenin state'ini değiştirmek isterseniz vermek istediğiniz state'i taşıyacak olan yeni bir nesne yaratmak zorundasınız.

Diyelim ki aşağıdaki gibi bir sınıfımız olsun.

public class MutableClass
{
    public int X { getset; }
    public int Y { getset; }
    public MutableClass(int x, int y)
    {
        this.X = x;
        this.Y = y;
    }
}

Buraya kadar yazdığımız kodun normalde yazdığımız koddan hiçbir farkı yok. Peki bir de bu sınıfı kullanan kısa bir kod yazalım.

class Program
{
    static void Main(string[] args)
    {
        MutableClass mutable = new MutableClass(10, 20);
        Console.WriteLine("Values: X={0},Y={1}", mutable.X, mutable.Y);
        mutable.X = 100;
        mutable.Y = 200;
        Console.WriteLine("Values: X={0},Y={1}", mutable.X, mutable.Y);
    }
}

Yukarıdaki kodu okursanız öncelikli olarak MutableClass tipinde bir nesne yarattık. Nesneyi yaratırken de içerisinde taşıyacağı x ve y değerlerini constructorına parametre olarak geçtik. Sonrasında ise x ve y fieldlarına bu sefer yeni değerler atadım. Daha doğrusu MutableClass tipinin tanımı benim bu işlemi yapmama imkan verdi.

Eğer bir nesneyi yarattıktan sonra nesnenin state'ini değiştirebiliyorsanız o tip Immutable'ın tam zıttı olan "Mutable" bir tiptir.

Şimdi bir de aşağıdaki koda bakalım.

public class ImmutableClass
{
    private readonly int _x;
    private readonly int _y;

    public int X
    {
        get
        {
            return _x;
        }
    }
    public int Y
    {
        get
        {
            return _y;
        }
    }
    public ImmutableClass(int x, int y)
    {
        this._x = x;
        this._y = y;
    }
}

Yukarıdaki sınıfta bu sefer readonly 2 field tanımladık. Sonrasında ise X ve Y propertylerinin getterlarından da bu readonly fieldları döndürdük. Ayrıca propertylerin setterlarını da kaldırdık !!!

Bu durumda ImmutableClass tipinden bir nesne örneği yaratmak isteyen yine MutableClass tipinde olduğu gibi x ve y fieldlarının değerlerini constructordan geçecek ve  yeni bir nesne yaratacak. Ancak bu sefer nesneyi yarattıktan sonra X ve Y propertylerinin setterları olmadığı için bu fieldların değerlerini değiştiremeyecek.

Aynı zamanda x ve y fieldlarını readonly olarak tanımladığımız için artık Immutable sınıfı içerisine internal veya private bir metot yazsanız bile bu x ve y fieldlarının değerlerini siz de değiştiremeyeceksiniz :)

Peki gelelim Immutable objectlerin faydalarına :)

Immutable objectlerin en önemli avantajı multi thread uygulamalarda ortaya çıkıyor. Immutable objectleri stateleri değiştirilemediği için o nesneyi kaç tane thread kullanırsa kullansın o nesne üzerinde değişiklik yapamıyor. Hal böyle olunca siz de threadler arasındaki senkronizasyonu sağlayacak olan mekanizmaları yazmaktan kurtulmuş oluyorsunuz ve otomatik olarak yazdığınız tip thread-safe oluyor.

.NET Framework Tarafında Immutable Tipler

.NET Framework tarafında Immutable tipler neler diye baktığımızda karşımıza ilk sırada string tipi çıkıyor. Aslında string tarafında  tipik senaryolara hepimiz hakimizdir. Bir for döngüsü içerisinde + kullanarak string birleştirmek yerine StringBuilder tipini kullanmak gibi tricklerin altında string tipinin aslında Immutable olması yatmakta. Zaten string tipinin içerisindeki metotlara bakarsanız çoğunun dönüş tipi stringtir.

Örneğin string.Concat metoduna 2 farklı string verirseniz bu 2 stringi birleşimini içerisinde bulunduran yeni bir string yaratılır.

.NET Framework içerisinde bulunan ama ayrı olarak NuGet package olarak sunulan Immutable Collections da aslında yukarıda bahsettiğimiz Immutable kavramının collectionlar üzerinde implemente edilmiş hali.

Immutable tipler thread-safety konusunda bizlere kolaylık ve iç rahatlığı sağlasa da her tipi immutable yapmak da doğru değil. Yazılım dünyasındaki her kavramda her güzellikte olduğu gibi bunu da gereken yerlerde kullanmak önemli. ;)

Umarim faydalı bir yazı olmuştur.



Yorum Gönder