C#分层架构

一、核心分层补充:BLL 层(业务逻辑层)

在原有分层基础上,BLL 层(Business Logic Layer) 是连接 UI 层与 DAL 层的核心中间层,负责处理核心业务逻辑,是分层架构中 "业务规则的执行者"。

  • 核心职责

    • 接收 UI 层的请求,结合业务规则处理数据(如数据校验、权限判断、流程控制等);

    • 调用 DAL 层获取或存储数据,不直接与数据库交互;

    • 将处理结果返回给 UI 层(通常以 Model 层实体为载体)。

  • 示例场景

    • 用户注册时,BLL 层验证 "用户名格式"、"密码强度"、"是否重复注册" 等业务规则,再调用 UserDAL 执行插入操作;

    • 订单提交时,BLL 层处理 "库存扣减"、"金额计算"、"事务管理(确保库存和订单操作同时成功或失败)" 等逻辑。

二、各层依赖关系与引用规则

分层架构的核心原则是 "上层依赖下层,下层不依赖上层",具体引用关系如下:

层级 可引用的层级 不可直接引用的层级 说明
UI 层 BLL 层、Model 层 DAL 层、IDAL 层 UI 仅通过 BLL 获取数据,不直接操作数据库
BLL 层 IDAL 层、Model 层 UI 层、DAL 层 BLL 依赖抽象接口(IDAL),不依赖具体实现
DAL 层 Model 层、IDAL 层(实现接口) UI 层、BLL 层 DAL 是 IDAL 接口的具体实现
IDAL 层 Model 层 UI 层、BLL 层、DAL 层 接口层仅定义规则,不依赖任何实现
Model 层 无(独立) 所有其他层 实体类是各层数据传递的 "载体"

目的:通过严格的依赖规则实现 "松耦合",例如更换数据库时(如从 MySQL 改为 SQL Server),只需修改 DAL 层实现,BLL 和 UI 层无需变动。

三、IDAL 层与工厂模式(Factory)的配合

IDAL 层的核心价值在于 "依赖抽象而非具体",而工厂模式是实现这一目标的关键手段:

  • 工厂模式作用:创建 DAL 层实例的 "中间件",使 BLL 层无需知道具体 DAL 类(如 UserDAL),只需通过工厂获取 IDAL 接口实例。

  • 实现示例

    复制代码
    // 工厂类(Factory)
    public class DALFactory {
        // 根据接口类型创建对应DAL实例
        public static IUser CreateUserDAL() {
            return new UserDAL(); // 若更换数据库,只需修改此处为NewUserDAL()
        }
        
        public static IProduct CreateProductDAL() {
            return new ProductDAL();
        }
    }
    ​
    // BLL层调用方式(无需直接引用DAL)
    public class UserBLL {
        private IUser userDAL = DALFactory.CreateUserDAL(); // 依赖抽象接口
        
        public void AddUser(User user) {
            // 业务逻辑校验
            if (string.IsNullOrEmpty(user.Account)) {
                throw new Exception("用户名不能为空");
            }
            userDAL.Add(user); // 调用接口方法
        }
    }
  • 优势 :当 DAL 层实现变化时(如从UserDAL改为UserDAL_MySQL),只需修改工厂类,无需改动 BLL 和 UI 层,符合 "开闭原则"。

四、Model 层的扩展:实体分类

Model 层不仅包含数据库映射实体,还可根据需求细分为:

  1. 实体类(Entity)

    • 与数据库表一一映射(如User对应Users表,Product对应Products表);

    • 字段与表结构一致,用于 DAL 层与数据库的交互。

  2. 视图模型(ViewModel)

    • 为 UI 层展示定制的数据模型,可能包含多个实体的组合数据;

    • 示例:UserDetailViewModel包含User的基本信息 +Order的统计数据,供用户详情页展示。

  3. 数据传输对象(DTO)

    • 用于跨层(尤其是分布式系统中)传输数据,可剔除敏感字段(如密码);

    • 示例:UserDTO仅包含IdAccountNickName,用于 API 接口返回。

五、DAL 层的实现细节

