Alan odaklı tasarım

**Alan Odaklı Tasarım** (**DDD**), yazılımı iş alanına uygun modellemeye odaklanan başlıca bir yazılım tasarımı yaklaşımıdır. Bu yaklaşım, iş alanındaki uzmanların katkılarına göre bir alan oluşturmayı hedefler. DDD, tek bir birleşik model fikrine karşıdır; bunun yerine büyük bir sistemi, her biri kendi modeline sahip olan sınırlı bağlamlara ayırır.

Domain-driven design'da, yazılım kodunun yapısı ve dili (sınıf isimleri, sınıf metotları, sınıf değişkenleri) iş alanına uygun olmalıdır. Örneğin, yazılım kredi başvurularını işliyorsa, "kredi başvurusu", "müşteriler" gibi sınıflara ve "teklif kabul et" ve "geri çek" gibi metodlara sahip olabilir.

Alan Odaklı Tasarım, şu hedeflere dayanır:

Projenin birincil odağını çekirdek alan ve alan mantığı katmanına yerleştirmek;
karmaşık tasarımları iş alanının bir modeline dayandırmak;
teknik ve alan uzmanları arasında yaratıcı bir işbirliği başlatarak belirli alan problemlerini ele alan kavramsal bir modeli iteratif olarak geliştirmek.
Domain-driven design eleştirmenleri, geliştiricilerin modeli saf ve yararlı bir yapıda tutmak için genellikle çok fazla izolasyon ve kapsülleme uygulamaları gerektiğini savunur. Domain-driven design, sürdürülebilirlik gibi faydalar sağlarken, Microsoft bu modeli yalnızca modelin iş alanının ortak anlayışını net bir şekilde sağladığı karmaşık alanlar için önerir.

Bu terim, Eric Evans tarafından 2003 yılında yayımlanan aynı isimli kitabında ortaya atılmıştır.

## Genel bakış
Alan Odaklı Tasarım, çeşitli üst düzey kavramları ve uygulamaları tanımlar.

En önemli kavramlardan biri, yazılımın *domain*idir; yani kullanıcının bir programı uyguladığı konu alanı. Yazılım geliştiricileri, bu domain'in seçilmiş yönlerini tanımlayan ve o domain ile ilgili sorunları çözmek için kullanılabilecek bir *domain modeli* oluşturur.

Alan Odaklı Tasarımın bu yönleri, domain uzmanları, kullanıcılar ve geliştiriciler arasında paylaşılan *yaygın bir dil* oluşturmayı amaçlar—bu dile *ubiquitous language* denir. Ubiquitous language, domain modelinde ve sistem gereksinimlerini tanımlamak için kullanılır.

Ubiquitous language, DDD'nin *stratejik tasarım* ve *taktiksel tasarım* ile birlikte temel dayanaklarından biridir.

Alan Odaklı Tasarımda, domain katmanı, nesne yönelimli bir çok katmanlı mimarideki ortak katmanlardan biridir.

## Model türleri
Alan Odaklı Tasarım, çeşitli model türlerini tanır. Örneğin, bir *entity*, özellikleri ile değil, kimliği ile tanımlanan bir nesnedir. Örneğin, çoğu havayolu, her uçuşta koltuklara benzersiz bir numara atar: bu, koltuğun kimliğidir. Buna karşılık, bir *[[değer nesnesi]]* ise özellikler içeren ancak kavramsal bir kimliği olmayan bir değişmez nesnedir. Örneğin, insanlar kartvizit değiş tokuş ettiğinde, her benzersiz kartı ayırt etmeye çalışmaktan ziyade sadece kart üzerindeki bilgilere (özelliklerine) önem verirler.

Modeller ayrıca *olaylar* (geçmişte olmuş bir şey) tanımlayabilir. Bir domain olayı, domain uzmanlarının ilgilendiği bir olaydır. Modeller, bir kök entity ile bağlanarak *aggregate* haline gelebilir. Aggregate dışındaki nesneler, köke referans tutabilir ancak aggregate içindeki diğer nesnelere referans tutamaz. Aggregate kökü, aggregate içindeki değişikliklerin tutarlılığını denetler. Örneğin, sürücüler bir arabayı her bir tekerleği ayrı ayrı kontrol etmek zorunda değildir; sadece arabayı sürerler. Bu bağlamda araba, diğer birçok nesnenin (motor, frenler, farlar vb.) bir aggregate'idir.

