.NET 中的垂直切片体系结构

aa3193935b3f89a56fc51cccbab40e4b.png

在现代软件开发中,高效地构建应用程序对于可维护性、可伸缩性和适应性至关重要。在 .NET 社区中越来越受欢迎的一种体系结构模式是垂直切片体系结构。

与传统的分层架构不同,垂直切片强调将应用程序划分为功能,而不是 UI、业务逻辑和数据访问等技术问题。

这种方法增强了凝聚力,减少了依赖性,并使其更容易独立地处理特定功能。

什么是垂直切片?

垂直切片是指围绕应用程序的功能构建应用程序,每个切片代表一个完整的、独立的功能,包含从用户界面到数据库的所有必要组件。每个切片包括:

  1. 表示层:负责用户交互,通常是 Web UI 或 API。

  2. 业务逻辑层:包含域逻辑和业务规则。

  3. 数据访问层:管理数据持久性和检索。

垂直切片的好处

  1. 功能独立性:每个功能都是独立的,因此可以更轻松地独立开发、测试和部署。

  2. 提高凝聚力:功能的所有部分都位于一起,增强了理解并减轻了开发人员的认知负担。

  3. 更易于维护:隔离功能可最大程度地减少更改的影响,并使调试更简单。

  4. 增强的可扩展性:功能可以独立扩展,优化资源使用。

在 .NET 中实现垂直切片

让我们演练一个在 .NET Web API 应用程序中实现垂直切片的示例。

第 1 步:设置项目

创建新的 ASP.NET Core Web API 项目:

dotnet new webapi -n VerticalSlicingExample  
cd VerticalSlicingExample

第 2 步:定义特征结构

按要素而不是图层组织工程。例如,如果您的应用程序具有 和 功能,请按如下方式构建它:

VerticalSlicingExample  
│  
├── Features  
│   ├── Orders  
│   │   ├── CreateOrder  
│   │   │   ├── CreateOrderCommand.cs  
│   │   │   ├── CreateOrderHandler.cs  
│   │   │   └── CreateOrderController.cs  
│   │   └── GetOrder  
│   │       ├── GetOrderQuery.cs  
│   │       ├── GetOrderHandler.cs  
│   │       └── GetOrderController.cs  
│   └── Customers  
│       ├── CreateCustomer  
│       │   ├── CreateCustomerCommand.cs  
│       │   ├── CreateCustomerHandler.cs  
│       │   └── CreateCustomerController.cs  
│       └── GetCustomer  
│           ├── GetCustomerQuery.cs  
│           ├── GetCustomerHandler.cs  
│           └── GetCustomerController.cs  
├── Program.cs  
└── Startup.cs

步骤 3:实现特征切片

让我们实现特征切片。

CreateOrderCommand.cs

public class CreateOrderCommand  
{  
    public string ProductName { get; set; }  
    public int Quantity { get; set; }  
    public decimal Price { get; set; }  
}

CreateOrderHandler.cs

public class CreateOrderHandler  
{  
    private readonly ApplicationDbContext _context;  
  
    public CreateOrderHandler(ApplicationDbContext context)  
    {  
        _context = context;  
    }  
  
    public async Task Handle(CreateOrderCommand command)  
    {  
        var order = new Order  
        {  
            ProductName = command.ProductName,  
            Quantity = command.Quantity,  
            Price = command.Price,  
            OrderDate = DateTime.UtcNow  
        };  
  
        _context.Orders.Add(order);  
        await _context.SaveChangesAsync();  
    }  
}

CreateOrderController.cs

[ApiController]  
[Route("api/[controller]")]  
public class CreateOrderController : ControllerBase  
{  
    private readonly CreateOrderHandler _handler;  
  
    public CreateOrderController(CreateOrderHandler handler)  
    {  
        _handler = handler;  
    }  
  
    [HttpPost]  
    public async Task<IActionResult> Post(CreateOrderCommand command)  
    {  
        await _handler.Handle(command);  
        return Ok();  
    }  
}

步骤 4:注册依赖项

在 中,注册依赖项:Startup.cs

public void ConfigureServices(IServiceCollection services)  
{  
    services.AddDbContext<ApplicationDbContext>(options =>  
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));  
  
    services.AddTransient<CreateOrderHandler>();  
    services.AddControllers();  
}

步骤 5:配置数据库上下文

ApplicationDbContext.cs

public class ApplicationDbContext : DbContext  
{  
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)  
        : base(options)  
    {  
    }  
  
    public DbSet<Order> Orders { get; set; }  
}  
  
public class Order  
{  
    public int Id { get; set; }  
    public string ProductName { get; set; }  
    public int Quantity { get; set; }  
    public decimal Price { get; set; }  
    public DateTime OrderDate { get; set; }  
}

使用连接字符串进行更新:appsettings.json

{  
  "ConnectionStrings": {  
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=VerticalSlicingDb;Trusted_Connection=True;MultipleActiveResultSets=true"  
  },  
  "Logging": {  
    "LogLevel": {  
      "Default": "Information",  
      "Microsoft": "Warning",  
      "Microsoft.Hosting.Lifetime": "Information"  
    }  
  },  
  "AllowedHosts": "*"  
}

