Soğan Mimarisi Nedir? Kim Tarafından Geliştirilmiştir ve Amacı Nedir? (Örnek Kodlarla Anlatım)

1. Soğan Mimarisi Nedir?

Soğan Mimarisi (Onion Architecture), 2008 yılında Jeffrey Palermo tarafından ortaya atılan ve yazılım projelerinde bağımlılıkları azaltarak iş mantığını merkezde tutmayı amaçlayan bir mimari yaklaşımdır. Yazılım geliştirme projelerinde dış bağımlılıkların etkisini en aza indiren ve iş mantığını dış dünya değişikliklerine karşı koruyan bu mimari, "Dependency Inversion Principle" (Bağımlılık Ters Çevirme İlkesi) üzerine kurulmuştur.

2. Amacı Nedir?

Soğan Mimarisi'nin temel amacı, yazılım projelerinde iş mantığını (domain logic) dış dünyadan izole etmek ve korumaktır. Palermo'nun amacı, yazılım geliştirme süreçlerinde dış bağımlılıkların (veritabanı, kullanıcı arayüzü, API vb.) iş mantığını etkilememesini sağlamaktır. Bu sayede, sistemin veritabanı, kullanıcı arayüzü veya dış API’ler gibi unsurlar değişse bile, merkezi iş mantığı (domain) aynı kalır ve etkilenmez.

3. Soğan Mimarisi'nin Katmanları

  1. Domain (Çekirdek Katman): İş kurallarını ve domain modellerini içerir. Hiçbir dış bağımlılığı yoktur.
  2. Application Katmanı: Domain’e hizmet eden iş servisleri burada yer alır.
  3. Infrastructure (Altyapı Katmanı): Veritabanı, dosya sistemi veya dış API’lerle ilgili tüm işlemler burada yapılır.
  4. UI (Kullanıcı Arayüzü Katmanı): Kullanıcı arayüzü ve dışa dönük etkileşimlerin yer aldığı katmandır.

Bu katmanlar arasındaki bağımlılıklar, soğanın katmanları gibi düzenlenir. Dış katmanlar iç katmanları kullanır, ancak iç katmanlar dış katmanlardan bağımsızdır. İş mantığının bağımsız kalması, projenin esneklik ve sürdürülebilirliğini artırır.

4. Soğan Mimarisi'nin Kullanımı

Soğan Mimarisi'ni bir e-ticaret sistemi örneği üzerinden basit bir şekilde inceleyelim. Bu sistemde ürünler satılır ve siparişler alınır. Veritabanı veya arayüz gibi dış bağımlılıklar, iş mantığından izole edilmiştir.

Domain Katmanı (Çekirdek Katman)

Domain katmanı, iş mantığının bulunduğu yer olup, dış dünyadan tamamen bağımsızdır.

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}

public interface IProductRepository
{
    Product GetById(int id);
    void Add(Product product);
}

Burada, Product sınıfı iş mantığındaki ürünleri temsil eder. IProductRepository ise bir repository arayüzüdür. Ancak bu katmanda, veritabanının ne olduğunu bilmeyiz, bu altyapı katmanında tanımlanır.

Application Katmanı

Bu katman, domain katmanındaki iş mantığını kullanarak uygulama işlemlerini gerçekleştirir. Örneğin, bir ürün eklemek için bir servis yazarız.

public class ProductService
{
    private readonly IProductRepository _productRepository;

    public ProductService(IProductRepository productRepository)
    {
        _productRepository = productRepository;
    }

    public void AddNewProduct(ProductDto productDto)
    {
        var product = new Product
        {
            Name = productDto.Name,
            Price = productDto.Price
        };

        _productRepository.Add(product);
    }
}

Bu servis, IProductRepository üzerinden ürün ekleme işlemini gerçekleştirir. Ancak burada da veritabanı işlemleri hakkında hiçbir bilgi yoktur. Sadece iş mantığı yönetilir.

Infrastructure Katmanı

Infrastructure katmanı, veritabanı veya dış sistemlerle ilgili işlemlerin gerçekleştirildiği katmandır. Veritabanı işlemleri bu katmanda yer alır.

public class ProductRepository : IProductRepository
{
    private readonly DbContext _context;

    public ProductRepository(DbContext context)
    {
        _context = context;
    }

    public Product GetById(int id)
    {
        return _context.Products.Find(id);
    }

    public void Add(Product product)
    {
        _context.Products.Add(product);
        _context.SaveChanges();
    }
}

Bu sınıf, veritabanı işlemlerini gerçekleştirir ve IProductRepository arayüzünü uygular. Veritabanı işlemleri burada yapılır, ancak iş mantığına müdahale edilmez.

UI Katmanı (Kullanıcı Arayüzü Katmanı)

Kullanıcılar, sistemle etkileşime geçtikleri arayüz üzerinden bu hizmetleri kullanırlar. Web API veya MVC gibi bir teknoloji kullanılabilir.

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    private readonly ProductService _productService;

    public ProductsController(ProductService productService)
    {
        _productService = productService;
    }

    [HttpPost]
    public IActionResult AddProduct(ProductDto productDto)
    {
        _productService.AddNewProduct(productDto);
        return Ok();
    }
}

Bu katman, kullanıcının sisteme ürün eklemesini sağlar. Ancak burada da veritabanına doğrudan bir erişim yoktur. İş mantığı ve altyapı katmanları arasında bir köprü görevi görür.

5. Soğan Mimarisi'nin Avantajları

  • Bağımsız Katmanlar: Dış katmanlardaki değişiklikler (örneğin, veritabanı değişikliği) iç katmanlardaki iş mantığını etkilemez.
  • Kolay Test Edilebilirlik: İş mantığı bağımsız olduğu için kolayca birim testler yazılabilir.
  • Esneklik: Veritabanı, API ya da diğer teknolojiler değiştiğinde iş mantığına müdahale etmek gerekmez.
  • Teknoloji Bağımsızlığı: İş mantığı teknolojiye bağımlı olmadığı için uzun ömürlü projelerde değişimlere karşı daha dayanıklıdır.

6. Soğan Mimarisi'nin Dezavantajları

  • Karmaşıklık: Küçük projeler için gereğinden fazla katman ve soyutlama yaratabilir.
  • Öğrenme Eğrisi: Yeni başlayanlar için katmanlı yapı karmaşık gelebilir.

7. Sonuç

Soğan Mimarisi, iş mantığını merkezde tutarak teknolojik bağımlılıkları minimumda tutmayı amaçlayan bir mimaridir. Jeffrey Palermo tarafından ortaya atılan bu mimari, büyük ve karmaşık projelerde sürdürülebilirliği ve esnekliği artırmak amacıyla geliştirilmiştir. Katmanlar arasında bağımlılığın ters yönde ilerlemesi, teknolojilerin değişmesine rağmen iş mantığının aynı kalmasını sağlar.