Share via


DDD odaklı mikro hizmet tasarlama

İpucu

Bu içerik, .NET Docs'ta veya çevrimdışı olarak okunabilen ücretsiz indirilebilir bir PDF olarak sağlanan Kapsayıcılı .NET Uygulamaları için .NET Mikro Hizmet Mimarisi e-Kitabı'ndan bir alıntıdır.

.NET Microservices Architecture for Containerized .NET Applications eBook cover thumbnail.

Etki alanı odaklı tasarım (DDD), kullanım örneklerinizle ilgili olarak işletmenin gerçekliğine göre modellemeyi destekler. Uygulama oluşturma bağlamında DDD, sorunlardan etki alanı olarak bahseder. Bağımsız sorun alanlarını Sınırlanmış Bağlamlar (her Sınırlanmış Bağlam bir mikro hizmetle bağıntılı) olarak açıklar ve bu sorunlar hakkında konuşmak için ortak bir dili vurgular. Ayrıca, iç uygulamayı desteklemek için zengin modellere sahip etki alanı varlıkları (anemik-etki alanı modeli yok), değer nesneleri, toplamalar ve toplu kök (veya kök varlık) kuralları gibi birçok teknik kavram ve desen önerir. Bu bölümde bu iç desenlerin tasarımı ve uygulaması tanıtılır.

Bazen bu DDD teknik kuralları ve desenleri, DDD yaklaşımlarını uygulamak için dik bir öğrenme eğrisi olan engeller olarak algılanıyor. Ancak önemli olan, desenlerin kendisi değil, kodu iş sorunlarıyla uyumlu olacak şekilde ve aynı iş terimlerini (yaygın dil) kullanarak düzenlemektir. Ayrıca, DDD yaklaşımları yalnızca önemli iş kuralları olan karmaşık mikro hizmetler uyguluyorsanız uygulanmalıdır. CRUD hizmeti gibi daha basit sorumluluklar daha basit yaklaşımlarla yönetilebilir.

Mikro hizmet tasarlarken ve tanımlarken temel görev sınırların çizileceği yerdir. DDD desenleri, etki alanındaki karmaşıklığı anlamanıza yardımcı olur. Her Sınırlanmış Bağlamın etki alanı modeli için, etki alanınızı modelleyen varlıkları, değer nesnelerini ve toplamları tanımlar ve tanımlarsınız. Bağlamınızı tanımlayan bir sınır içinde yer alan bir etki alanı modeli derleyip daraltabilirsiniz. Bu da mikro hizmet biçiminde açık bir ifadedir. Bu sınırlar içindeki bileşenler sizin mikro hizmetleriniz olur, ancak bazı durumlarda bc veya iş mikro hizmetleri çeşitli fiziksel hizmetlerden oluşabilir. DDD sınırlarla ilgilidir ve mikro hizmetler de öyledir.

Mikro hizmet bağlam sınırlarını nispeten küçük tutun

Sınırlanmış Bağlamlar arasında sınırların nereye yerleştirileceği belirlenerek iki rakip hedef dengelenmiş olur. İlk olarak, başlangıçta mümkün olan en küçük mikro hizmetleri oluşturmak istiyorsunuz, ancak ana sürücü bu olmamalıdır; uyum gerektiren şeylerin çevresinde bir sınır oluşturmanız gerekir. İkincisi, mikro hizmetler arasındaki gevendekli iletişimlerden kaçınmak istiyorsunuz. Bu hedefler birbiriyle çelişebilir. İletişim sınırlarının yeni bir Sınırlanmış Bağlamı ayırmaya yönelik her ek girişimle hızla büyüdüğünü görene kadar sistemi olabildiğince küçük mikro hizmetlere ayırarak bunları dengelemeniz gerekir. Tek bir sınırlanmış bağlam içinde birlikte çalışma anahtarıdır.

Sınıflar uygulanırken Uygunsuz Yakınlık kod kokusuna benzer. İki mikro hizmetin birbiriyle çok fazla işbirliği yapması gerekiyorsa, büyük olasılıkla aynı mikro hizmet olmalıdır.

