翼度科技»论坛 编程开发 .net 查看内容

六边形架构简介

9

主题

9

帖子

27

积分

新手上路

Rank: 1

积分
27
六边形架构简介

在这本综合指南中,我们将引导您了解有关此强大架构模式的所有信息。我们将介绍基本和核心概念、使用六边形架构的好处、实际示例、测试以及最后的常见问题解答部分,如果您还有其他疑问!
最后,您不仅将了解 Hexagonal Architecture,而且还可以在 C# 项目中实现它。让我们开始吧!
什么是六边形架构?

六边形体系结构,也称为端口和适配器,是一种促进关注点分离的体系结构模式。它旨在通过将核心逻辑与外部系统隔离,使您的应用程序更易于维护和更灵活。
使用六边形架构的好处

为什么要关心六边形架构?以下是一些令人信服的原因:

  • 改进的可维护性:通过明确区分核心逻辑和外部系统,您的代码变得更易于管理。
  • 提高可测试性:隔离的组件使编写单元测试变得更加容易。
  • 增强的灵活性:切换外部系统(例如数据库)变得轻而易举。
六边形架构的核心概念

在接下来的章节中,我们将分解六边形架构的构建块。您将对端口和适配器、依赖项注入和关注点分离有深入的了解。
探索的端口和适配器

六边形架构的核心是端口和适配器。但它们到底是什么?让我们来分解一下。
端口是定义应用程序可以执行的操作的接口。将它们视为应用程序的“内容”。
适配器是这些接口的实现。他们负责“如何”——如何执行端口定义的操作。
下面是 C# 中的一个简单的示例:
  1. 1 // Port: An interface defining a service
  2. 2 public interface IFileStorage
  3. 3 {
  4. 4     void SaveFile(string fileName, byte[] data);
  5. 5 }
  6. 6
  7. 7 // Adapter: An implementation of the interface
  8. 8 public class LocalFileStorage : IFileStorage
  9. 9 {
  10. 10     public void SaveFile(string fileName, byte[] data)
  11. 11     {
  12. 12         // Saving file locally
  13. 13         System.IO.File.WriteAllBytes(fileName, data);
  14. 14     }
  15. 15 }
  16. 16  
复制代码
 
在此示例中,是端口,是适配器。IFileStorageLocalFileStorage
依赖注入的作用

依赖注入 (DI) 是六边形架构中的关键参与者。它使我们能够在不改变核心逻辑的情况下轻松更换适配器。把它想象成一种即插即用的机制。
下面介绍如何在 C# 项目中设置 DI:
  1. // Configure Dependency Injection in Startup.cs
  2. public void ConfigureServices(IServiceCollection services)
  3. {
  4.     // Register the IFileStorage interface with its implementation
  5.     services.AddTransient<IFileStorage, LocalFileStorage>();
  6. }
复制代码
 
 使用 DI,您可以从 .LocalFileStorageAzureFileStorage
  1. services.AddTransient<IFileStorage, AzureFileStorage>();
复制代码
 
 关注点分离

六边形架构通过将核心逻辑与外部系统解耦来强制执行关注点分离。这不仅使您的代码更简洁,而且更健壮。想象一下,在不破坏奥利奥的情况下分离出美味的馅料。有了六边形架构,这成为可能。
在 C 语言中实现六边形架构

在本节中,我们将深入探讨如何使用 Hexagonal Architecture 设置 C# 项目。
设置 C# 项目

让我们从设置 C# 项目结构开始。通常有三个主要层:

  • 核心:包含核心业务逻辑和端口(接口)。
  • 基础结构:容纳适配器(端口的实现)。
  • UI:处理用户界面并通过端口与内核进行交互。
您的解决方案可能如下所示:
  1. /Solution
  2.   /Core
  3.     /Interfaces
  4.   /Infrastructure
  5.   /UI
复制代码
 
定义接口(端口)

