Vertical Slice Architecture vs. Traditional Layered Architecture: A Comprehensive Comparison

July 6, 2024 5 mins to read
Share

In the ever-evolving world of software development, architects and developers continuously seek methodologies that enhance code organization, maintainability, and scalability. Two prominent architectural patterns that have emerged are the Traditional Layered Architecture and Vertical Slice Architecture. While the former has been a staple in the industry for decades, the latter is gaining traction for its innovative approach to structuring code. This article delves into a comprehensive comparison between these two architectures, highlighting their benefits, drawbacks, and real-world applications with C# .NET code examples.

Understanding Traditional Layered Architecture

Traditional Layered Architecture, also known as N-tier architecture, organizes an application into horizontal layers, each responsible for a distinct aspect of the system. The common layers include:

  1. Presentation Layer: Handles user interface and user experience.
  2. Application Layer: Manages business logic and workflow.
  3. Domain Layer: Contains the core business logic and rules.
  4. Data Access Layer: Interacts with the database and handles data retrieval and storage.
Vertical Slice Architecture

Example: Traditional Layered Architecture in C# .NET

// Presentation Layer: Controller in ASP.NET Core
public class ProductController : ControllerBase
{
    private readonly IProductService _productService;

    public ProductController(IProductService productService)
    {
        _productService = productService;
    }

    [HttpPost("products")]
    public IActionResult CreateProduct([FromBody] CreateProductRequest request)
    {
        var result = _productService.CreateProduct(request);
        if (result.IsSuccess)
            return Ok(result.Value);
        return BadRequest(result.Error);
    }
}

// Application Layer: Service
public class ProductService : IProductService
{
    private readonly IProductRepository _productRepository;

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

    public Result<ProductResponse> CreateProduct(CreateProductRequest request)
    {
        var product = new Product
        {
            Name = request.Name,
            Price = request.Price
        };

        _productRepository.Add(product);
        return Result.Success(new ProductResponse(product.Id, product.Name, product.Price));
    }
}

// Domain Layer: Domain Model
public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}

// Data Access Layer: Repository
public class ProductRepository : IProductRepository
{
    private readonly AppDbContext _context;

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

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

Benefits of Traditional Layered Architecture

  1. Separation of Concerns: Each layer focuses on a specific aspect of the application, promoting clear separation of responsibilities.
  2. Reusability: Common functionalities can be reused across multiple layers.
  3. Testability: Layers can be tested independently, facilitating unit testing.

Drawbacks of Traditional Layered Architecture

  1. Complexity: Managing dependencies and interactions across layers can become cumbersome.
  2. Tight Coupling: Changes in one layer often necessitate changes in others, leading to brittle code.
  3. Scalability Issues: Scaling specific features can be challenging due to the horizontal nature of the architecture.

Understanding Vertical Slice Architecture

Vertical Slice Architecture takes a different approach by organizing code around features rather than technical concerns. Each vertical slice encompasses all the necessary components to fulfill a specific functionality, from the user interface to the data access.

Vertical Slice Architecture

Example: Vertical Slice Architecture in C# .NET

public static class CreateProduct
{
    public record Request(string Name, decimal Price);
    public record Response(int Id, string Name, decimal Price);

    public class Validator : AbstractValidator<Request>
    {
        public Validator()
        {
            RuleFor(x => x.Name).NotEmpty().MaximumLength(100);
            RuleFor(x => x.Price).GreaterThanOrEqualTo(0);
        }
    }

    public class Endpoint : IEndpoint
    {
        public void MapEndpoint(IEndpointRouteBuilder app)
        {
            app.MapPost("products", Handler).WithTags("Products");
        }

        public static async Task<IResult> Handler(
            Request request,
            IValidator<Request> validator,
            AppDbContext context)
        {
            var validationResult = await validator.ValidateAsync(request);
            if (!validationResult.IsValid)
            {
                return Results.BadRequest(validationResult.Errors);
            }

            var product = new Product
            {
                Name = request.Name,
                Price = request.Price
            };

            context.Products.Add(product);
            await context.SaveChangesAsync();

            return Results.Ok(new Response(product.Id, product.Name, product.Price));
        }
    }
}

Benefits of Vertical Slice Architecture

  1. Improved Cohesion: Each feature is self-contained, making the code easier to understand, modify, and test.
  2. Reduced Complexity: The mental model of the application is simplified, as developers focus on features rather than layers.
  3. Focus on Business Logic: The architecture emphasizes business use cases over technical details.
  4. Easier Maintenance: Changes to a feature are localized within its slice, reducing the risk of unintended side effects.

Drawbacks of Vertical Slice Architecture

  1. Initial Learning Curve: Developers accustomed to traditional architectures may need time to adapt to VSA.
  2. Potential Code Duplication: Without careful management, there might be duplication of code across slices.

Comparison of Traditional Layered Architecture and Vertical Slice Architecture

  1. Separation of Concerns:
    • Traditional Layered Architecture: Separation is based on technical concerns (UI, business logic, data access).
    • Vertical Slice Architecture: Separation is based on business features, promoting a more cohesive and understandable structure.
  2. Complexity:
    • Traditional Layered Architecture: Complexity arises from managing dependencies and interactions across horizontal layers.
    • Vertical Slice Architecture: Complexity is reduced as each slice is self-contained, but managing cross-cutting concerns can be challenging.
  3. Scalability:
    • Traditional Layered Architecture: Scaling specific features can be difficult due to the horizontal nature of the architecture.
    • Vertical Slice Architecture: Features can be scaled independently, as each slice is self-contained.
  4. Testability:
    • Traditional Layered Architecture: Each layer can be tested independently, but end-to-end testing might be complex.
    • Vertical Slice Architecture: Testing is more straightforward as each slice can be tested in isolation, including integration tests.
  5. Maintenance:
    • Traditional Layered Architecture: Changes in one layer often necessitate changes in others, leading to brittle code.
    • Vertical Slice Architecture: Changes are localized within slices, reducing the risk of unintended side effects.

How to start with it?

We prepared a simple VSA Project Template that you can download for free.
Download the source code and start exploring.

Download here:

https://medium.com/codenx/code-in-clean-vs-traditional-layered-architecture-net-31c4cad8f815

https://www.linkedin.com/pulse/clean-hexagonal-traditional-layered-architectures-abdallah-shaaban-vpvwf

Leave a comment

Your email address will not be published. Required fields are marked *