Uygulamalarımızda reuse edebilecğimiz common patternleri bulmamızı sağlayan DDD tekniklerine genel bir bakış yapacağız.
Apply simplified CQRS and DDD patterns in a microservice
- CQRS, dataları read ve write için ayrı modellere ayıran bir architectural patterndir.
- Ana fikir, bir sistemin operasyonlarını keskin bir şekilde ayrılmış iki kategoriye ayırabilmenizdir:
Queries : Sistemin durumunu (state) değiştirmez, Geriye bir result return eder ve side effect yoktur.(Get Operation)
Commands: Sistemin durumunu değiştirir.(Add,Update,Delete)
CQRS, Query ve Command operasyonları için ayrı birer logical model oluşturulması gerektiğini söyler. Burada query ve commandlar için ayrı birer database olması şart değildir. Fakat modeller farklı olmalıdır.
Command ve Queryler için ayrı birer logical model oluşturmanın en büyük faydası Command işlemleri için uygulanan DDD kısıtlamalarının Queryleri etkilemeyecek olmasıdır.
Queryler, Idempotenttir. Yani kaç kere aynı query çalıştırırsak çalıştıralım sistemin durumu değişmeyecektir ve geriye sadece veri tabanından data return edilecektir.
Öte yandan Commandlar transaction ve data update işlemlerini tetikleyerek sistemin durumu(state) değiştirir. Commandlarla, karmaşıklık ve sürekli değişen bussines rulelarla uğraşırken dikkatli olmanız gerekir. Daha iyi modellenmiş bir sisteme sahip olmak için DDD tekniklerini uygulayacağımız yer burasıdır.
Domain Driven Desing
DDD, problemleri domain olarak nitelendirir. Birbirinden bağımsız her bir problem Bounded Context olarak tanımlanır ve problem üzerine konuşmak için ortak bir dil kullanılır.(Her Bounded Context bir micro servise karşılık gelir.). Uygulama implementasyonunda Entity Domain With Rich Entity, ValueObjects, Aggregates ve AggregateRoot(entity root) gibi kavramlar kullanılır.
DDD yaklaşımları, sadece önemli bussines rulelara sahip complex mikro servisler oluşturmanız gerektiğinde kullanılmalıdır. CRUD servisleri gibi basit uygulamalar için uygulanmamalıdır.
Keep the microservice context boundaries small
Bounded Contextleri belirlerken aşağıdaki durumlar dikkate alınmalıdır.
- İki mikro servisin birbiriyle çok fazla işbirliği yapması gerekiyorsa, muhtemelen aynı mikro servis olmalıdırlar.
- Micro servisler özerk(autonomy) olmalıdır. Bir mikro servisin , bir talebe doğrudan hizmet vermesi için başka bir servise bağlı olması gerekiyorsa, gerçekten özerk(autonomy) değildir.
Layers in DDD microservices
Önemli bussines ve teknik karmaşıklığa sahip çoğu kurumsal uygulama, birden çok katmanla tasarlanır. Farklı katmanlar geliştiricilerin kod karmaşıklığını yönetmesini kolaylaştırır.
AggregateRootlar tarafından kontrol edilen always-valid entitiylere sahip olmanız gerekir. Bu yüzden entityler, client viewlara bağlı olmamalıdır, çünkü UI düzeyinde bazı veriler validate edilmemiş olabilir. ViewModel, yalnızca Presentation Layer gereksinimlerine yönelik bir data modelidir. Domain model entityleri doğrudan ViewModel'e ait değildir. Bunun yerine, ViewModels ve Domain Model Entityleri arasında translate/map yapmamız gerekir.
Yukarıda tanımlanmış layerlar arasındaki bağımlılıklar iyi yönetilmelidir. Domain Layer hiç bir layera bağımlı olmamalıdır.
Bir Domain Model Entitysi, Behaviorları metodlar aracılığıyla implemente eder , Yani "anemic" model gibi değildir. Bazen herhangi bir logici uygulamayan Entitylere sahip olabilirsiniz.
Anemic Modelin en büyük belirtisi bu entityler içerisinde hiç bir behavior yoktur. Sadece propertylerden ibarettir. Geleneksel yöntemlerde Business Layer data modelin üzerinde yer alır ve data modeli sadece data olarak kullanır. Anemic Domain Model, yalnızca prosedürel stilde bir tasarımdır. Anemik Entity Objeleri , behaviordan(yöntemlerden) yoksun oldukları için gerçek nesne değildir. Sadece data propertyleri tutarlar ve bu nedenle nesne yönelimli tasarım değildir. Tüm behavioru servis nesnelerine (business layer) koyarak, aslında spagetti kodu veya işlem betikleri elde edersiniz ve bu nedenle bir domain modelin sağladığı avantajları kaybedersiniz.
Ne olursa olsun, Mikro Servisiniz veya Bounded Contextiniz çok basitse (bir CRUD hizmeti), yalnızca data propertylere sahip entity objeleri biçimindeki anamic domain modeli yeterli olabilir ve daha karmaşık DDD kalıpları uygulamaya değmeyebilir. Bu durumda, CRUD için sadece datalarla bir entity oluşturduğunuz için bunun ismi Persistence Model olacaktır.
Bazı insanlar anemic domain modelin bir anti-kalıp olduğunu söylüyor. Bu gerçekten ne uyguladığınıza bağlıdır. Oluşturmakta olduğunuz mikro servis yeterince basitse (örneğin, bir CRUD hizmeti), anamic domaic model burada bir anti-kalıp değildir
How you can determine where the 𝗯𝘂𝘀𝗶𝗻𝗲𝘀𝘀 𝗹𝗼𝗴𝗶𝗰 should reside in DDD !?
Within Domain-Driven Design, the essence of business logic is divided into two distinct layers: 𝗗𝗼𝗺𝗮𝗶𝗻 𝗟𝗼𝗴𝗶𝗰 and 𝗔𝗽𝗽𝗹𝗶𝗰𝗮𝘁𝗶𝗼𝗻 𝗟𝗼𝗴𝗶𝗰.
𝗗𝗼𝗺𝗮𝗶𝗻 𝗟𝗼𝗴𝗶𝗰 encapsulates the core domain rules governing the system, while 𝗔𝗽𝗽𝗹𝗶𝗰𝗮𝘁𝗶𝗼𝗻 𝗟𝗼𝗴𝗶𝗰 is responsible for implementing application-specific use cases.
Even though we understand the concept, putting it into practice isn't always straightforward. Figuring out which code belongs in the Application Layer and which in the Domain Layer can be tricky
asking "𝘄𝗵𝗲𝘁𝗵𝗲𝗿 𝘁𝗵𝗲 𝗹𝗼𝗴𝗶𝗰 𝗰𝗵𝗮𝗻𝗴𝗲𝘀 𝗮𝗰𝗿𝗼𝘀𝘀 𝗱𝗶𝗳𝗳𝗲𝗿𝗲𝗻𝘁 𝘂𝘀𝗲 𝗰𝗮𝘀𝗲𝘀" is a fundamental question to determine whether it belongs in the Domain Layer or the Application Layer in Domain-Driven Design (DDD).
Let's take an example of 𝗠𝗲𝗺𝗯𝗲𝗿𝘀𝗵𝗶𝗽 𝗥𝗲𝗴𝗶𝘀𝘁𝗿𝗮𝘁𝗶𝗼𝗻.
In this scenario, every guest who registers for membership must be charged $1. However, if the member is added by certain use cases, such as the operation team, no charge is applied.
so as you can see charging $1 for membership is not necessary to be able to create a new membership. It's an application logic specific to certain use cases.
Within Domain-Driven Design, the essence of business logic is divided into two distinct layers: 𝗗𝗼𝗺𝗮𝗶𝗻 𝗟𝗼𝗴𝗶𝗰 and 𝗔𝗽𝗽𝗹𝗶𝗰𝗮𝘁𝗶𝗼𝗻 𝗟𝗼𝗴𝗶𝗰.
𝗗𝗼𝗺𝗮𝗶𝗻 𝗟𝗼𝗴𝗶𝗰 encapsulates the core domain rules governing the system, while 𝗔𝗽𝗽𝗹𝗶𝗰𝗮𝘁𝗶𝗼𝗻 𝗟𝗼𝗴𝗶𝗰 is responsible for implementing application-specific use cases.
Even though we understand the concept, putting it into practice isn't always straightforward. Figuring out which code belongs in the Application Layer and which in the Domain Layer can be tricky
asking "𝘄𝗵𝗲𝘁𝗵𝗲𝗿 𝘁𝗵𝗲 𝗹𝗼𝗴𝗶𝗰 𝗰𝗵𝗮𝗻𝗴𝗲𝘀 𝗮𝗰𝗿𝗼𝘀𝘀 𝗱𝗶𝗳𝗳𝗲𝗿𝗲𝗻𝘁 𝘂𝘀𝗲 𝗰𝗮𝘀𝗲𝘀" is a fundamental question to determine whether it belongs in the Domain Layer or the Application Layer in Domain-Driven Design (DDD).
Let's take an example of 𝗠𝗲𝗺𝗯𝗲𝗿𝘀𝗵𝗶𝗽 𝗥𝗲𝗴𝗶𝘀𝘁𝗿𝗮𝘁𝗶𝗼𝗻.
In this scenario, every guest who registers for membership must be charged $1. However, if the member is added by certain use cases, such as the operation team, no charge is applied.
so as you can see charging $1 for membership is not necessary to be able to create a new membership. It's an application logic specific to certain use cases.
Hiç yorum yok:
Yorum Gönder