- Yazılım geliştirirken çoğumuzun ilk adımı, veritabanı odaklı bir yaklaşım olur. Özellikle Entity Framework Core (EF Core) gibi araçlarla çalışırken, genellikle veri yapılarımızı ve ilişkileri ön planda tutarız. Ancak, iş kuralları karmaşıklaştıkça ve uygulamalar büyüdükçe, bu yaklaşım bazı sorunlara yol açabilir. İşte tam bu noktada Domain Driven Design (DDD) devreye girer.
title:: Domain Driven Design Entity Nedir ?
-
DDD'ye Bir Bakış Atalım
DDD, yazılımı geliştirirken odağımızı veriden çok, iş kurallarına ve gerçek hayattaki problemlere yöneltmemizi sağlayan bir yaklaşımdır. Yani, uygulamanın "ne yaptığına" ve "nasıl çalıştığına" odaklanırız. DDD'nin temel amacı, iş birimiyle (domain expert) aynı dili konuşan, esnek ve sürdürülebilir bir kod tabanı oluşturmaktır.
Bu aslında insanların biraz kafasını karıştıran bir durum örnek olarak domain expert dendiği zaman insanların aklına doğrudan çok deneyimli yazılımı yalamış yutmuş bir insan bir geliştirici geliyor şahsen ben ve bir çok arkadaşım böyle düşünmüştük.
Ama aslında konu biraz farklı.
Bir yazılımcıya maden sektörü ile ilgili bir uygulama geliştirmesi söylense, ilgili yazılımcının konuya dair herhangi bir bilgisi olmaksızın uygulama geliştirmesi pek mümkün olmayacaktır. Örnek olarak kardeşim biz bir maden envanteri programı istiyoruz hadi beraber geliştirelim al bu bilgisayar hadi kod yazmaya başla dediğimiz zaman geliştirici eğer veri tabanında ne gibi veriler tutulacak hangi tablo ne ile ilgili bilmez ise hiçbir şey yapamaz değil mi ?
Yazılımcının bu işi gerçekleştirebilmesi için; tutulacak işlenecek yorumlanacak verileri ve yönlendirmeleri , ne şekilde yönlendirileceği, işin mevzuatı vs. gibi türlü bilgilerin aydınlatılması gerekmektedir. Peki bu konulara hakim olan kim var? Sizden projeyi yapmanızı isteyen kişi peki bu kişi yazılım biliyor mu? Hayır . Ama iş akışını ve yürüyüşünü gerekli olan bilgileri bilen bu kişi bizim için domain expert oluyor işte.
Yani daha resmi bir açıklama yapmak gerekirse Domain Expert, yazılımın geliştirilmekte olduğu iş alanının (domain’in) uzmanıdır.
Yani, yazılımcıların kodladığı sistemin gerçek dünyadaki karşılığını çok iyi bilen kişidir.
-
💼 Kim olabilir?
İş alanına göre farklılık gösterir:
Sektör / Uygulama | Domain Expert |
---|
E-ticaret | Pazarlama müdürü, stok yöneticisi |
Bankacılık | Kredi analisti, finans danışmanı |
Hastane otomasyonu | Doktor, hemşire, hasta kabul görevlisi |
Lojistik uygulaması | Nakliye planlayıcısı, depo yöneticisi |
İnsan kaynakları yazılımı | İK uzmanı, bordro sorumlusu |
-
🧩 Yazılımdaki Rolü Nedir?
DDD’de Domain Expert’in rolü:
- Yazılımcılara iş kurallarını ve süreçleri açıklar
- Geliştiricilerle birlikte Ubiquitous Language (Ortak Dil) geliştirir
- Gerçek hayat iş akışlarını yazılımla uyumlu hâle getirir
- Domain modelin (Entity, Value Object, Aggregate) doğru kurulmasını sağlar
- Şimdiye kadar Domain Expert kavramını detaylıca inceledik ve yazılım geliştirirken iş alanına hakim kişilerin ne kadar kritik bir rol oynadığını gördük. Ancak sadece domain expert’in bilgili olması yeterli değil; bu bilgilerin doğru ve eksiksiz bir şekilde yazılıma aktarılması da gerekir.
İşte bu noktada hem yazılımcıların hem de domain expert’lerin aynı dili konuşması büyük önem kazanır. DDD’nin bize sunduğu en güçlü araçlardan biri olan Ubiquitous Language, tam da bu ihtiyacı karşılar.
-
Ubiquitous Language (Her Yerde Geçerli Ortak Dil)
Domain-Driven Design’ın temel taşlarından biri de “Ubiquitous Language” yani her yerde geçerli ortak dildir. Bu kavram, yazılım geliştirme sürecinde yer alan tüm paydaşların (yazılımcılar, domain expert’ler, ürün sahipleri vb.) aynı dili konuşmasını ifade eder.
Peki neden önemli?
Yazılım geliştirirken yaşanan en büyük problemlerden biri, aynı şeyi farklı şekilde anlatma sorunudur. Örneğin:
- Domain uzmanı “müşteri” der, yazılımcı “kullanıcı” olarak kodlar.
- Domain uzmanı “ürün tipi” der, yazılımcı “kategori” olarak veritabanına yazar.
- Domain uzmanı “sipariş onayı” derken, sistemde bu “durum güncellemesi” olarak geçer.
İşte bu farklar zamanla iletişim kopukluklarına, yanlış modellemelere ve bakımı zor sistemlere yol açar. Ubiquitous Language bu sorunu çözmeyi hedefler.
-
📌 Ortak Dil Nasıl Oluşturulur?
- Yazılımcılar ve domain uzmanları sık sık bir araya gelir.
- Kavramlar netleştirilir: “Müşteri” nedir, “Sipariş” nedir, “İptal” ne zaman olur? gibi gibi ...
- Bu kavramlar sadece konuşmalarda değil, kodda da birebir kullanılır.
- Sınıf isimleri, methodlar, değişkenler, veri tabanı alanları hep bu dile göre yazılır.
-
bash
public class Order
{
public Customer Customer { get; private set; }
public List<OrderItem> Items { get; private set; }
public OrderStatus Status { get; private set; }
}
- Yukarıdaki örnekte “Order”, “Customer”, “OrderItem” gibi kavramlar hem iş dünyasında kullanılan terimlerdir hem de kodun içinde aynen bu şekilde yer alır. Böylece hem yazılımcı, hem domain uzmanı hem de yeni gelen biri sistemi rahatlıkla anlayabilir.
-
bash
public class Tbl_MainData
{
public string user_info;
public string prod_type;
public int stt;
}
Bu tarz isimlendirmeler, kodun okunabilirliğini ve sürdürülebilirliğini tamamen ortadan kaldırır. İş birimi bu kodu asla okuyamaz, yazılımcı bile birkaç hafta sonra neyi ne için yazdığını unutabilir.
- Artık hem domain expert’in kim olduğunu hem de ortak bir dil geliştirmenin neden bu kadar önemli olduğunu öğrendik. Şimdi sırada bu bilgilerin yazılım dünyasında nasıl somutlaştığını anlamak var.
DDD yaklaşımında, tüm iş kurallarının ve süreçlerin odak noktası olan kavram Domain’dir. Yani yazılımın ne yaptığı, nasıl çalıştığı ve hangi problemi çözdüğü sorularının cevabı tam olarak burada saklıdır.
O halde gelin, yazılım geliştirmenin kalbi olan bu “domain” kavramını daha yakından inceleyelim.
-
🧠 Domain Nedir?
Domain kelime anlamı olarak “alan” demektir. Yazılım geliştirme bağlamında ise domain, uygulamanın çözmeye çalıştığı gerçek dünyadaki iş problemlerinin tamamını ifade eder.
Örneğin:
- Bir e-ticaret uygulaması için domain, ürün yönetimi, sipariş işlemleri, müşteri hesapları gibi iş kurallarının tamamıdır.
- Bir muhasebe uygulaması için domain, fatura, bütçe, vergi hesaplamaları gibi iş konularıdır.
-
Domain Ne İşe Yarar?
- Teknik detaylardan (veritabanı, API vs.) soyutlanarak iş mantığına odaklanmanı sağlar.
- Kodun hem iş birimiyle hem de teknik ekiplerle anlaşılır olmasına yardımcı olur.
- Gerçek iş kurallarının yazılımda doğru ve merkezi bir yerde temsil edilmesini sağlar.
- Bu konuyu anlamaya çalışırken, daha önce birçok kez EF Core kullanarak uygulama geliştirdiğimden, özellikle Entity kavramı üzerinden düşünmek bana oldukça yardımcı oldu. Çünkü birçok geliştirici gibi ben de projelerime Code-First yaklaşımıyla başlarken, ilk oluşturduğum katman genellikle “Entity” katmanı olurdu.
- Bu katman, veritabanındaki tabloları temsil eden sınıfları içerir ve CRUD işlemleri de bu yapılar üzerinden gerçekleştirilir. EF Core ile çalışırken bu yaklaşım oldukça pratiktir;
DbContext
, DbSet<T>
yapılarıyla doğrudan veriye erişebiliriz. Ancak iş karmaşıklaştığında ve uygulama büyüdüğünde, sadece Entity sınıflarına bağlı kalmak bazı sınırlamalara yol açar.
- İşte burada Domain kavramı devreye giriyor.
Domain kavramı kendi içerisinde parçalara ayrılıyor Entity + Value Object + Aggregate gibi gibi şimdilik bunu bir bütün olarak düşünüp çok basit örnekler üzerinden konuyu anlatmak istiyorum.
Hemen başlayalım :-)
-
EF Core Entity sınıfları ile DDD’de geçen Domain Entity’leri ya da Domain kavramı arasındaki fark nedir?
-
📌 1. Odağı Farklıdır:
EF Core Entity sınıfları genellikle verinin nasıl saklandığı ile ilgilidir. Ama Domain Entity sınıfları, verinin nasıl davrandığı ile ilgilidir.
-
EF Core Tarzı:
bash
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
Bu sınıfta sadece veriler var. Bu sınıf, bir veritabanı tablosunu temsil eder. Ama bu sınıfa bir iş kuralı (örneğin fiyat güncelleme) eklenmez.
-
🧠 Domain Model Tarzı:
bash
public class Product
{
public int Id { get; private set; }
public string Name { get; private set; }
public decimal Price { get; private set; }
public Product(int id, string name, decimal price)
{
if (price < 0) throw new ArgumentException("Fiyat negatif olamaz.");
Id = id;
Name = name;
Price = price;
}
public void UpdatePrice(decimal newPrice)
{
if (newPrice < 0) throw new ArgumentException("Yeni fiyat negatif olamaz.");
Price = newPrice;
}
}
Burada artık ürün sadece bir veri değil, kendi davranışına da sahip bir varlık (entity) haline geldi. Kurallar sınıfın içinde, dışarı sızmıyor.
-
2. İçerik Farklıdır:
-
EF Core Yaklaşımı:
bash
public class Order
{
public int Id { get; set; }
public decimal TotalAmount { get; set; }
public bool IsPaid { get; set; }
}
- Burada
IsPaid
doğrudan dışarıdan set edilebilir.
- Herhangi bir iş mantığı yok.
public set
vardır, doğrudan erişilebilir.EF Core tarafından veritabanına veri okuma/yazma için kullanılır. İçerisinde hiçbir iş kuralı yoktur. Sadece veri taşıma (DTO gibi düşünebilirsin).
- Her yerden
Price
doğrudan değiştirilebilir.
- Domain mantığını koruyamazsın. Yarın "fiyat 0'dan küçük olmasın" dediğinde sistemin her yeri kontrol etmen gerekir.
-
Domain Yaklaşımı:
bash
public class Order
{
public int Id { get; private set; }
public decimal TotalAmount { get; private set; }
public bool IsPaid { get; private set; }
public Order(int id, decimal totalAmount)
{
if (totalAmount <= 0)
throw new ArgumentException("Tutar sıfırdan büyük olmalı.");
Id = id;
TotalAmount = totalAmount;
IsPaid = false;
}
public void MakePayment()
{
if (IsPaid)
throw new InvalidOperationException("Bu sipariş zaten ödenmiş.");
IsPaid = true;
}
}
- Burada
IsPaid
dışarıdan doğrudan değiştirilemez. İş kuralları sınıfın içinde uygulanır.
- set metotları
private
ya da hiç yoktur. Dışarıdan erişime kapalıdır.
- Değişiklikler methodlarla olur (
MakePayment
).
- Bu sınıf direkt olarak veritabanına bağlı değil, amacı domain davranışı.
- Yarın "fiyat 10 Liradan az olamaz" dediklerinde sadece domain üzerinden değişiklik yapman yeterli olur.
-
3. Anlam Farklıdır:
EF Core Entity’leri veritabanı nesnelerini temsil ederken, Domain Entity’leri gerçek hayattaki nesneleri temsil eder.
-
Örnek:
bash
public class Order
{
public int Id { get; set; }
public decimal TotalAmount { get; set; }
public bool IsPaid { get; set; }
}
EF Core’daki Order
sınıfı sadece bir tablo gibidir.
-
bash
{
public int Id { get; private set; }
public decimal TotalAmount { get; private set; }
public bool IsPaid { get; private set; }
public Order(int id, decimal totalAmount)
{
if (totalAmount <= 0)
throw new ArgumentException("Tutar sıfırdan büyük olmalı.");
Id = id;
TotalAmount = totalAmount;
IsPaid = false;
}
public void MakePayment()
{
if (IsPaid)
throw new InvalidOperationException("Bu sipariş zaten ödenmiş.");
IsPaid = true;
}
}
- Ama Domain’deki
Order
, siparişin ne zaman oluşturulduğu, ödenip ödenmediği, iptal edilip edilmediği, indirime uğrayıp uğramadığı gibi tüm işsel durumları kapsar.
-
4. Modelin Amacı Farklıdır:
- EF Core Entity → Veriyi saklamak için oluşturulur. (Persistence Model)
- Domain Entity → İşi anlamak ve çözmek için oluşturulur. (Business Model / Domain Model)
-
Neden Domain Modeli?
- Domain (iş) değişiklikleri hızlı olur, ama veri yapısı daha sabittir.
- Domain modelin, database yapısına bağlı olursa esnekliğini kaybedersin.
- Test yazarken Domain sınıflarını test etmek kolay olur.
- Veritabanını değiştirdiğinde (örneğin Mongo'ya geçince) sadece altyapıyı değiştirirsin, Domain aynı kalır.
- Yukarıda gördüğümüz gibi, Domain Model ile EF Core Entity’leri arasındaki en büyük fark, iş kurallarının ve davranışların Domain katmanında toplanmasıdır. Bu sayede gerçek dünyadaki karmaşık iş süreçlerini ve mantıkları kod içinde net ve sürdürülebilir şekilde ifade edebiliriz.
- Şimdi Domain karamının genel olarak ne demek olduğunu anladığımızı düşünüyorum.
Artık EFCore Entity kavramını tamamen kafamızdan çıkararak yolumuza devam edelim, yukarıda bahsettiğim gibi Domain kavramı kendi içinde aytılan farklı farklı görevler ve anlamlar üstlenen yapıtaşlarının tümü olarak inceledik. Şimdi artık kavram kavram basit bir şekilde DDD ile ilgili kavramlardan ilerleyelim.
Öğrenmemiz gereken kavramlar sırasıyla.
- --> Entities
--> Value Objects
--> Aggregates
--> Repositories
--> Domain Events
--> Factories
-
🧱 Entity Nedir?
DDD’de Entity, kimliği (identity) olan, yaşam döngüsü boyunca kimliğiyle takip edilen nesnedir. Yani bir varlığı temsil eder ve bu varlığın kendine has bir kimliği vardır. Kimlik, o varlığın diğer varlıklardan ayrılmasını sağlar.
-
Özellikleri:
- Kimlik (Identity): Her Entity’nin benzersiz bir kimliği vardır.
- Davranış: Entity sadece veri değil, aynı zamanda iş kurallarını kapsar.
- Yaşam Döngüsü: Entity, oluşturulma, değiştirilme, silinme gibi süreçlere sahiptir ve bu süreçler boyunca kimliği sabittir.
-
Mutabilite: Entity’nin durumu değişebilir ancak kimliği değişmez.
-
Örnek Domain Entity:
bash
public class Customer
{
public Guid Id { get; private set; }
public string Name { get; private set; }
public string Email { get; private set; }
public bool IsActive { get; private set; }
public Customer(Guid id, string name, string email)
{
Id = id;
Name = name;
Email = email;
IsActive = true;
}
public void ChangeEmail(string newEmail)
{
// Basit bir validasyon örneği
if (string.IsNullOrWhiteSpace(newEmail) || !newEmail.Contains("@"))
throw new ArgumentException("Geçerli bir email adresi giriniz.");
Email = newEmail;
}
public void Deactivate()
{
IsActive = false;
}
}
Bu örnekte Customer
entity’si sadece verileri değil, aynı zamanda müşteriyle ilgili davranışları da kapsıyor.
- Burada son kez bir hatırlatma geçmemde fayda var diye düşüyorum ,
- EF Core tarafında
Id
genellikle veritabanındaki benzersiz kimliği temsil eder. Yani: Veri tabanına kayıt eklenir, EF Core o kaydın Id
alanını otomatik üretir (örneğin bir int veya GUID), Biz bu kimliği, veriyi sorgularken kullanırız. Bu yaklaşım tamamen persist (kalıcı) veriye odaklıdır.
DDD tarafında ise Entity'nin kimliği (ID):
-
Bellek (memory) içinde yaşarken bile o nesneyi tanımlamak için kullanılır. Henüz veritabanıyla hiçbir bağlantı kurmamış olsa bile, bir Order
nesnesi Id
değerine sahiptir ve bu sayede uygulama içinde tanımlıdır. Yani burada kimlik, sadece veri saklamak için değil, domain mantığında varlıkları ayırt etmek içindir.
-
🔍 Özetle şöyle diyebiliriz:
✅ EF Core Entity: Id
, veritabanında o satırı benzersiz yapan şeydir. (Persistence odaklı)
✅ DDD Entity: Id
, sistem içindeki varlıkları birbirinden ayıran, işsel kimliktir. Veritabanına bağımlı değildir. (Domain odaklı)
🧠 Hatta bazı DDD uygulamalarında, kimlik veritabanı tarafından değil, uygulama tarafından (örneğin Guid.NewGuid()
ile) belirlenir. Çünkü kimlik domain’e aittir, veritabanına değil.
-
Örnek verelim
-
🎯 EF Core Entity Yaklaşımı (Persistence Odaklı)
bash
public class Order
{
public int Id { get; set; } // Veritabanı tarafından atanır (Identity)
public DateTime CreatedAt { get; set; }
public decimal TotalAmount { get; set; }
}
Id
genellikle veritabanı tarafından üretilir (IDENTITY
veya SEQUENCE
).
- Veritabanı odaklı çalışılır.
- Order henüz veritabanına eklenmediyse
Id
null/0 olabilir.
- Kimlik, sistem için değil, veritabanı için önemlidir.
-
🧠 DDD Entity Yaklaşımı (Domain Odaklı)
bash
csharp
KopyalaDüzenle
public class Order
{
public Guid Id { get; private set; } // Uygulama tarafından atanır
public DateTime CreatedAt { get; private set; }
public decimal TotalAmount { get; private set; }
public Order(decimal totalAmount)
{
Id = Guid.NewGuid(); // Kimlik veritabanı değil, uygulama tarafından atanır
CreatedAt = DateTime.UtcNow;
TotalAmount = totalAmount;
}
public void UpdateTotal(decimal newTotal)
{
if (newTotal < 0)
throw new InvalidOperationException("Tutar negatif olamaz.");
TotalAmount = newTotal;
}
}
Id
, uygulama içinde oluşturulur ve domain kimliği olarak kullanılır.
- Veritabanıyla hiçbir ilgisi olmasa bile, bu
Order
sistemde tanınabilir.
-
Kimlik, iş mantığına göre belirlenir ve tüm sistem boyunca aynı kalır.
-
📌 Ne Kazanırız?
- DDD yaklaşımı sayesinde:
- Order nesnesi, henüz veritabanına kaydedilmeden bile anlamlı hale gelir.
- Test edilebilirlik artar (in-memory nesnelerle çalışmak mümkün).
- Domain kuralları veriden ayrılır.
- Şimdi Entity kavramını anladığımızı düşünüyorum.
Bir sonraki konumuz olan Value Objects kavramına geçmeden önce sizler ile bir konuda beraber fikir yürüterek özellikle DDD’de
Value Object
kavramını anlamanın en kritik noktalarından biri, eşitlik (equality) mantığının beraber farkına varalım istiyorum.
Şimdi örnek olarak bir tane Category classımız olsun.
-
bash
namespace DomainDrivenDesign.Domain.Categories
{
public sealed class Category: Entity
{
public Category(Guid CreatedTimeAssignedId) : base(CreatedTimeAssignedId)
{
}
public string Name { get; set; }
public ICollection<Product> Products { get; set; }
}
}
-
bash
namespace DomainDrivenDesign.Domain.Abstractions
{
//Sadece Kalıtım alınsın istiyoruz kendi başına bir oluşum olmasın
//Bu yüzden abstract olarak tanımlıyoruz
public abstract class Entity
{
public Guid Id { get; init; } //Inıt property olarak tanımladık ki sadece constructor'da atama yapılabilsin ve değiştirilemesin
protected Entity(Guid CreatedTimeAssignedId)
{
this.Id = CreatedTimeAssignedId;
}
}
}
- Gördüğünüz
Category
sınıfı, senin daha önce tanımladığın Entity
sınıfından kalıtım (inheritance) alıyor ve bu sayede bir DDD Entity'si oluyor:
- Peki biz projemizde bir adet
Guid Id
değeri oluştursak daha sonra bu oluşturduğumuz id değeri ile 2 tane class tanımlasak şimdiye kadar konuştuğumuz DDD mantığına göre iki Entity'nin aynı mıdır ?
Şöyle inceleyelim isterseniz.
-
bash
public class ExampleClass : Entity
{
public ExampleClass(Guid CreatedTimeAssignedId) : base(CreatedTimeAssignedId)
{
}
}
public class TestRunner
{
public void main()
{
Guid oneTimeCreatedGuid = Guid.NewGuid();
ExampleClass example1 = new(oneTimeCreatedGuid);
ExampleClass example2 = new(oneTimeCreatedGuid);
Console.WriteLine(example1.Id == example2.Id);
Console.WriteLine(example1.Equals(example2));
}
}
- Sizce buradaki çıktılar sırasıyla ne olur ?
A-) True True
B-) True False
Kendine şöyle bir soru sormanı istiyorum.
Burada iki farklı nesne oluşturuyorsun, ancak aynı ID’yi taşıyorlar. Bunlar gerçekten aynı varlık mıdır? DDD açısından evet, çünkü kimlik (ID) aynıdır.
Ama C# dilinde
example1 == example2
sonucu false
çıkar çünkü referans karşılaştırması yapılır.
Peki ben şimdi neden böyle bir soru sordum ?
Başından beri Entity kavramını anlatırken ne diyorduk?
Benzersiz bir kimlik değerine sahip olan her bir yapı, sistem içerisinde kimliğiyle tanımlanır ve takip edilir — bu nedenle referansları farklı olsa bile, kimlikleri aynıysa aynı Entity olarak kabul edilirler.
- İşte burada Value Object kısmına geçmeden önce bilmemiz gereken bir kavram var. Equality Check
-
🎯 Eşitlik Kontrolü (Equality Check) Nedir ve Neden Önemlidir?
- Bu terim, genellikle Entity'nin eşitlik karşılaştırması (equality check) için bir kontrol sistemini ifade eder. Yani:
İki Entity'nin aynı mı olduğunu nasıl anlarız?
Aynı ID’ye sahiplerse aynı Entity midir?
Yoksa başka şeylere de bakmalı mıyız?
- Entity’ler, kimlikleri (ID) ile tanımlanır. Yani bir Entity’nin eşitliği, içindeki tüm alanların aynı olmasıyla değil, kimliklerinin aynı olmasıyla belirlenir.
Bunun anlamı:
- İki farklı nesne örneği olabilir (bellekte farklı adreslerde duruyorlar) ama aynı
Id
değerine sahiplerse, bu iki Entity “aynıdır”.
-
Tersine, tüm alanları aynı olsa bile Id
farklıysa, bu iki Entity farklıdır.
-
🎯 Neden standart referans karşılaştırması yeterli değil?
- C#’ta iki nesne
==
ile karşılaştırıldığında, varsayılan olarak referans eşitliği kontrol edilir. Yani bellekte aynı nesne olup olmadığına bakılır.
- Ancak DDD’de, farklı bellek adreslerinde olsalar bile, aynı kimliğe sahip Entity’lerin eşit kabul edilmesi gerekir.
- Bu yüzden Entity sınıflarında eşitlik operatörleri ve
Equals()
metodu override edilerek, kimlik bazlı karşılaştırma yapılmalıdır.
bash
public abstract class Entity : IEquatable<Entity>
{
public Guid Id { get; init; }
protected Entity(Guid CreatedTimeAssignedId)
{
this.Id = CreatedTimeAssignedId;
}
/* Equals metodunu override ettik çünkü Entity sınıfından türetilen sınıfların
karşılaştırılmasını istiyoruz */
public override bool Equals(object? obj)
{
if (obj is null)
{
return false;
}
if (obj is not Entity entity)
{
return false;
}
if (obj.GetType() == GetType())
{
return false;
}
return entity.Id == Id;
}
/*GetHashCode metodunu override ettik çünkü
Entity sınıfından türetilen Array veya List gibi koleksiyonlarda kullanılacaksa,
bu metodun da doğru çalışması gerekiyor. */
public override int GetHashCode()
{
return Id.GetHashCode();
}
// IEquatable<Entity> arayüzünü implement ettik çünkü Entity sınıfından türetilen sınıfların karşılaştırılmasını istiyoruz
public bool Equals(Entity? other)
{
if (other is null)
{
return false;
}
if (other is not Entity entity)
{
return false;
}
if (other.GetType() != GetType())
{
return false;
}
return entity.Id == Id;
}
/*
Burada ufak bir dipnot belirtmek istiyorum.
Burada kullandığımız IEquatable<Entity> arayüzü ile kendi oluşturduğumuz
equals methodundan daha biraz daha advance bir method.
Fark Şu : - Kendi override ettiğimiz method Unboxing yapıyor yani basitçe objeyi tipe çeviriyor,
Tipe göre kontrol etme işlemi yapıyor biraz daha kötü performans sağlıyor.
- İmplement ettiğimiz method ise Unboxing yapmıyor.
*/
}
- Entity’ler üzerinden ilerlerken, kimliği olan ve yaşam döngüsü boyunca izlenen varlıkları tanımladık. Ancak, yazılım sistemimizde her şey bir kimlik taşımaz. Bazı kavramlar vardır ki, onları temsil eden veriler değiştiğinde, artık farklı bir şeyi temsil ederler — tıpkı bir adres, bir para birimi ya da bir koordinat gibi.
Bu tür kavramları modellemek için DDD bize başka bir yapı sunar: Value Object.
Şimdi gelin, Value Object nedir, Entity’den farkı nedir ve neden bu kadar önemli, birlikte bir sonraki makalemde inceleyelim.