让我们在核心层定义几个接口。这些将充当我们的端口。
  1. // IFileStorage.cs
  2. public interface IFileStorage
  3. {
  4.     void SaveFile(string fileName, byte[] data);
  5. }
  6. // IUserRepository.cs
  7. public interface IUserRepository
  8. {
  9.     User GetUserById(int id);
  10.     void SaveUser(User user);
  11. }
复制代码
 
 实现适配器

接下来,我们在基础结构层中创建适配器类。
  1. // LocalFileStorage.cs
  2. public class LocalFileStorage : IFileStorage
  3. {
  4.     public void SaveFile(string fileName, byte[] data)
  5.     {
  6.         System.IO.File.WriteAllBytes(fileName, data);
  7.     }
  8. }
  9. // DatabaseUserRepository.cs
  10. public class DatabaseUserRepository : IUserRepository
  11. {
  12.     private readonly List<User> _users = new List<User>();
  13.     public User GetUserById(int id)
  14.     {
  15.         return _users.FirstOrDefault(u => u.Id == id);
  16.     }
  17.     public void SaveUser(User user)
  18.     {
  19.         _users.Add(user);
  20.     }
  21. }
复制代码
 
为六边形体系结构构建 C# 项目

到现在为止,您应该有一个清晰的结构。解决方案应如下所示:
  1. /Solution
  2.   /Core
  3.     /Interfaces
  4.       IFileStorage.cs
  5.       IUserRepository.cs
  6.   /Infrastructure
  7.     LocalFileStorage.cs
  8.     DatabaseUserRepository.cs
  9.   /UI
  10.     // Your application logic and UI
复制代码
 
这种结构使一切保持整洁有序,使其易于导航和维护。
实例

在 C 语言中使用 Hexagonal Architecture 构建一个简单的应用程序

让我们构建一个使用 Hexagonal Architecture 保存用户数据的基本应用程序。
步骤 1:定义核心逻辑
  1. // User.cs in Core layer
  2. public class User
  3. {
  4.     public int Id { get; set; }
  5.     public string Name { get; set; }
  6. }
复制代码
 
步骤 2:在基础架构中实施存储库
  1. // DatabaseUserRepository.cs
  2. public class DatabaseUserRepository : IUserRepository
  3. {
  4.     private readonly List<User> _users = new List<User>();
  5.     public User GetUserById(int id)
  6.     {
  7.         return _users.FirstOrDefault(u => u.Id == id);
  8.     }
  9.     public void SaveUser(User user)
  10.     {
  11.         _users.Add(user);
  12.     }
  13. }
复制代码
 
 步骤 3:在核心中创建服务
  1. // UserService.cs
  2. public class UserService
  3. {
  4.     private readonly IUserRepository _userRepository;
  5.     public UserService(IUserRepository userRepository)
  6.     {
  7.         _userRepository = userRepository;
  8.     }
  9.     public void AddUser(User user)
  10.     {
  11.         _userRepository.SaveUser(user);
  12.     }
  13.     public User GetUser(int id)
  14.     {
  15.         return _userRepository.GetUserById(id);
  16.     }
  17. }
复制代码
 
第 4 步:与 UI 集成

最后,将服务与简单的 UI 集成。
  1. // Program.cs in UIclass Program{    static void Main(string[] args)    {        // Setup Dependency Injection        var services = new ServiceCollection();        services.AddTransient<IFileStorage, AzureFileStorage>();        services.AddTransient<IFileStorage, AzureFileStorage>();        var serviceProvider = services.BuildServiceProvider();        // Get UserService        var userService = serviceProvider.GetService();        // Add a user        var user = new User { Id = 1, Name = "John Doe" };        userService.AddUser(user);        // Retrieve the user        var retrievedUser = userService.GetUser(1);        Console.WriteLine($"User retrieved: {retrievedUser.Name}");    }}
复制代码
 
在上面的示例中,UI 层中的类与 from Core 层交互,而 from Core 层又使用 from Infrastructure 层。Program UserService IUserRepository
真实世界的用例

