SmartOrder — Bölüm 2: Servis Katmanı Mimarisi
SmartOrder serimizin ikinci bölümüne hoş geldiniz! İlk bölümde sistemin genel mimarisine ve veri erişim katmanına (DAL) odaklanmıştık. Bu bölümde ise SmartOrder uygulamasının kalbi olan Servis Katmanı (Services Layer) mimarisini derinlemesine inceleyeceğiz. Servis katmanı, iş mantığının merkezi olduğu, uygulamanın temel fonksiyonlarını barındıran ve dış dünya ile etkileşimi yöneten kritik bir katmandır. Bu katmanın doğru tasarlanması, uygulamanın ölçeklenebilirliği, sürdürülebilirliği ve test edilebilirliği açısından hayati öneme sahiptir.
Servis Katmanı Nedir ve Neden Önemlidir?
Servis katmanı, bir uygulamanın iş kurallarını, süreçlerini ve mantığını barındıran katmandır. Genellikle kullanıcı arayüzü (UI) veya API katmanı ile veri erişim katmanı (DAL) arasında köprü görevi görür. Bu katman, veritabanı işlemlerini doğrudan yapmaz; bunun yerine veri erişim katmanını kullanarak veri manipülasyonu yapar ve bu verilere iş mantığını uygular.
İş Mantığının Merkezi
Servis katmanı, uygulamanın tüm önemli iş kurallarını ve süreçlerini tek bir yerde toplar. Örneğin, bir siparişin oluşturulması, güncellenmesi veya iptal edilmesi gibi tüm operasyonlar burada tanımlanır. Bu merkezileşme, iş mantığının tutarlı bir şekilde uygulanmasını sağlar ve farklı arayüzlerden (web, mobil, API) gelen isteklerin aynı kurallara tabi olmasını garanti eder.
Soyutlama ve Bağımlılık Azaltma
Bu katman, alt katmanlardaki (veri erişim katmanı gibi) detayları üst katmanlardan (UI, API) soyutlar. Üst katmanlar, verilerin nasıl saklandığı veya erişildiği hakkında bilgi sahibi olmak zorunda kalmaz; sadece servis katmanının sunduğu arayüzleri kullanarak işlevselliğe erişirler. Bu soyutlama, bağımlılıkları azaltır ve alt katmanlarda yapılan değişikliklerin üst katmanları doğrudan etkilemesini engeller.
Geliştirme Süreçlerine Katkısı
İyi tasarlanmış bir servis katmanı, paralel geliştirmeyi kolaylaştırır. Bir ekip UI üzerinde çalışırken, başka bir ekip servis katmanındaki iş mantığını geliştirebilir. Ayrıca, iş gereksinimleri değiştikçe, bu değişikliklerin çoğu servis katmanında yönetilebilir, bu da diğer katmanlarda minimum etki yaratır. Bu durum, uygulamanın adaptasyon yeteneğini artırır.
Örnek: Bir Sipariş Oluşturma Süreci
SmartOrder’da bir sipariş oluşturma süreci, servis katmanının kritik rolünü açıkça gösterir:
- Kullanıcı, ürünleri seçer ve sepetini onaylar.
- API katmanı, bu isteği
OrderService‘e iletir. OrderService, ürün stoklarını kontrol eder (ProductServiceveyaStockServicearacılığıyla).- Müşteri bilgileri doğrulanır (
CustomerServicearacılığıyla). - Siparişin geçerliliği için iş kuralları uygulanır (minimum sipariş tutarı, kampanya koşulları vb.).
- Geçerliyse, sipariş veritabanına kaydedilir (
OrderRepositoryaracılığıyla). - Ödeme işlemi başlatılır (
PaymentServicearacılığıyla). - Sipariş durumu güncellenir ve müşteriye bildirim gönderilir.
SmartOrder Servis Katmanının Temel Prensipleri
SmartOrder’ın servis katmanı, modern yazılım geliştirme prensiplerine uygun olarak tasarlanmıştır. Bu prensipler, katmanın sağlam, esnek ve sürdürülebilir olmasını sağlar.
Katmanlı Mimari Yaklaşımı
SmartOrder, geleneksel katmanlı mimariyi benimser. Bu yaklaşımda, her katmanın belirli bir sorumluluğu vardır ve sadece kendi altındaki katmanla iletişim kurar. Servis katmanı, sunum katmanından gelen istekleri alır ve veri erişim katmanıyla etkileşime girerek iş mantığını uygular. Bu net ayrım, karmaşıklığı azaltır ve her katmanın bağımsız olarak geliştirilmesine ve test edilmesine olanak tanır.
Sorumlulukların Ayrılması (Separation of Concerns)
Her servis sınıfı, belirli bir iş alanına veya fonksiyona odaklanır. Örneğin, OrderService sadece siparişlerle ilgili işlemleri yönetirken, ProductService ürün yönetimiyle ilgilenir. Bu prensip, kodun daha okunabilir, bakımı daha kolay ve hatalara daha az açık olmasını sağlar. Bir değişiklik yapılması gerektiğinde, yalnızca ilgili servisin etkilenmesi beklenir.
Bağımlılık Enjeksiyonu (Dependency Injection – DI)
Servis katmanı, bağımlılık enjeksiyonunu yoğun bir şekilde kullanır. Servisler, ihtiyaç duydukları diğer servisleri veya repository’leri doğrudan oluşturmak yerine, constructor’ları aracılığıyla dışarıdan alırlar. Bu, servislerin daha gevşek bağlı olmasını (loosely coupled) sağlar, test edilebilirliği artırır ve kodun esnekliğini yükseltir. SmartOrder’da bu genellikle bir IoC (Inversion of Control) konteyneri (örneğin, .NET’in yerleşik DI konteyneri veya Autofac gibi bir kütüphane) aracılığıyla yönetilir.
public class OrderService : IOrderService
{
private readonly IOrderRepository _orderRepository;
private readonly IProductService _productService;
private readonly IPaymentService _paymentService;
public OrderService(IOrderRepository orderRepository, IProductService productService, IPaymentService paymentService)
{
_orderRepository = orderRepository;
_productService = productService;
_paymentService = paymentService;
}
// ... servis metodları ...
}
Tek Sorumluluk Prensibi (Single Responsibility Principle - SRP)
Her servis veya servis metodu, yalnızca tek bir sorumluluğa sahip olmalıdır. Bu, bir sınıfın veya metodun değişmesi için yalnızca bir nedeni olması gerektiği anlamına gelir. Örneğin, bir OrderService'in hem sipariş oluşturma hem de kullanıcı yetkilendirme mantığını içermesi SRP'ye aykırıdır. Yetkilendirme ayrı bir AuthorizationService tarafından ele alınmalıdır. Bu prensip, kodun anlaşılabilirliğini ve sürdürülebilirliğini önemli ölçüde artırır.
Servis Katmanı Bileşenleri
SmartOrder'ın servis katmanı, farklı sorumlulukları olan çeşitli bileşenlerden oluşur. Bu bileşenler, iş mantığını düzenli ve yönetilebilir bir şekilde uygulamak için birlikte çalışır.
Uygulama Servisleri (Application Services)
Uygulama servisleri, genellikle dış dünya ile (API veya UI katmanı) etkileşime giren ve belirli bir iş akışını veya kullanım senaryosunu koordine eden sınıflardır. Bunlar, birden fazla domain servisinin veya repository'nin orkestrasyonunu yaparak karmaşık iş işlemlerini yönetir. Örneğin, OrderAppService, bir siparişin uçtan uca oluşturulması sürecini yönetebilir, bu süreçte ProductService, CustomerService ve PaymentService gibi diğer servisleri çağırabilir.
Domain Servisleri (Domain Services)
Domain servisleri, tek bir domain varlığına (örneğin, Order veya Product) ait olmayan, ancak birden fazla varlığı veya genel bir iş kuralını içeren iş mantığını barındırır. Örneğin, bir ürünün stok durumuna göre indirim uygulama kuralı, hem Product hem de Discount varlıklarını ilgilendirdiği için bir PricingService veya DiscountService içinde yer alabilir. Bu servisler, genellikle uygulama servisleri tarafından çağrılır.
Veri Erişim Katmanı (DAL) ile Etkileşim
Servis katmanı, doğrudan veritabanı işlemleri yapmaz. Bunun yerine, veri erişim katmanında tanımlanmış olan repository arayüzlerini (örneğin, IOrderRepository, IProductRepository) kullanır. Bu arayüzler aracılığıyla veri ekleme, güncelleme, silme ve sorgulama işlemleri gerçekleştirilir. Bu ayrım, servis katmanını veritabanı teknolojisinden bağımsız hale getirir ve DAL'da yapılan değişikliklerin servis katmanını etkilemesini en aza indirir.
public async Task CreateOrderAsync(CreateOrderCommand command)
{
// Validasyonlar burada veya ayrı bir validator'da yapılır.
if (command.OrderItems == null || !command.OrderItems.Any())
{
throw new BusinessException("Sipariş öğeleri boş olamaz.");
}
var order = new Order
{
CustomerId = command.CustomerId,
OrderDate = DateTime.UtcNow,
Status = OrderStatus.Pending,
// Diğer özellikler
};
foreach (var item in command.OrderItems)
{
var product = await _productService.GetProductByIdAsync(item.ProductId);
if (product == null || product.StockQuantity < item.Quantity)
{
throw new BusinessException($"Ürün {item.ProductId} için yeterli stok yok.");
}
order.AddOrderItem(new OrderItem { ProductId = item.ProductId, Quantity = item.Quantity, Price = product.Price });
await _productService.DecreaseStockAsync(item.ProductId, item.Quantity); // Stok güncelleme
}
await _orderRepository.AddAsync(order);
await _orderRepository.UnitOfWork.CommitAsync(); // Transaction yönetimi
// Ödeme servisini çağır
await _paymentService.ProcessPaymentAsync(order.Id, order.TotalPrice);
return _mapper.Map(order);
}
Yardımcı Sınıflar ve Ara Katmanlar (Helper Classes and Middleware)
Servis katmanı içinde, iş mantığına doğrudan hizmet eden ancak bir servisin ana sorumluluğu olmayan yardımcı sınıflar (örneğin, tarih/saat yardımcıları, formatlama yardımcıları) bulunabilir. Ayrıca, loglama, önbellekleme veya yetkilendirme gibi çapraz kesen konuları ele almak için ara katmanlar (middleware) veya Aspect-Oriented Programming (AOP) yaklaşımları da kullanılabilir. Bu, ana iş mantığının temiz kalmasını sağlar.
İş Akışları ve Senaryolar
SmartOrder'ın servis katmanı, uygulamanın temel iş akışlarını ve kullanım senaryolarını yönetmek üzere tasarlanmıştır. Her senaryo, belirli bir dizi adımdan oluşur ve bu adımlar, farklı servislerin ve repository'lerin koordinasyonunu gerektirir.
Sipariş Oluşturma Akışı
Daha önce kısaca bahsedilen sipariş oluşturma akışı, servis katmanının en karmaşık senaryolarından biridir. Bu akış, kullanıcıdan gelen verilerin doğrulanması, stok kontrolü, fiyatlandırma, veritabanına kaydetme ve ödeme işlemlerini içerir. Her adımda olası hataların yönetimi ve tutarlılığın sağlanması kritik öneme sahiptir.
// Sipariş Oluşturma Akışı Pseudo-Kodu
public async Task CreateOrder(CreateOrderRequest request)
{
// 1. İstek verilerini valide et (FluentValidation veya manuel)
ValidateOrderRequest(request);
// 2. Müşteri bilgilerini kontrol et
var customer = await _customerService.GetCustomerById(request.CustomerId);
if (customer == null) throw new NotFoundException("Müşteri bulunamadı.");
var order = Order.CreateNew(request.CustomerId);
foreach (var itemRequest in request.Items)
{
// 3. Ürün ve stok kontrolü
var product = await _productService.GetProductById(itemRequest.ProductId);
if (product == null) throw new NotFoundException($"Ürün {itemRequest.ProductId} bulunamadı.");
if (product.StockQuantity < itemRequest.Quantity) throw new BusinessException($"Yetersiz stok için {product.Name}.");
order.AddOrderItem(product.Id, itemRequest.Quantity, product.Price);
await _productService.DecreaseStock(product.Id, itemRequest.Quantity); // Stok düşürme
}
// 4. İş kurallarını uygula (indirimler, minimum sipariş tutarı vb.)
_discountService.ApplyDiscounts(order);
// 5. Siparişi kaydet (Transaction içinde)
await _orderRepository.AddAsync(order);
await _orderRepository.UnitOfWork.CommitAsync(); // Veritabanı işlemini onayla
// 6. Ödeme işlemini başlat
var paymentResult = await _paymentService.ProcessPayment(order.Id, order.TotalPrice);
if (!paymentResult.IsSuccess)
{
// Ödeme başarısız olursa siparişi iptal et veya durumu güncelle
order.Status = OrderStatus.PaymentFailed;
await _orderRepository.UpdateAsync(order);
await _orderRepository.UnitOfWork.CommitAsync();
throw new PaymentFailedException("Ödeme işlemi başarısız oldu.");
}
order.Status = OrderStatus.Confirmed;
await _orderRepository.UpdateAsync(order);
await _orderRepository.UnitOfWork.CommitAsync();
// 7. Müşteriye bildirim gönder
_notificationService.SendOrderConfirmationEmail(customer, order);
return _mapper.Map(order);
}
Sipariş Güncelleme ve İptal
Bir siparişin güncellenmesi veya iptal edilmesi de karmaşık süreçlerdir. Örneğin, bir sipariş iptal edildiğinde, stokların geri eklenmesi, ödemenin iade edilmesi ve müşteriye bildirim gönderilmesi gerekebilir. Bu işlemlerin tamamı, atomik bir şekilde (ya hepsi başarılı olur ya da hiçbiri) gerçekleştirilmelidir.
Stok Yönetimi Entegrasyonu
SmartOrder, stok yönetimi ile derinlemesine entegredir. Bir sipariş oluşturulduğunda veya güncellendiğinde, ilgili ürünlerin stok miktarları otomatik olarak güncellenir. Bu entegrasyon, tutarsızlıkları önlemek ve gerçek zamanlı stok bilgilerini sağlamak için hayati öneme sahiptir. ProductService veya özel bir StockService bu entegrasyonu yönetir.
Ödeme İşlemleri
Ödeme işlemleri, hassas ve harici sistemlerle etkileşim gerektiren bir alandır. PaymentService, ödeme ağ geçitleri ile iletişim kurarak ödeme alma, iade etme ve ödeme durumlarını güncelleme gibi işlemleri yönetir. Bu servis, güvenlik ve hata yönetimi açısından özel dikkat gerektirir.
Hata Yönetimi ve Validasyon
Sağlam bir servis katmanı, kapsamlı hata yönetimi ve validasyon mekanizmalarına sahip olmalıdır. Bu, uygulamanın beklenmedik durumlarla başa çıkabilmesini ve kullanıcıya anlamlı geri bildirimler sunabilmesini sağlar.
Giriş Verisi Validasyonu
Servis katmanına gelen tüm giriş verileri (DTO'lar, komutlar), işlenmeden önce valide edilmelidir. Bu validasyonlar, zorunlu alanların doldurulup doldurulmadığı, veri tiplerinin doğru olup olmadığı ve belirli formatlara uyulup uyulmadığı gibi temel kontrolleri içerir. FluentValidation gibi kütüphaneler bu süreçte oldukça faydalıdır.
İş Kuralı İhlalleri
Giriş verisi geçerli olsa bile, iş kurallarına uymayabilir. Örneğin, bir müşterinin kredi limiti aşılmış olabilir veya bir ürün stokta olmayabilir. Bu tür durumlar, özel iş istisnaları (BusinessException) fırlatılarak yönetilir ve bu istisnalar, üst katmanlarda yakalanarak kullanıcıya uygun bir hata mesajı olarak iletilir.
Özel İstisnalar ve Hata Kodları
SmartOrder, farklı hata türleri için özel istisna sınıfları tanımlar (örneğin, NotFoundException, BusinessException, PaymentFailedException). Bu, hataların daha spesifik bir şekilde yakalanmasını ve işlenmesini sağlar. Ayrıca, hata kodları kullanarak istemciye daha detaylı bilgi verilebilir.
public class BusinessException : Exception
{
public string ErrorCode { get; }
public BusinessException(string message, string errorCode = null) : base(message)
{
ErrorCode = errorCode;
}
}
Merkezi Hata Yakalama
Servis katmanında fırlatılan istisnalar, genellikle API katmanında merkezi bir hata yakalama mekanizması (örneğin, bir global exception handler middleware) tarafından yakalanır. Bu mekanizma, istisnaları uygun HTTP durum kodlarına (400 Bad Request, 404 Not Found, 500 Internal Server Error) ve standartlaştırılmış hata yanıtlarına dönüştürür.
Güvenlik ve Yetkilendirme
SmartOrder'ın servis katmanı, uygulamanın güvenliğini sağlamak ve yetkisiz erişimi engellemek için kritik bir rol oynar. İşlemlerin yalnızca yetkili kullanıcılar tarafından ve doğru izinlerle gerçekleştirildiğinden emin olunur.
Kimlik Doğrulama (Authentication)
Servis katmanı, doğrudan kimlik doğrulama işlemini yapmaz. Bu genellikle API veya sunum katmanında (örneğin, JWT token doğrulama) gerçekleştirilir. Ancak, servis metotları çağrıldığında, çağrıyı yapan kullanıcının kimliği (örneğin, kullanıcı ID'si) genellikle servis katmanına iletilir.
Yetkilendirme Kontrolleri (Authorization Checks)
Servis katmanı, belirli bir işlemin gerçekleştirilmesi için kullanıcının gerekli izinlere sahip olup olmadığını kontrol eder. Bu kontroller, metodun başında veya daha genel bir şekilde bir yetkilendirme filtresi (örneğin, .NET Core'daki [Authorize] attribute'ları ve özel policy'ler) aracılığıyla yapılabilir. Örneğin, sadece "Admin" rolüne sahip kullanıcılar siparişleri iptal edebilirken, "Customer" rolüne sahip kullanıcılar sadece kendi siparişlerini görüntüleyebilir.
// Örnek bir yetkilendirme kontrolü
public async Task CancelOrderAsync(Guid orderId, Guid userId, UserRole userRole)
{
var order = await _orderRepository.GetByIdAsync(orderId);
if (order == null)
{
throw new NotFoundException("Sipariş bulunamadı.");
}
// Yalnızca adminler veya kendi siparişini iptal eden kullanıcılar
if (userRole != UserRole.Admin && order.CustomerId != userId)
{
throw new UnauthorizedAccessException("Bu siparişi iptal etme yetkiniz yok.");
}
if (order.Status == OrderStatus.Cancelled || order.Status == OrderStatus.Delivered)
{
throw new BusinessException("İptal edilemez durumda olan bir sipariş.");
}
// ... iptal mantığı ...
order.Status = OrderStatus.Cancelled;
await _orderRepository.UpdateAsync(order);
await _orderRepository.UnitOfWork.CommitAsync();
// Stokları geri ekle, ödemeyi iade et vb.
return true;
}
Hassas Veri İşleme
Servis katmanı, hassas verilerin (örneğin, kredi kartı bilgileri, kişisel tanımlayıcı bilgiler) işlenmesinde ve depolanmasında güvenlik en iyi uygulamalarını takip eder. Bu veriler, şifreleme, maskeleme ve minimum ayrıcalık prensibi gibi yöntemlerle korunur. Doğrudan hassas verileri depolamaktan kaçınılır ve bunun yerine tokenizasyon gibi yöntemler tercih edilir.
Güvenlik Politikalarının Uygulanması
SmartOrder'ın güvenlik politikaları, servis katmanında titizlikle uygulanır. Bu, yetkilendirme kurallarının yanı sıra, veri bütünlüğü kontrolleri, SQL enjeksiyonu ve XSS gibi yaygın güvenlik açıklarına karşı koruma sağlamayı da içerir. Tüm girişler sanitize edilir ve güvenli API kullanım kalıpları benimsenir.
Test Edilebilirlik ve Bakım
İyi tasarlanmış bir servis katmanı, kolayca test edilebilir ve uzun vadede bakımı yapılabilir olmalıdır. Bu, yazılımın kalitesini ve geliştirme hızını doğrudan etkiler.
Birim Testleri (Unit Tests)
Servis katmanındaki her bir servis metodu, izole bir şekilde birim testlerine tabi tutulmalıdır. Bağımlılık enjeksiyonu sayesinde, servislerin bağımlılıkları (repository'ler, diğer servisler) kolayca mock'lanabilir veya stub'lanabilir. Bu, her metodun kendi iş mantığını doğru bir şekilde yerine getirip getirmediğini hızlı ve güvenilir bir şekilde doğrulamayı sağlar.
// OrderService için birim testi örneği
[Fact]
public async Task CreateOrder_WithValidData_ReturnsOrderDto()
{
// Arrange
var mockOrderRepo = new Mock();
var mockProductService = new Mock();
var mockPaymentService = new Mock();
var mockMapper = new Mock(); // AutoMapper için
var orderService = new OrderService(
mockOrderRepo.Object,
mockProductService.Object,
mockPaymentService.Object,
mockMapper.Object
);
var createCommand = new CreateOrderCommand
{
CustomerId = Guid.NewGuid(),
OrderItems = new List
{
new OrderItemCommand { ProductId = Guid.NewGuid(), Quantity = 1 }
}
};
var product = new Product { Id = createCommand.OrderItems[0].ProductId, StockQuantity = 10, Price = 100 };
mockProductService.Setup(s => s.GetProductByIdAsync(It.IsAny())).ReturnsAsync(product);
mockPaymentService.Setup(s => s.ProcessPaymentAsync(It.IsAny(), It.IsAny())).ReturnsAsync(new PaymentResult { IsSuccess = true });
mockOrderRepo.Setup(r => r.UnitOfWork).Returns(new Mock().Object); // UnitOfWork mock'lama
// Act
var result = await orderService.CreateOrderAsync(createCommand);
// Assert
Assert.NotNull(result);
mockOrderRepo.Verify(r => r.AddAsync(It.IsAny()), Times.Once);
mockOrderRepo.Verify(r => r.UnitOfWork.CommitAsync(), Times.Exactly(2)); // Add ve Payment sonrası
mockProductService.Verify(s => s.DecreaseStockAsync(It.IsAny(), It.IsAny()), Times.Once);
}
Entegrasyon Testleri (Integration Tests)
Birim testleri iş mantığını doğrulamak için yeterli olsa da, servis katmanının diğer katmanlarla (özellikle veri erişim katmanı ve harici servisler) doğru bir şekilde entegre olup olmadığını doğrulamak için entegrasyon testleri gereklidir. Bu testler, gerçek veritabanı veya mock'lanmış harici servislerle çalışarak daha geniş kapsamlı senaryoları kapsar.
Mocking ve Bağımlılıkların Yönetimi
Bağımlılık enjeksiyonu ve iyi tanımlanmış arayüzler, testler sırasında bağımlılıkları kolayca mock'lamamızı sağlar. Moq gibi kütüphaneler, mock nesneler oluşturarak test ortamını kontrol etmemize ve belirli senaryoları simüle etmemize olanak tanır. Bu, testlerin hızlı çalışmasını ve dış bağımlılıklardan etkilenmemesini sağlar.
Kod Kalitesi ve Refactoring
Servis katmanı, uygulamanın en sık değişen ve gelişen kısmı olmaya eğilimlidir. Bu nedenle, kod kalitesine ve düzenli refactoring'e büyük önem verilmelidir. Temiz kod prensipleri, DRY (Don't Repeat Yourself), YAGNI (You Aren't Gonna Need It) ve KISS (Keep It Simple, Stupid) gibi yaklaşımlar, katmanın uzun vadede yönetilebilir kalmasına yardımcı olur.
Sonuç
SmartOrder uygulamasının servis katmanı, iş mantığının kalbi ve uygulamanın en kritik bileşenlerinden biridir. Bu katman, katmanlı mimari, sorumlulukların ayrılması, bağımlılık enjeksiyonu ve tek sorumluluk prensibi gibi modern yazılım prensiplerine uygun olarak tasarlanmıştır. Güçlü hata yönetimi, kapsamlı güvenlik önlemleri ve yüksek test edilebilirlik sayesinde, SmartOrder'ın servis katmanı, ölçeklenebilir, sürdürülebilir ve güvenilir bir platform sunar. Bu sağlam temel, gelecekteki geliştirmeler ve değişen iş gereksinimleri karşısında uygulamanın esnek kalmasını sağlar.
SSS (Sık Sorulan Sorular)
Servis katmanı ile Repository katmanı arasındaki temel fark nedir?
Repository katmanı (veri erişim katmanının bir parçası), veritabanı CRUD (Create, Read, Update, Delete) operasyonlarını soyutlar. Yani, verilerin nasıl saklandığı veya alındığıyla ilgilenir. Servis katmanı ise, bu repository'leri kullanarak iş kurallarını ve süreçlerini uygular. Servis katmanı "ne" yapılacağını (örneğin, sipariş oluşturma), repository ise "nasıl" yapılacağını (örneğin, siparişi veritabanına kaydetme) bilir.
Domain servisi ne zaman kullanılmalı?
Domain servisleri, iş mantığı birden fazla varlığı ilgilendirdiğinde veya tek bir varlığa ait olmayan karmaşık bir iş kuralı olduğunda kullanılır. Örneğin, bir kullanıcının kredi puanına göre indirim uygulama veya farklı ürün kategorileri arasında çapraz satış önerme gibi senaryolar domain servislerinde yer alabilir. Tek bir varlığın kendi içindeki davranışları genellikle varlığın kendi metotları içinde (rich domain model) veya uygulama servisleri içinde yönetilir.
Servis katmanında transaction yönetimi nasıl yapılır?
Transaction yönetimi genellikle servis katmanında, birden fazla veritabanı operasyonunun atomik bir birim olarak yürütülmesi gerektiğinde uygulanır. SmartOrder'da bu, genellikle Unit of Work deseni (repository'ler aracılığıyla) kullanılarak yapılır. Bir servis metodu içinde birden fazla repository işlemi yapıldığında, tüm işlemler başarılı olursa Commit çağrılır, aksi takdirde Rollback yapılır. Bu, veritabanı tutarlılığını sağlar.
SmartOrder'da servis katmanı performansı nasıl etkiler?
İyi tasarlanmış bir servis katmanı, performansı olumlu yönde etkileyebilir. İş mantığını merkezileştirerek ve gereksiz veri erişimini önleyerek optimizasyonlara olanak tanır. Ancak, kötü tasarlanmış servisler (örneğin, gereksiz katmanlar arası çağrılar, verimli olmayan sorgular, aşırı büyük servis metotları) performansı olumsuz etkileyebilir. SmartOrder'da, performans kritik senaryolarda önbellekleme, asenkron işlemler ve verimli veri erişim stratejileri kullanılarak performans optimize edilir.