Değer Objeleri ve Entity Framework ile Kullanımı

You can access the English version via this link.

Bu yazıda Değer Objeleri nedir ve Entity Framework kullanırken değer objeleri nasıl kullanılabilir sorularına kısaca değineceğiz.

Photo by Franck on Unsplash

Değer Objeleri Nedir?

Özellikle Domain Driven Design yönteminde önem arz eden yapılardır. Tek başına anlam ifade etmeyen ama bir bilgi taşıyan yapılara değer objeleri denir. Buna örnek olarak tarih yapısını düşünebiliriz. Gün, ay, ve yıl olmak üzere 3 tane sayının bir araya gelmesiyle belirli bir tarihi işaret eden bir bilgi oluşur. Buna karşın bu tarihin ne anlam ifade ettiği belirsizdir. Değer objelerinin iki ana özelliğinden bahsedince bu konu daha anlaşılır olacaktır.

1 — Kimliksiz Oluşları

Değer objeleri kimliksiz varlıklardır. Yani veri tutarlar ama tek başlarına bir anlam ifade etmezler. DateTime yapısını düşünürsek bir tarih bilgisi taşır. Buna karşın tek başına kullanıldığı zaman bu tarihin ne anlam ifade ettiğini bilemeyiz. Kimliği olan bir varlık tarafından kullanıldıkları zaman değer objeleri bir anlam kazanırlar. Kullanıcı, sipariş veya kargo varlıklarını hayal edelim. Tarih bilgisi bu varlıklarla birlikte doğum tarihi, siparişin oluşturulma tarihi veya bir kargonun teslim tarihi gibi anlamlara sahip olabilir.

2 — Değiştirilemez (Immutable) Oluşları

Objeler oluşturulurken yapıcı metotları aracılığıyla verileri alırlar ve bu veriler bir daha değiştirilemezler. DateTime örneği ile bu durumu açıklayabiliriz. Gün, ay ve yıl değerleri ile tarih objesini oluşturduktan sonra bu değeleri değiştiremeyiz. Yeni bir tarih belirlemek istersek yeniden bir DateTime objesi oluşturmamız gerekmektedir.

Değer Objelerini Kullanmanın Faydaları

Tasarımın daha kolay anlaşılır olmasını sağlar

Yukarıdaki kod parçasına baktığımız zaman, kullanıcı sınıfının ikinci versiyonu daha okunaklı bir haldedir. Verileri bir araya gruplayarak bilgi haline getirilmesi kodun sürdürülebilirliğine de pozitif etki yaratacaktır.

Paralel programlama yaparken güvenlik

Paralel kod çalışması sırasında farklı threadler tarafından objelerin üzerinde taşıdıkları değerler değiştirilmek istenebilir. Bu durumda “yarış durumu” (race condition) ortaya çıkar. Yarış durumu sebebiyle de program her çalışmada farklı sonuçlar üretebilir. Değer objeleri değiştirilemez oldukları için yarış durumu oluşması söz konusu olmayacaktır.

Değer Objelerinin Entity Framework ile Kullanılması

Bu başlık altında değer objesine sahip varlıkların Entity Framework ile veri tabanına kaydedilmesi ve veri tabanından sorgulanması için gereken adımlara göz atacağız.

Kod örneğine GitHub linki üzerinden erişebilirsiniz.

Başlarken

Örneğimiz için Sipariş adında bir sınıf oluşturacağız. Basitçe ülke ve şehir değerlerine sahip olacak bir Adres değer objesi üreterek siparişin nereye teslim edileceğini saklayacağız.

İmplementasyon

1 — BaseValueObject Sınıfının Oluşturulması

Öncelikli olarak BaseValueObject adında bir sınıf tasarlayarak işe başlayalım. implement-value-objects yazısında yer alan kod parçasının birazcık değiştirilmiş hali aşağıda yer almaktadır. Bu sınıf değer objelerimiz için gerekli olan temel operasyonları içermektedir. Aşağıda iki değer objesinin eşit olup olmadığının kıyaslanmasına dair bir kod parçası görebilmekteyiz.

2 — Address Değer Objesinin Oluşturulması

Adres değer objemiz gerekli parametreleri yapıcı metodu aracılığıyla elde etmektedir. Ayrıca görülebileceği gibi Country ve City alanlarına yapıcı metot dışında değer ataması yapılan başka bir yer bulunmamaktadır.

NOT: Country ve City alanlarının private set olarak setter değerlerinin olması gerekmektedir. Bunun sebebi veri tabanından getirilen değerlerin Entity Framework tarafından bu alanlara yerleştirilirken ihtiyaç duyulmasıdır.

3 — Sipariş Sınıfının Oluşturulması

Sadece kullanıcı adı ve adres bilgisine sahip olacak şekilde basit bir Sipariş sınıfı oluşturalım.

4 — Sipariş Sınıfı ve Veri Tabanı Arasındaki İlişkinin Ayarlanması

Sipariş sınıfımızın veri tabanı tablo ve kolonlarıyla olan ilişkisini belirlemek için IEntityTypeConfiguration arayüzünden bir örnek oluşturarak sürece devam edelim. FluentApi ile aşağıdaki gibi bir ayarlama yapabiliriz.

Değer objemizi Entity Framework aracılığıyla kullanmak için OwnsOne metodundan yararlanıyoruz. Eğer kolon ismini HasColumnName metodu ile belirtmezsek varsayılan olarak ‘Address_Country’ ve ‘Address_City’ şeklinde isimlendirilmiş kolon isimleri ile adres değer objemizin alanları ilişkilendirilecektir. Yukarıda yer alan örnekte ise veri tabanınında Country ve City isimli kolonların olduğunu ve adres değer objemizin bu kolonlarla ilişkide olduğunu belirtmiş oluyoruz.

Sipariş Kaydetme

Yukarıdaki kod parçasında görüleceği gibi sipariş sınıfına ait bir örnek oluşturup veri tabanına kaydetmek, değer objesine sahip olmayan bir varlığı kaydetmek ile aynı şekilde yapılmaktadır.

Sipariş Sorgulama

Bellekte yüklü iki değer objesi için Equals metodu ile eşitlik kontrolü yapılabilmektedir. Buna karşın yukarıdaki kod parçasının alt satırında yer alan sorgulama yöntemi ile veri tabanı sorgulaması yapmayı başaramadım. Bunun yerine veri tabanında yer alan her bir kolona karşılık gelen alanlar için sorgulama yapabildim. Bu şekilde Entity Framework, sorgularımı başarılı şekilde oluşturup çalıştırabildi.

Umarım yararlı bir yazı olmuştur. Diğer yazılarıma göz atmak için bu linke tıklayabilirsiniz.

var software = ConvertFrom(caffeine)