DAL 层作为数据访问的 "执行者",需关注以下技术点:

  • 数据库操作方式

    • 原生 SQL:通过SqlConnectionSqlCommand执行 SQL 语句(灵活性高,适合复杂查询);

    • ORM 框架:如 Entity Framework(EF)、Dapper,通过对象关系映射简化操作(开发效率高);

    • 示例(Dapper 实现):

      复制代码
      public class UserDAL : IUser {
          private string _connStr = "数据库连接字符串";
          
          public User GetModel(int id) {
              using (var conn = new SqlConnection(_connStr)) {
                  return conn.QueryFirstOrDefault<User>(
                      "SELECT * FROM Users WHERE Id = @Id", 
                      new { Id = id }
                  );
              }
          }
      }
  • 连接管理

    • 必须使用using语句或手动释放数据库连接,避免资源泄露;

    • 连接字符串应存储在配置文件(如App.config)中,而非硬编码。

六、通用层(Common):跨层工具集

为避免代码重复,可新增Common 层(类库),提供各层通用的功能:

  • 包含内容

    • 工具类:如StringHelper(字符串处理)、DateTimeHelper(日期转换);

    • 常量定义:如DBConst(数据库表名)、ErrorMsg(错误提示);

    • 异常处理:自定义异常类(如BusinessException)、异常日志工具;

    • 配置管理:读取配置文件的工具类。

  • 引用规则:所有其他层均可引用 Common 层,Common 层不依赖任何其他层。

七、分层架构的测试策略

分层架构的低耦合特性,使其易于单元测试:

  • UI 层:通过 UI 自动化测试框架(如 Selenium)测试用户交互;

  • BLL 层:使用单元测试框架(如 xUnit、NUnit),通过 Mock 工具(如 Moq)模拟 IDAL 接口的返回结果,无需依赖真实数据库;

    复制代码
    // 测试UserBLL的AddUser方法(模拟IUser接口)
    [Test]
    public void AddUser_WhenAccountEmpty_ThrowException() {
        // 模拟IUser接口(不执行真实数据库操作)
        var mockUserDAL = new Mock<IUser>();
        var userBLL = new UserBLL(mockUserDAL.Object);
        
        // 测试逻辑
        var user = new User { Account = "" };
        Assert.Throws<Exception>(() => userBLL.AddUser(user));
    }
  • DAL 层:通过集成测试验证数据库操作的正确性(需连接测试数据库)。

八、命名规范与项目结构

为保证代码可读性,各层类 / 方法命名需遵循统一规范:

层级 命名规则示例 说明
UI 层 UserFormProductPage 窗体 / 页面以功能 + 类型命名
BLL 层 UserBLLOrderBLL 以实体名 + BLL 结尾
DAL 层 UserDALProductDAL 以实体名 + DAL 结尾
IDAL 层 IUserIProduct 接口以 I + 实体名开头
Model 层 UserProductUserDTO 实体类直接用业务名称
方法 AddUserGetProductById 动词 + 实体 + 操作(如 Add、Get)

九、分层架构的适用场景与挑战

  • 适用场景

    • 中大型项目(团队协作、业务复杂);

    • 需长期维护、可能频繁变更需求的项目;

    • 需支持多数据库、多 UI(如同时有 WinForm 和 Web 界面)的项目。

  • 潜在挑战

    • 小型项目可能因 "过度设计" 增加开发成本;

    • 层次过多可能导致性能轻微损耗(可通过优化减少);

    • 团队需严格遵守分层规范,否则可能出现 "层间越权"(如 UI 直接调用 DAL)。

十、C# 分层架构各层信息汇总表

层级 英文全称 类型 核心职责 依赖层级 典型命名示例 技术要点
UI 层 User Interface 应用程序 展示数据、接收用户输入、调用 BLL 层处理请求 BLL 层、Model 层 UserForm.cs、ProductPage.xaml 界面控件绑定、用户交互逻辑、数据展示格式化
BLL 层 Business Logic Layer 类库 处理业务规则(校验、权限、流程)、协调 DAL 层数据操作、返回结果给 UI 层 IDAL 层、Model 层、Common 层 UserBLL.cs、OrderBLL.cs 事务管理、业务规则验证、依赖注入(通过接口调用 DAL)
IDAL 层 Interface Data Access Layer 类库 定义数据访问接口规范,统一 DAL 层方法名称和参数 Model 层 IUser.cs、IProduct.cs 接口继承(IBase)、方法签名标准化、不包含具体实现
DAL 层 Data Access Layer 类库 实现 IDAL 接口,直接与数据库交互(CRUD 操作) Model 层、IDAL 层、Common 层 UserDAL.cs、ProductDAL.cs 数据库连接管理、ORM 框架(EF/Dapper)、SQL 语句优化
Model 层 Model 类库 定义数据实体,作为各层数据传递的载体 无(独立) User.cs(实体)、UserDTO.cs(传输对象) 实体与数据库表映射、数据注解(验证规则)、敏感字段过滤(DTO)
Common 层 Common 类库 提供跨层通用工具和常量 无(被所有层引用) StringHelper.cs、DBConst.cs 工具类封装、异常处理、配置文件读取、日志记录