Bu açıdan bakmanın bir diğer yolu da özerkliktir. Bir mikro hizmetin doğrudan bir isteğe hizmet vermek için başka bir hizmete güvenmesi gerekiyorsa, gerçekten otonom değildir.

DDD mikro hizmetlerindeki katmanlar

önemli iş ve teknik karmaşıklığı olan çoğu kurumsal uygulama birden çok katmanla tanımlanır. Katmanlar mantıksal bir yapıttır ve hizmetin dağıtımıyla ilgili değildir. Bunlar, geliştiricilerin koddaki karmaşıklığı yönetmesine yardımcı olmak için vardır. Farklı katmanların (etki alanı modeli katmanıyla sunu katmanı gibi) farklı türleri olabilir ve bu türler arasında çeviriler zorunlu kılınabilir.

Örneğin, veritabanından bir varlık yüklenebilir. Daha sonra bu bilgilerin bir kısmı veya diğer varlıklardaki ek veriler de dahil olmak üzere bilgilerin bir toplamı rest Web API'si aracılığıyla istemci kullanıcı arabirimine gönderilebilir. Buradaki nokta, etki alanı varlığının etki alanı modeli katmanında yer alması ve sunu katmanı gibi ait olmadığı diğer alanlara yayılmaması gerektiğidir.

Ayrıca, toplama kökleri (kök varlıklar) tarafından denetlenen her zaman geçerli varlıklara (etki alanı modeli katmanında doğrulama tasarlama bölümüne bakın) sahip olmanız gerekir. Bu nedenle, kullanıcı arabirimi düzeyinde bazı veriler yine de doğrulanmayabileceği için varlıklar istemci görünümlerine bağlı olmamalıdır. Bu nedenle ViewModel bunun içindir. ViewModel, yalnızca sunu katmanı gereksinimlerine yönelik bir veri modelidir. Etki alanı varlıkları doğrudan ViewModel'e ait değildir. Bunun yerine, ViewModel'ler ile etki alanı varlıkları arasında çeviri yapmanız gerekir ve bunun tersi de geçerlidir.

Karmaşıklığı düzeltirken, bu varlık grubuyla (toplama) ilgili tüm sabit ve kuralların tek bir giriş noktası veya geçit (toplama kökü) üzerinden gerçekleştirilmesini sağlayan bir etki alanı modelinin toplama kökleri tarafından denetlenmesini sağlamak önemlidir.

Şekil 7-5'te katmanlı bir tasarımın eShopOnContainers uygulamasında nasıl uygulandığı gösterilmektedir.

Diagram showing the layers in a domain-driven design microservice.

Şekil 7-5. eShopOnContainers'da mikro hizmeti sıralamada DDD katmanları

Sıralama gibi bir DDD mikro hizmetindeki üç katman. Her katman bir VS projesidir: Uygulama katmanı Ordering.API, Etki alanı katmanı Ordering.Domain ve Altyapı katmanı da Ordering.Infrastructure katmanıdır. Sistemi, her katmanın yalnızca belirli diğer katmanlarla iletişim kuracak şekilde tasarlamak istiyorsunuz. Katmanlar farklı sınıf kitaplıkları olarak uygulandığında bu yaklaşımın uygulanması daha kolay olabilir çünkü kitaplıklar arasında hangi bağımlılıkların ayarlandığını net bir şekilde belirleyebilirsiniz. Örneğin, etki alanı modeli katmanı başka bir katmana bağımlılık almamalıdır (etki alanı modeli sınıfları Düz Eski Sınıf Nesneleri veya POCO, sınıflar olmalıdır). Şekil 7-6'da gösterildiği gibi, Ordering.Domain katman kitaplığının yalnızca .NET kitaplıklarına veya NuGet paketlerine bağımlılıkları vardır, ancak veri kitaplığı veya kalıcılık kitaplığı gibi diğer özel kitaplıklarda bağımlılıkları olmaz.

Screenshot of Ordering.Domain dependencies.

