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 bir sınıf oluşturmanın en basit yolu, tüm değerleri ayarlayan bir oluşturucuyla readonly alanlarını kullanmak ve hiçbir ayarlayıcı sağlamamaktı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);
}

Yeni değerlerle güncellenmiş yeni bir nokta alırken özgün nokta değişmeden kalır. Bu desen .NET genelinde kullanılır; örneğin dizeler değişmezdir. ToUpper() çağırdığınızda, özgün dizeyi değiştirmek yerine yeni bir dize alırsınız.

Değişmez nesneler, oluşturulduktan sonra hiçbir kod onları değiştiremeyeceği için doğaları gereği iş parçacığı açısından güvenlidir. Ayrıca durumlarının beklenmedik bir şekilde asla değişmeyeceğini bildiğiniz için bunlar hakkında akıl yürütmek daha kolaydır.

challenge icon

Görev

Kolay

Oluşturulduktan sonra hiçbir zaman değişmeyecek şekilde nesnelerin nasıl tasarlanabileceğini gösteren değişmez 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; bu yaklaşım kodunu daha güvenli ve anlaşılması daha kolay hâle getirir.

Kodunu iki dosya arasında düzenleyeceksin:

  • Money.cs: Money namespace'inde değişmez bir Finance sınıfı oluştur. Para nesnen aşağıdakilere sahip olmalı:
    • İki readonly alan: Amount (decimal) ve Currency (string)
    • Her iki değeri de ayarlayan bir constructor - oluşturulduktan sonra bir Money nesnesi hiçbir zaman değişemez
    • Artırılmış tutara sahip new bir Add(decimal value) nesnesi döndüren Money metodu (aynı para birimiyle)
    • Azaltılmış tutara sahip new bir Subtract(decimal value) nesnesi döndüren Money metodu (aynı para birimiyle)
    • Tutarın kur ile çarpıldığı ve yeni para biriminin kullanıldığı new bir Convert(string newCurrency, decimal rate) nesnesi döndüren Money metodu
    • GetDisplay() biçiminde bir string döndüren "{Amount} {Currency}" metodu
    Unutma: bu metotların hiçbiri orijinal nesneyi değiştirmemeli; hepsi tamamen yeni Money örnekleri döndürmeli!
  • Program.cs: Ana dosyanda değişmezliği uygulamalı olarak göster. Başlangıçta bir Money nesnesi oluştur, ardından hem orijinale hem de sonuçlara ait başvuruları koruyarak bu nesne üzerinde işlemler gerçekleştir. Bu, birden fazla işlemden sonra bile orijinalin hiç değişmediğini kanıtlayacaktır.

Dört girdi alacaksın:

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

Çıktıyı şu biçimde yazdır:

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

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

Money çağrıldıktan sonra bile orijinal 100.00 USD nesnesinin hâlâ Add() gösterdiğine dikkat et; işte değişmezlik budur! Add() metodu, orijinali değiştirmeden 150.00 USD içeren tamamen yeni bir nesne oluşturdu. Dönüştürme, add 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

Kendi başına pratik yap: Online C# derleyicisi