十一、C# 分层架构树状图(项目结构)

复制代码
项目根目录/
├── UI/                      // 用户界面层
│   ├── Forms/               // 窗体文件(WinForm)
│   │   ├── UserForm.cs      // 用户管理窗体
│   │   └── ProductForm.cs   // 商品管理窗体
│   ├── Pages/               // 页面文件(WPF/ASP.NET)
│   │   └── HomePage.xaml    // 首页页面
│   └── Program.cs           // 程序入口
│
├── BLL/                     // 业务逻辑层
│   ├── UserBLL.cs           // 用户业务逻辑处理
│   ├── ProductBLL.cs        // 商品业务逻辑处理
│   └── OrderBLL.cs          // 订单业务逻辑处理
│
├── IDAL/                    // 数据访问接口层
│   ├── IBase.cs             // 基础接口(通用方法)
│   ├── IUser.cs             // 用户数据访问接口
│   ├── IProduct.cs          // 商品数据访问接口
│   └── DALFactory.cs        // 数据访问层工厂类
│
├── DAL/                     // 数据访问层
│   ├── UserDAL.cs           // 用户数据访问实现
│   ├── ProductDAL.cs        // 商品数据访问实现
│   └── DBHelper.cs          // 数据库连接辅助类
│
├── Model/                   // 实体模型层
│   ├── Entity/              // 数据库实体类
│   │   ├── User.cs          // 用户实体
│   │   └── Product.cs       // 商品实体
│   ├── DTO/                 // 数据传输对象
│   │   └── UserDTO.cs       // 用户传输对象
│   └── ViewModel/           // 视图模型
│       └── ProductViewModel.cs // 商品视图模型
│
└── Common/                  // 通用工具层
    ├── Helper/              // 工具类
    │   ├── StringHelper.cs  // 字符串处理工具
    │   └── DateTimeHelper.cs // 日期时间工具
    ├── Const/               // 常量定义
    │   └── DBConst.cs       // 数据库相关常量
    └── Exception/           // 异常处理
        └── BusinessException.cs // 业务异常类

树状图说明:

  1. 各层以独立类库 / 项目存在,通过 "项目引用" 建立依赖关系

  2. 箭头方向为依赖方向(如 UI 层引用 BLL 层,BLL 层引用 IDAL 层)

  3. 工厂类(DALFactory)通常放在 IDAL 层或单独的 Factory 层,负责创建 DAL 实例,解除 BLL 与 DAL 的直接依赖

相关推荐
学习编程的gas1 分钟前
C++:STL中list的使用和模拟实现
开发语言·c++
今晚打老虎19 分钟前
c++之基础B(第一课)
开发语言·c++
wa的一声哭了20 分钟前
Python多进程并行multiprocess基础
开发语言·jvm·人工智能·python·机器学习·语言模型·自然语言处理
枫叶丹434 分钟前
【Qt开发】信号与槽(三)-> 自定义信号和槽
开发语言·qt
奔跑吧邓邓子44 分钟前
从0到1学PHP(三):PHP 流程控制:掌控程序的走向
开发语言·php·流程控制
R-G-B1 小时前
【31】C# WinForm入门到精通 ——保存文件SaveFileDialog 【属性、方法、事件、实例、源码】
开发语言·c#·c# winform·c#保存文件·savefiledialog
啊阿狸不会拉杆1 小时前
《Java 程序设计》第 11 章 - 泛型与集合
java·开发语言·jvm·数据结构·算法
cui_win1 小时前
Prometheus实战教程 01 - Prometheus 简介和架构
架构·prometheus
小白要加油努力2 小时前
C++-STL-String重点知识
开发语言·c++
恣艺2 小时前
LeetCode 68:文本左右对齐
算法·leetcode·c#