Şekil 7-6. Kitaplık olarak uygulanan katmanlar, katmanlar arasındaki bağımlılıkların daha iyi denetlenebilmesini sağlar

Etki alanı modeli katmanı

Eric Evans'ın domain driven design adlı mükemmel kitabı etki alanı modeli katmanı ve uygulama katmanı hakkında aşağıdakileri söylüyor.

Etki Alanı Modeli Katmanı: İşletmenin kavramlarını, iş durumu hakkındaki bilgileri ve iş kurallarını temsil etme sorumluluğundadır. İş durumunu yansıtan durum, depolamanın teknik ayrıntıları altyapıya devredilmiş olsa bile burada denetlenip kullanılır. Bu katman, iş yazılımının kalbidir.

Etki alanı modeli katmanı, işletmenin ifade edildiği yerdir. .NET'te bir mikro hizmet etki alanı modeli katmanı uyguladığınızda, bu katman veri artı davranışı yakalayan etki alanı varlıklarıyla (mantıksal yöntemler) bir sınıf kitaplığı olarak kodlanır.

Kalıcılık Yoksayma ve Altyapı Cehalet ilkelerine göre, bu katman veri kalıcılığı ayrıntılarını tamamen yok saymalıdır. Bu kalıcılık görevleri altyapı katmanı tarafından gerçekleştirilmelidir. Bu nedenle, bu katman altyapıya doğrudan bağımlılıklar almamalıdır; bu da önemli bir kuralın etki alanı modeli varlık sınıflarınızın POCO olması gerektiği anlamına gelir.

Etki alanı varlıklarının Entity Framework veya NHibernate gibi herhangi bir veri erişim altyapısı çerçevesinde doğrudan bağımlılığı olmamalıdır (temel sınıftan türetme gibi). İdeal olarak, etki alanı varlıklarınız herhangi bir altyapı çerçevesinde tanımlanan herhangi bir türden türetmemeli veya uygulamamalıdır.

Entity Framework Core gibi modern ORM çerçevelerinin çoğu bu yaklaşıma izin verir, böylece etki alanı modeli sınıflarınızın altyapıyla birleştirilmiş olmamasını sağlar. Ancak Azure Service Fabric'te Aktörler ve Güvenilir Koleksiyonlar gibi belirli NoSQL veritabanları ve çerçeveleri kullanılırken POCO varlıklarına sahip olmak her zaman mümkün değildir.

Etki alanı modeliniz için Kalıcılık Yoksayma ilkesini izlemeniz önemli olsa bile kalıcılık sorunlarını yoksaymamalısınız. Fiziksel veri modelini ve varlık nesne modelinizle nasıl eşlendiğinden anlamak hala önemlidir. Aksi takdirde imkansız tasarımlar oluşturabilirsiniz.

Ayrıca bu özellik, ilişkisel veritabanı için tasarlanmış bir modeli alıp doğrudan NoSQL veya belge odaklı bir veritabanına taşıyabileceğiniz anlamına gelmez. Bazı varlık modellerinde model sığabilir ancak genellikle sığmaz. Varlık modelinizin hem depolama teknolojisine hem de ORM teknolojisine bağlı kalması gereken kısıtlamalar vardır.

Uygulama katmanı

Uygulama katmanına geçmek için Eric Evans'ın Domain Driven Design adlı kitabını tekrar alıntılayabiliriz:

Uygulama Katmanı: Yazılımın yapması gereken işleri tanımlar ve açıklayıcı etki alanı nesnelerini sorunları gidermeye yönlendirir. Bu katmanın sorumlu olduğu görevler işletme için anlamlıdır veya diğer sistemlerin uygulama katmanlarıyla etkileşim için gereklidir. Bu katman ince tutulur. İş kuralları veya bilgi içermez, ancak yalnızca görevleri koordine eder ve temsilciler sonraki katmandaki etki alanı nesnelerinin işbirliğine çalışır. İş durumunu yansıtan bir durumu yoktur, ancak kullanıcı veya program için bir görevin ilerleme durumunu yansıtan bir duruma sahip olabilir.