## Modellerle çalışma
Alan Odaklı Tasarımda, bir nesnenin oluşturulması genellikle o nesnenin kendisinden ayrıdır.

Örneğin, bir *repository*, bir veri deposundan (ör. bir veritabanı) domain nesnelerini almak için metodlara sahip bir nesnedir. Benzer şekilde, bir factory, doğrudan domain nesneleri oluşturmak için metodlara sahip bir nesnedir.

Bir programın işlevselliğinin bir parçası kavramsal olarak hiçbir nesneye ait değilse, genellikle bir servis olarak ifade edilir.

## Diğer fikirlerle ilişki
Bir bounded context, bir mikroservise benzer.

Alan Odaklı Tasarım, doğrudan nesne yönelimli yaklaşımlarla ilişkili olmamasına rağmen, pratikte bu tekniklerin avantajlarını kullanır. Bunlar arasında, komutları/metod çağrılarını alan entity/aggregate kökleri, en başta aggregate kökleri içinde durumun kapsüllenmesi ve daha yüksek mimari seviyelerde bounded context'ler bulunur.

Bu nedenle, Alan Odaklı Tasarım genellikle Plain Old Java Objects ve Plain Old CLR Objects ile ilişkilendirilir; bunlar sırasıyla Java ve .NET Framework'e özgü teknik uygulama detaylarıdır. Bu terimler, domain nesnelerinin daha spesifik bir teknoloji çerçevesi yerine, iş alanının davranışlarıyla tanımlanması gerektiğine yönelik bir görüşü yansıtır.

Benzer şekilde, naked objects deseni, kullanıcı arayüzünün yeterince iyi bir domain modelinin doğrudan bir yansıması olabileceğini savunur. Kullanıcı arayüzünün domain modelinin doğrudan bir yansıması olmasını zorunlu kılmak, daha iyi bir domain modelinin tasarımını teşvik edecektir.

Alan Odaklı Tasarım, yazılım geliştirme için diğer yaklaşımları da etkilemiştir.

Örneğin, Alan'a özgü modelleme, alan'a özgü dillerle gerçekleştirilen Alan Odaklı Tasarım uygulamasıdır. Alan Odaklı Tasarım, özellikle bir alan'a özgü dil kullanımını gerektirmez; ancak, bir alan'a özgü dili tanımlamaya yardımcı olmak ve alan'a özgü multimodellemeyi desteklemek için kullanılabilir.

Ayrıca, aspect-oriented programming (AOP), teknik konuları (güvenlik, işlem yönetimi, günlükleme gibi) bir domain modelinden ayırmayı kolaylaştırarak, domain modelinin sadece iş mantığına odaklanmasını sağlar.

## Model tabanlı mühendislik ve mimari
Alan Odaklı Tasarım, model tabanlı mühendislik ve model tabanlı mimari ile uyumlu olmakla birlikte, iki kavramın amacı farklıdır. Model tabanlı mimari, daha iyi domain modelleri tanımlamaktan ziyade bir modeli farklı teknoloji platformlarına dönüştürmeye odaklanır.

Ancak, model tabanlı mühendislik tarafından sunulan teknikler (domain'leri modellemek, domain uzmanları ve geliştiriciler arasında iletişimi kolaylaştırmak için alan'a özgü diller oluşturmak gibi...) Alan Odaklı Tasarımı pratikte kolaylaştırır ve uygulayıcıların modellerinden daha fazla fayda sağlamalarına yardımcı olur. Model tabanlı mühendisliğin model dönüştürme ve kod oluşturma teknikleri sayesinde, domain modeli, onu yönetecek olan gerçek yazılım sistemini oluşturmak için kullanılabilir.

### Komut ve sorgu sorumluluğu ayrımı
Komut ve Sorgu Sorumluluğu Ayrımı (CQRS), veriyi okumayı (bir 'sorgu') veriye yazmaktan ayıran bir mimari desenidir. Uygulama içinde komutlar ve sorgular arasında net bir ayrım sağlar.

## Kaynakça