Menu
Coddy logo textTech

Değişmezlik Kalıpları

Coddy'nin C# Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 34 / 70.

Değişmezlik (Immutability), kapsüllemeyi (encapsulation) mantıksal uç noktasına taşır; bir nesne bir kez oluşturulduğunda asla değiştirilemez. Bu, verilerinizin beklenmedik bir şekilde değiştirilmesi konusunda asla endişelenmenize gerek kalmadığı için tüm hata kategorilerini ortadan kaldırır.

Değişmez (immutable) bir sınıf oluşturmanın en basit yolu, tüm değerleri ayarlayan bir yapıcı (constructor) ile birlikte readonly alanlar kullanmak ve hiçbir ayarlayıcı (setter) sunmamaktır:

public class Point
{
    public readonly int X;
    public readonly int Y;
    
    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }
}

Bir Point oluşturulduktan sonra, koordinatları değiştirilemez. Peki ya değiştirilmiş bir versiyonuna ihtiyacınız olursa? Mevcut nesneyi değiştirmek yerine, yeni bir tane döndürürsünüz:

public Point Move(int deltaX, int deltaY)
{
    return new Point(X + deltaX, Y + deltaY);
}

Orijinal nokta değişmeden kalırken, güncellenmiş değerlere sahip yeni bir nokta elde edersiniz. Bu desen .NET genelinde kullanılır; örneğin dizeler (strings) değişmezdir (immutable). ToUpper() metodunu çağırdığınızda, orijinali değiştirmek yerine yeni bir dize elde edersiniz.

Değişmez (immutable) nesneler, oluşturulduktan sonra hiçbir kod onları değiştiremediği için doğası gereği iş parçacığı açısından güvenlidir (thread-safe). Ayrıca, durumlarının asla beklenmedik bir şekilde değişmeyeceğini bildiğiniz için haklarında akıl yürütmek daha kolaydır.

challenge icon

Görev

Kolay

Nesnelerin oluşturulduktan sonra asla değişmeyecek şekilde nasıl tasarlanabileceğini gösteren değişmez (immutable) bir para sistemi oluşturalım. Her işlemin orijinali değiştirmek yerine yeni bir nesne döndürdüğü bir Money sınıfı oluşturacaksınız - bu desen, kodunuzu daha güvenli ve üzerinde akıl yürütmesi daha kolay hale getirir.

Kodunuzu iki dosya halinde düzenleyeceksiniz:

  • Money.cs: Finance ad alanı (namespace) içinde değişmez bir Money sınıfı oluşturun. Paranız şunlara sahip olmalıdır:
    • İki adet readonly alan: Amount (decimal) ve Currency (string)
    • Her iki değeri de ayarlayan bir yapıcı (constructor) - bir kez oluşturulduktan sonra, bir Money nesnesi asla değişemez
    • Artırılmış tutara (aynı para birimi) sahip yeni bir Money nesnesi döndüren bir Add(decimal value) metodu
    • Azaltılmış tutara (aynı para birimi) sahip yeni bir Money nesnesi döndüren bir Subtract(decimal value) metodu
    • Tutarı kur (rate) ile çarpılmış ve yeni para birimine sahip yeni bir Money nesnesi döndüren bir Convert(string newCurrency, decimal rate) metodu
    • "{Amount} {Currency}" formatında bir dize döndüren bir GetDisplay() metodu
    Unutmayın: bu metotların hiçbiri orijinal nesneyi değiştirmemelidir - hepsi yepyeni Money örnekleri döndürür!
  • Program.cs: Ana dosyanızda, değişmezliği (immutability) iş başında gösterin. Başlangıçta bir Money nesnesi oluşturun, ardından hem orijinaline hem de sonuçlara referansları tutarak üzerinde işlemler yapın. Bu, birden fazla işlemden sonra bile orijinalin asla değişmediğini kanıtlayacaktır.

Dört girdi alacaksınız:

  • Başlangıç tutarı (decimal)
  • Başlangıç para birimi (string)
  • Eklenecek tutar (decimal)
  • EUR'ya dönüşüm kuru (decimal)

Çıktıyı şu formatta yazdırın:

Original: {GetDisplay()}
After add: {GetDisplay()}
Original unchanged: {GetDisplay()}
Converted: {GetDisplay()}

Örneğin, girdiler 100.00, USD, 50.00 ve 0.85 ise çıktı şöyle olmalıdır:

Original: 100.00 USD
After add: 150.00 USD
Original unchanged: 100.00 USD
Converted: 127.50 EUR

Add() metodunu çağırdıktan sonra bile orijinal Money nesnesinin hala 100.00 USD gösterdiğine dikkat edin - işte değişmezlik budur! Add() metodu, orijinaline dokunmadan 150.00 USD değerine sahip tamamen yeni bir nesne oluşturdu. Dönüştürme işlemi, ekleme işleminin sonucu üzerinde gerçekleştirilir.

Kendin dene

using System;
using Finance;

class Program
{
    public static void Main(string[] args)
    {
        // Girdileri oku
        decimal initialAmount = Convert.ToDecimal(Console.ReadLine());
        string initialCurrency = Console.ReadLine();
        decimal amountToAdd = Convert.ToDecimal(Console.ReadLine());
        decimal conversionRate = Convert.ToDecimal(Console.ReadLine());

        // TODO: Başlangıç tutarı ve para birimi ile bir başlangıç Money nesnesi oluşturun

        // TODO: GetDisplay() kullanarak orijinal parayı yazdırın

        // TODO: Orijinal üzerinde Add() metodunu çağırın ve sonucu yeni bir değişkende saklayın

        // TODO: Ekleme işleminden sonraki sonucu GetDisplay() kullanarak yazdırın

        // TODO: Değişmediğini kanıtlamak için orijinali tekrar yazdırın

        // TODO: Eklenen sonucu dönüşüm oranını kullanarak EUR birimine dönüştürün

        // TODO: Dönüştürülen parayı GetDisplay() kullanarak yazdırın
    }
}
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