- Value Object Id si yoktur.
- immutable(değişemez)dir.
- Property valueları eşit olan iki value object nesnesi eşit kabul edilir.(Phone, Address, Money, İsim)
Value Objectler sadece değerleriyle tanımlanan türlerdir. Değerleri aynıysa iki value object eşit kabul edilir. Value Objectler daha karmaşık yapıları temsil etmek için primitive tipler(int, string, boolean vs.) kullanırken ortaya çıkan sorunları çözmek için kullanılır.
FirstName alanı için databasede nvarchar tipinde bir alan tutmamız gerekiyor. Dolayısıyla da uygulama tarafında string tipinde saklamak durumunda kalıyoruz. Yada PhoneNumber alanı için aynı şekilde string tipini kullanıyoruz. Mesela string sınıfına ait toLower() metodu için konuşursak bu metod phoneNumber için uygun mudur? Tabiki uygun değildir. Onun için PhoneNumberı value object olarak tanımlayabiliriz. Yada aynı şekilde firstName alanınıda value object olarak tanımlayabiliriz. Value objectler içerisinde kendisi ile ilgili bussineslara sahip olabilir.
Yukarıdaki member sınıfını ele aldığımız da member sınıfından nesne üretmek için
Member member1 = new Member(37,"Aytaç","demirci","aytac@gmail.com")
Member member2 = new Member(37,"aytac@gmail.com","Aytaç","Demirci")
Firstname yerine email, email yerine isim yazdığımızda bu bir hata vermez ve çalışır fakat doğru bir işlem yapmış olmayız. Ayrıca firstName için en az 50 karakter olsun. Empty olmasın gibi kısıtlar getirmek isteyebiliriz. İşte bunu sağlayabilmek için value objectleri kullanabiliriz.
namespace Gatherly.Domain.ValueObjects { public sealed class FirstName : ValueObject { private FirstName() { } public const int MaxLength = 50; public string Value { get; } private FirstName(string value) { Value = value; } public override IEnumerable<object> GetAtomicValues() { yield return Value; //Bu value objectin extra propertyleri olursa buraya eklenecek. } public static FirstName Create(string firstName) { if (string.IsNullOrWhiteSpace(firstName)) { throw new ArgumentNullException($"{nameof(firstName)} is empty."); } if (firstName.Length > MaxLength) { throw new InvalidLenghtException($"{nameof(firstName)} is too long."); } return new FirstName(firstName); } } }
Alttaki abstract GetAtomicValues metodu miras alınan sınıflarda override edilip buraya o sınıfın propertyleri yield return peropertyname şeklinde eklenecektir.
public abstract class ValueObject : IEquatable<ValueObject> { public abstract IEnumerable<object> GetAtomicValues(); public override bool Equals(object? obj) { return obj is ValueObject other && ValuesAreEqual(other); } public bool Equals(ValueObject? other) { return other is not null && ValuesAreEqual(other); } private bool ValuesAreEqual(ValueObject other) { return GetAtomicValues().SequenceEqual(other.GetAtomicValues()); } public override int GetHashCode() { return GetAtomicValues() .Aggregate(default(int), HashCode.Combine); } }
Hiç yorum yok:
Yorum Gönder