.NET'teki bir mikro hizmetin uygulama katmanı genellikle ASP.NET Core Web API projesi olarak kodlanır. Proje, mikro hizmetin etkileşimini, uzaktan ağ erişimini ve kullanıcı arabiriminden veya istemci uygulamalarından kullanılan dış Web API'lerini uygular. Bir CQRS yaklaşımı, mikro hizmet tarafından kabul edilen komutlar ve hatta mikro hizmetler arasındaki olay temelli iletişim (tümleştirme olayları) gibi sorgular içerir. Uygulama katmanını temsil eden ASP.NET Core Web API'sinin iş kuralları veya etki alanı bilgisi (özellikle işlemler veya güncelleştirmeler için etki alanı kuralları) içermemesi gerekir; bunlar etki alanı modeli sınıf kitaplığına ait olmalıdır. Uygulama katmanının yalnızca görevleri koordine etmesi ve herhangi bir etki alanı durumunu (etki alanı modeli) tutmaması veya tanımlamaması gerekir. İş kurallarının yürütülmesini etki alanı modeli sınıflarına (toplam kökler ve etki alanı varlıkları) devrederek bu etki alanı varlıklarındaki verileri güncelleştirir.

Temel olarak, uygulama mantığı, belirli bir ön uca bağlı olan tüm kullanım örneklerini uyguladığınız yerdir. Örneğin, bir Web API hizmetiyle ilgili uygulama.

Amaç, etki alanı modeli katmanındaki etki alanı mantığının, sabitlerinin, veri modelinin ve ilgili iş kurallarının sunu ve uygulama katmanlarından tamamen bağımsız olması gerektiğidir. En önemlisi, etki alanı modeli katmanı doğrudan herhangi bir altyapı çerçevesine bağımlı olmamalıdır.

Altyapı katmanı

Altyapı katmanı, başlangıçta etki alanı varlıklarında (bellekte) tutulan verilerin veritabanlarında veya başka bir kalıcı depoda nasıl kalıcı hale geldiğini gösterir. İlişkisel veritabanında verileri kalıcı hale getirmek için DBContext kullanan Depo desen sınıflarını uygulamak için Entity Framework Core kodunun kullanılması buna örnek olarak verilmiştir.

Daha önce bahsedilen Kalıcılık Cehalet ve Altyapı Cehalet ilkelerine uygun olarak, altyapı katmanının etki alanı modeli katmanını "kirletmemesi" gerekir. Etki alanı modeli varlık sınıflarını, çerçevelere sıkı bağımlılıklar almayarak verileri (EF veya başka bir çerçeve) kalıcı hale getirmek için kullandığınız altyapıdan bağımsız tutmanız gerekir. Etki alanı modeli katmanı sınıf kitaplığınızda yalnızca etki alanı kodunuz olmalı, yalnızca yazılımınızın kalbini uygulayan ve altyapı teknolojilerinden tamamen ayrılmış POCO varlık sınıfları olmalıdır.

Bu nedenle, katmanlarınız veya sınıf kitaplıklarınız ve projeleriniz, Şekil 7-7'de gösterildiği gibi etki alanı modeli katmanınıza (kitaplık) bağlı olmalıdır.

Diagram showing dependencies that exist between DDD service layers.

Şekil 7-7. DDD'de katmanlar arasındaki bağımlılıklar

DDD Hizmeti'ndeki bağımlılıklar, Uygulama katmanı Etki Alanına ve Altyapı'ya, Altyapı ise Etki Alanına bağlıdır, ancak Etki alanı herhangi bir katmana bağımlı değildir. Bu katman tasarımı her mikro hizmet için bağımsız olmalıdır. Daha önce belirtildiği gibi, DDD desenlerini izleyen en karmaşık mikro hizmetleri uygularken, daha basit veri temelli mikro hizmetleri (tek bir katmanda basit CRUD) daha basit bir şekilde uygulayabilirsiniz.

Ek kaynaklar