步骤 6:运行应用程序

运行应用程序并使用 Postman 等工具测试终结点。使用表示 的 JSON 正文向 发送 POST 请求。

将垂直切片与 SOA 集成

在面向服务的体系结构 (SOA) 中,每个服务都是一个独立的单元,具有其业务逻辑和数据存储。垂直切片通过确保每个服务(或微服务)都以功能为中心来补充 SOA。每个服务都可以公开其 API 端点,同时封装其数据访问和业务逻辑,遵循单一责任原则。

示例:Orders Microservice

  • 表示层:ASP.NET 核心 Web API

  • 业务逻辑层:包含在每个处理程序类中。

  • 数据访问层:用于数据库操作的实体框架核心或 Dapper。

示例:客户微服务

  • 表示层:ASP.NET 核心 Web API

  • 业务逻辑层:包含在每个处理程序类中。

  • 数据访问层:用于数据库操作的实体框架核心或 Dapper。

将垂直切片扩展到其他技术

垂直切片也可以应用于 Angular、React 或 Vue.js 等前端技术,其中每个功能切片都包括组件、服务和状态管理。

此外,它可以与 Azure 或 AWS 等云服务集成,其中每个切片都可以具有其无服务器函数、存储帐户和其他资源。

示例:Angular 功能模块

使用功能模块构建 Angular 项目:

src  
│  
├── app  
│   ├── orders  
│   │   ├── create-order  
│   │   │   ├── create-order.component.ts  
│   │   │   ├── create-order.service.ts  
│   │   │   ├── create-order.component.html  
│   │   │   └── create-order.component.css  
│   │   └── get-order  
│   │       ├── get-order.component.ts  
│   │       ├── get-order.service.ts  
│   │       ├── get-order.component.html  
│   │       └── get-order.component.css  
│   └── customers  
│       ├── create-customer  
│       │   ├── create-customer.component.ts  
│       │   ├── create-customer.service.ts  
│       │   ├── create-customer.component.html  
│       │   └── create-customer.component.css  
│       └── get-customer  
│           ├── get-customer.component.ts  
│           ├── get-customer.service.ts  
│           ├── get-customer.component.html  
│           └── get-customer.component.css

示例:Azure 函数应用

按功能构建 Azure 函数应用:

FunctionApp  
│  
├── Orders  
│   ├── CreateOrder  
│   │   ├── index.js  
│   │   └── function.json  
│   └── GetOrder  
│       ├── index.js  
│       └── function.json  
└── Customers  
    ├── CreateCustomer  
    │   ├── index.js  
    │   └── function.json  
    └── GetCustomer  
        ├── index.js  
        └── function.json

传统分层架构与垂直切片架构

传统分层架构

结构:

  • 根据技术问题将应用程序划分为水平层。

  • 典型的层包括表示、业务逻辑和数据访问。

凝聚力:

  • 由于相关代码分散在多个层中,因此功能内的内聚力较低。

  • 层内凝聚力高,但不一定跨要素。

依赖关系:

  • 层以分层方式相互依赖。

  • 较低层(例如,数据访问)的变化可能会对较高层(例如,演示)产生连锁反应。

功能开发:

  • 需要接触多个图层才能实现单个功能。

  • 由于跨层变化,开发速度较慢。

可扩展性:

  • 水平缩放需要复制整个图层。

  • 更难独立扩展特定功能。

保养:

  • 维护起来更具挑战性,因为更改通常需要跨多个层进行更新。

  • 由于特征逻辑的分散,调试可能很复杂。

测试:

  • 单元测试侧重于单个层,因此集成测试对于整体验证至关重要。

  • 更复杂的测试设置,以确保所有层都能正常工作。

垂直切片架构

结构:

  • 根据功能将应用程序划分为垂直切片。

  • 每个切片都包含自己的 Presentation、Business Logic 和 Data Access 组件。

凝聚力:

  • 由于所有相关代码都位于一起,因此每个功能切片内具有很高的内聚力。

  • 每个切片独立运行。

依赖关系:

  • 功能彼此独立。

  • 一个要素切片中的更改对其他要素切片的影响最小。

功能开发:

  • 开发速度更快,因为每个功能都可以独立实现。

  • 开发人员可以一次专注于一个切片,而不必担心应用程序的其他部分。

可扩展性:

  • 更轻松地独立扩展特定功能。

  • 每个功能都可以根据需要进行部署和扩展,而不会影响其他功能。

保养:

  • 由于更改在要素切片中本地化,因此更易于维护。

  • 由于所有相关代码都包含在切片中,因此简化了调试。

测试:

  • 单元测试侧重于单个功能切片,从而可以更轻松地隔离和测试功能。

  • 集成测试更直接,因为每个切片都是一个完整的功能。

总结

  • 传统的分层架构适用于较小的应用程序,或者当保持严格的关注点分离至关重要时,但随着应用程序的增长,它可能会导致开发和维护挑战变慢。

  • 垂直切片架构非常适合功能独立性、开发速度更快、更易于维护的大型复杂应用程序。它与微服务和领域驱动设计等现代开发实践非常吻合。

  • 如果你喜欢我的文章,请给我一个赞!谢谢

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值