六边形架构具有高度的通用性,可以应用于各种类型的项目,从简单的控制台应用程序到复杂的企业系统。无论您是在构建电子商务平台、网上银行应用程序还是社交网络,Hexagonal Architecture 都可以帮助您保持代码库的整洁和可维护性。
传统架构的迁移策略

如果您使用的是遗留系统,则迁移到六边形架构似乎很困难。但别担心,这里有一个简单的策略:

  • 确定核心逻辑:首先确定应用程序的核心逻辑。
  • 定义端口:为已识别的逻辑创建接口。
  • 创建适配器:将接口实现为适配器。
  • 渐进式重构:逐步重构系统,用抽象代替直接依赖关系。
这种增量方法可帮助您采用六边形架构,而不会造成重大中断。
六边形架构测试

Hexagonal Architecture 的最大优势之一是增强了可测试性。在本节中,我们将探讨不同类型的测试。
单元测试

单元测试侧重于单个组件。下面是一个测试:UserService
  1. // UserServiceTests.cs
  2. using Moq;
  3. public class UserServiceTests
  4. {
  5.     [Fact]
  6.     public void AddUser_ShouldSaveUser()
  7.     {
  8.         // Arrange
  9.         var userRepositoryMock = new Mock<IUserRepository>();
  10.         var userService = new UserService(userRepositoryMock.Object);
  11.         var user = new User { Id = 1, Name = "Jane Doe" };
  12.         // Act
  13.         userService.AddUser(user);
  14.         // Assert
  15.         userRepositoryMock.Verify(r => r.SaveUser(user), Times.Once);
  16.     }
  17. }
复制代码
 
 集成测试

集成测试验证不同组件之间的交互。下面是一个示例:
  1. // UserIntegrationTests.cspublic class UserIntegrationTests{    private ServiceProvider serviceProvider;    public UserIntegrationTests()    {        // Setup Dependency Injection        var services = new ServiceCollection();        services.AddTransient<IFileStorage, AzureFileStorage>();        services.AddTransient<IFileStorage, AzureFileStorage>();        serviceProvider = services.BuildServiceProvider();    }    [Fact]    public void UserService_ShouldRetrieveSavedUser()    {        // Arrange        var userService = serviceProvider.GetService();        var user = new User { Id = 1, Name = "John Doe" };        userService.AddUser(user);        // Act        var retrievedUser = userService.GetUser(1);        // Assert        Assert.Equal("John Doe", retrievedUser.Name);    }}
复制代码
 
端到端测试

端到端 (E2E) 测试对整个系统进行评估。它们模拟真实的用户交互,并确保整个应用程序按预期工作。
最佳实践和常见陷阱

在这里,我们将分享一些在 C# 中实现六边形体系结构时要避免的最佳实践和常见错误。
C# 六边形体系结构的最佳实践


  • 保持简单:不要过度设计。从简单的结构开始,并根据需要进行优化。
  • 使用依赖注入:善用 DI 管理依赖。
  • 编写测试:彻底测试核心逻辑和适配器。
常见陷阱以及如何避免它们


  • 使设计过于复杂:避免创建过多的层和抽象。保持直截了当。
  • 忽略测试:跳过测试可能会导致错误和难以维护的代码。定期编写测试。
  • 忽略性能:确保您的设计不会引入性能瓶颈。
性能注意事项

要保持应用程序的性能,请执行以下操作:

  • 最小化跳层:层数过多会降低应用程序速度。保持图层最小且集中。
  • 优化数据访问:使用高效的数据访问模式和数据库。
结论

到现在为止,您应该对六边形体系结构、其优点以及如何在 C# 中实现它有深入的了解。准备好彻底改变您的编码实践了吗?
关键要点回顾


  • 六边形架构将核心逻辑与外部系统分开。
  • 端口(接口)和适配器(实现)是关键组件。
  • 依赖注入对于灵活性至关重要。
  • 使用 Hexagonal Architecture,测试变得轻而易举。

来源:https://www.cnblogs.com/BitchFace/p/18257906
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具