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.
Görev
KolayOluş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:Moneynamespace'inde değişmez birFinancesınıfı oluştur. Para nesnen aşağıdakilere sahip olmalı:- İki
readonlyalan:Amount(decimal) veCurrency(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ürenMoneymetodu (aynı para birimiyle) - Azaltılmış tutara sahip new bir
Subtract(decimal value)nesnesi döndürenMoneymetodu (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ürenMoneymetodu GetDisplay()biçiminde bir string döndüren"{Amount} {Currency}"metodu
Moneyörnekleri döndürmeli!- İki
Program.cs: Ana dosyanda değişmezliği uygulamalı olarak göster. Başlangıçta birMoneynesnesi 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 EURMoney ç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
}
}
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
1OOP Temelleri
Harici Dosyalarİsim Alanları ve YönergelerSınıf ve Nesnelere Giriş'this' Anahtar KelimesiMetotlar ve ParametrelerAlanlar ve ÖzelliklerYapıcı MetotlarNesne BaşlatıcılarÖzet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtım (:) Sözdizimi'base' Anahtar KelimesiVirtual ve Override Anahtar KelimeleriSealed Sınıflar'object' Temel SınıfıÖzet - Çalışan Hiyerarşisi7İleri Düzey Özellikler
Operatör Aşırı Yüklemeİndeksleyiciler (this[])ToString() Geçersiz KılmaGenişletme MetotlarıÖzet - Özel Liste10Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişThread-Safe SingletonFactory KalıbıObserver Kalıbı (Olaylar)Strategy Kalıbı2Özellikler ve Statik Üyeler
Otomatik Uygulanan ÖzelliklerSadece Okunur/Yazılır ÖzelliklerStatik Alanlar ve MetotlarStatik Sınıflarİfade Gövdeli Üyeler5Polimorfizm ve Arayüzler
Derleme vs Çalışma Zamanı PolimorfizmiArayüz vs Soyut SınıfÇoklu ArayüzlerBelirgin ArayüzlerUpcasting ve DowncastingÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kalıtım yerine KompozisyonGenerics (Sınıflar ve Metotlar)Delegates ve EventlerAttributes ve ReflectionIDisposable ve using İfadesiDependency Injection Temelleri11Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit Kalıbı3Sınıf Mimarisi
Örnek vs Statik Veri'readonly' ve 'const' Anahtar KelimeleriDestekleyici Alanlar (Backing Fields)Özet - Banka Hesabı Yöneticisi6Kapsülleme
Erişim BelirleyicilerKapsülleme için ÖzelliklerVeri Gizleme UygulamasıDeğişmezlik KalıplarıÖzet - Öğrenci KayıtlarıKendi başına pratik yap: Online C# derleyicisi