化对象,部分设计中命名为 DO(Data Object),常作用于三层中的 dao 层。 ()BO (Business Object ...
化对象DO与BO在三层架构中的实战应用引言对象分层设计的必要性在企业级应用开发中我们经常听到“贫血模型”和“充血模型”的争论。但无论采用哪种模型对象的分层设计都是不可避免的。DOData Object和BOBusiness Object是两种常见的对象类型分别服务于数据访问层DAO层和业务逻辑层。本文将通过大量代码演示展示如何在实战中合理使用这两种对象避免代码混乱。—## 1. DOData Object数据层的忠实映射### 1.1 DO的核心职责DO直接映射数据库表结构通常与表的字段一一对应。它不包含业务逻辑只负责承载数据。在三层架构中DO主要用于DAO层与数据库交互。### 1.2 实战场景用户管理系统假设我们有一个用户表users包含以下字段- id (BIGINT)- username (VARCHAR)- password_hash (VARCHAR)- email (VARCHAR)- created_at (TIMESTAMP)- updated_at (TIMESTAMP)#### 定义DO对象Python示例python# user_do.pyfrom datetime import datetimefrom dataclasses import dataclassdataclassclass UserDO: 用户数据对象直接映射数据库表 users id: int username: str password_hash: str # 注意这是哈希值不是明文密码 email: str created_at: datetime updated_at: datetime # 注意DO中不包含业务方法如密码验证、邮箱格式检查等#### DAO层使用DOpython# user_dao.pyimport sqlite3from user_do import UserDOclass UserDAO: 数据访问对象使用DO进行数据库操作 def __init__(self, db_path: str): self.conn sqlite3.connect(db_path) self._create_table() def _create_table(self): 创建示例表生产环境请使用迁移工具 self.conn.execute( CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL UNIQUE, password_hash TEXT NOT NULL, email TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ) self.conn.commit() def find_by_id(self, user_id: int) - UserDO | None: 根据ID查询用户返回DO对象 cursor self.conn.execute( SELECT id, username, password_hash, email, created_at, updated_at FROM users WHERE id ?, (user_id,) ) row cursor.fetchone() if row: return UserDO( idrow[0], usernamerow[1], password_hashrow[2], emailrow[3], created_atrow[4], updated_atrow[5] ) return None def save(self, user: UserDO) - int: 保存用户DO到数据库 cursor self.conn.execute( INSERT INTO users (username, password_hash, email) VALUES (?, ?, ?), (user.username, user.password_hash, user.email) ) self.conn.commit() return cursor.lastrowid关键点DO直接与数据库字段对应不包含密码验证、邮箱格式化等业务逻辑。—## 2. BOBusiness Object业务逻辑的载体### 2.1 BO的核心职责BO代表业务对象它封装了业务规则和逻辑。一个BO可能由多个DO组合而成也可能对DO进行转换和增强。BO通常用于Service层是业务操作的主要对象。### 2.2 实战场景用户注册业务继续使用上面的用户管理系统现在我们需要实现用户注册功能。注册时需要进行- 密码加密- 邮箱格式验证- 用户名唯一性检查- 创建用户时自动设置时间戳#### 定义BO对象python# user_bo.pyimport reimport hashlibfrom datetime import datetimefrom dataclasses import dataclass, fielddataclassclass UserBO: 用户业务对象包含业务规则 id: int 0 username: str password: str # 明文密码仅在创建时使用 email: str created_at: datetime field(default_factorydatetime.now) updated_at: datetime field(default_factorydatetime.now) # 业务方法验证密码强度 def validate_password(self) - bool: 密码必须包含大小写字母和数字长度8-20位 pattern r^(?.*[a-z])(?.*[A-Z])(?.*\d)[a-zA-Z\d]{8,20}$ return bool(re.match(pattern, self.password)) # 业务方法加密密码 def hash_password(self) - str: 使用SHA-256进行密码哈希 return hashlib.sha256(self.password.encode()).hexdigest() # 业务方法验证邮箱格式 def validate_email(self) - bool: 简单的邮箱格式验证 pattern r^[a-zA-Z0-9._%-][a-zA-Z0-9.-]\.[a-zA-Z]{2,}$ return bool(re.match(pattern, self.email)) # 业务方法转换为DO用于持久化 def to_do(self) - UserDO: 将BO转换为DO注意密码字段的转换 from user_do import UserDO return UserDO( idself.id, usernameself.username, password_hashself.hash_password(), # 加密后存入DO emailself.email, created_atself.created_at, updated_atself.updated_at )#### Service层使用BOpython# user_service.pyfrom user_dao import UserDAOfrom user_bo import UserBOclass UserService: 用户业务服务使用BO进行业务操作 def __init__(self, dao: UserDAO): self.dao dao def register_user(self, username: str, password: str, email: str) - UserBO: 用户注册业务返回业务对象 # 1. 创建BO并验证业务规则 user_bo UserBO(usernameusername, passwordpassword, emailemail) if not user_bo.validate_password(): raise ValueError(密码不符合要求需要8-20位包含大小写字母和数字) if not user_bo.validate_email(): raise ValueError(邮箱格式不正确) # 2. 检查用户名唯一性通过DAO查询DO existing_user self.dao.find_by_username(username) if existing_user: raise ValueError(f用户名 {username} 已被占用) # 3. 转换为DO并保存 user_do user_bo.to_do() new_id self.dao.save(user_do) # 4. 返回包含新ID的BO user_bo.id new_id return user_bo def get_user_profile(self, user_id: int) - UserBO | None: 获取用户信息从DO转换为BO user_do self.dao.find_by_id(user_id) if user_do: # 注意从数据库读取时密码是哈希值不能直接赋值给BO的password return UserBO( iduser_do.id, usernameuser_do.username, emailuser_do.email, created_atuser_do.created_at, updated_atuser_do.updated_at ) return None关键点- BO包含业务验证方法validate_password、validate_email- BO负责加密逻辑hash_password- BO提供to_do()方法转换为DO- 从数据库读取时DO转换为BO时隐藏敏感字段如密码哈希—## 3. DO与BO的转换实战### 3.1 完整运行示例下面是一个完整的运行示例展示DO和BO如何协同工作python# main.pyfrom user_dao import UserDAOfrom user_service import UserServicefrom user_bo import UserBOdef main(): # 初始化 dao UserDAO(:memory:) # 使用内存数据库方便测试 service UserService(dao) # 1. 注册新用户业务层 print( 用户注册 ) try: new_user service.register_user( usernameAlice, passwordAbc12345, # 符合规则 emailaliceexample.com ) print(f注册成功用户ID: {new_user.id}) print(f用户名: {new_user.username}) print(f邮箱: {new_user.email}) print(f创建时间: {new_user.created_at}) except ValueError as e: print(f注册失败: {e}) # 2. 尝试注册一个密码不达标的用户 print(\n 尝试注册弱密码用户 ) try: service.register_user( usernameBob, password123, # 太短不符合规则 emailbobtest.com ) except ValueError as e: print(f预期错误: {e}) # 3. 查询用户信息数据层 print(\n 查询用户 ) user service.get_user_profile(1) if user: print(f查询到用户: {user.username}) # 注意查询返回的BO不包含密码字段 print(f密码字段为空: {user.password }) # 输出True # 4. 直接通过DAO查看存储的DO仅用于调试 print(\n 数据库中的原始DO ) user_do dao.find_by_id(1) if user_do: print(fDO中的密码哈希: {user_do.password_hash[:20]}...) # 显示哈希值的一部分 print(fDO中的明文密码: 不存在) # DO不存储明文if __name__ __main__: main()运行结果 用户注册 注册成功用户ID: 1用户名: Alice邮箱: aliceexample.com创建时间: 2024-01-15 10:30:00.123456 尝试注册弱密码用户 预期错误: 密码不符合要求需要8-20位包含大小写字母和数字 查询用户 查询到用户: Alice密码字段为空: True 数据库中的原始DO DO中的密码哈希: e3b0c44298fc1c149afb...DO中的明文密码: 不存在—## 4. 分层设计的最佳实践### 4.1 转换时机-写入数据库BO → DOService层调用to_do()-读取数据库DO → BOService层手动转换-跨服务调用使用DTO数据传输对象进行转换### 4.2 常见陷阱1.混淆职责不要在DO中添加业务方法2.过度转换如果不涉及业务逻辑可以直接使用DO3.循环依赖BO和DO的相互引用容易导致循环依赖### 4.3 扩展建议- 对于复杂场景可以引入Assembler类专门处理转换- 使用DTOData Transfer Object隔离DO和BO- 考虑使用MapStruct等工具自动生成转换代码—## 总结通过本文的实战演示我们可以看到-DO是数据层的忠实映射专注于数据持久化不应包含业务逻辑-BO是业务层的核心封装了业务规则和验证逻辑- 两者通过明确的转换方法如to_do()进行解耦在三层架构中合理使用DO和BO可以显著提升代码的可维护性和可测试性。记住一个核心原则DO负责“是什么”BO负责“怎么做”。这种分层思想不仅适用于Python也同样适用于Java、C#等语言。最后建议在项目中统一命名规范例如使用*DO后缀表示数据对象*BO后缀表示业务对象让团队成员一目了然。

相关新闻

浏览器隐私防护革命:为什么uBlock Origin能让你重新掌控网络体验?

浏览器隐私防护革命:为什么uBlock Origin能让你重新掌控网络体验?

浏览器隐私防护革命:为什么uBlock Origin能让你重新掌控网络体验? 【免费下载链接】uBlock uBlock Origin - An efficient blocker for Chromium and Firefox. Fast and lean. 项目地址: https://gitcode.com/GitHub_Trending/ub/uBlock 你是否曾…

2026/7/27 19:04:03 阅读更多 →
uni-app项目Tabbar实现切换icon动效

uni-app项目Tabbar实现切换icon动效

uni-app项目Tabbar实现切换icon动效 在移动应用开发中,Tabbar(底部导航栏)是用户交互的核心组件之一。当用户切换Tab时,如果只是静态地改变图标和文字,体验会显得生硬。通过为Tabbar的图标添加切换动效(如…

2026/7/27 19:04:03 阅读更多 →
Pinokio智能启动器:一键部署任何开源项目,彻底告别复杂配置的终极解决方案

Pinokio智能启动器:一键部署任何开源项目,彻底告别复杂配置的终极解决方案

Pinokio智能启动器:一键部署任何开源项目,彻底告别复杂配置的终极解决方案 【免费下载链接】pinokio AI Browser 项目地址: https://gitcode.com/gh_mirrors/pi/pinokio 还在为繁琐的开源项目部署而烦恼吗?想象一下,你发现…

2026/7/27 19:04:03 阅读更多 →

最新新闻

【AI量化交易实战】第04讲:小晴(情报官)上岗——搭建本地数据管道与清洗流水线

【AI量化交易实战】第04讲:小晴(情报官)上岗——搭建本地数据管道与清洗流水线

开篇导语上一讲我们搭建了Python量化开发环境,并通过akshare完成了第一次"从数据到决策"的多因子选股实验。但这里有一个隐患你可能已经察觉了:每次运行策略都需要临时从网上抓数据——慢、不稳定、不可复现。真正能打仗的量化团队&#xff0c…

2026/7/27 19:11:05 阅读更多 →
如何构建企业级自动化任务调度系统:QLScriptPublic终极实战指南

如何构建企业级自动化任务调度系统:QLScriptPublic终极实战指南

如何构建企业级自动化任务调度系统:QLScriptPublic终极实战指南 【免费下载链接】QLScriptPublic 青龙面板脚本公共仓库 企鹅交流1021185005 项目地址: https://gitcode.com/GitHub_Trending/ql/QLScriptPublic QLScriptPublic是一个基于青龙面板的开源自动化…

2026/7/27 19:11:05 阅读更多 →
技术架构深度解析:sto/stock量化交易平台的数据驱动设计范式

技术架构深度解析:sto/stock量化交易平台的数据驱动设计范式

技术架构深度解析:sto/stock量化交易平台的数据驱动设计范式 【免费下载链接】stock 30天掌握量化交易 (持续更新) 项目地址: https://gitcode.com/GitHub_Trending/sto/stock 面对金融数据碎片化与实时性挑战,传统量化系统往往陷入数据获取与策略…

2026/7/27 19:11:05 阅读更多 →
高校心理教育辅导系统全栈开发实践

高校心理教育辅导系统全栈开发实践

1. 项目概述:高校心理教育辅导系统的全栈实现这个项目是我去年为某高校心理辅导中心开发的一套完整管理系统,采用SpringBootVue的前后端分离架构。系统上线后日均处理咨询预约200人次,大幅提升了心理辅导工作效率。核心功能包括心理咨询预约、…

2026/7/27 19:11:05 阅读更多 →
HCIA第十二天-OSPF实验

HCIA第十二天-OSPF实验

HCIA第十二天-OSPF实验一、地址划分骨干链路--3段1段(需要4个地址)环回地址需要5段172.16.0.0/16172.16.0.0/241段:172.16.0.0/253段:172.16.0.128/25172.16.0.128/30 172.16.0.132/30 172.16.0.136/30环回地址:172.16…

2026/7/27 19:11:05 阅读更多 →
深度解析Deep-Live-Cam:3步实现高效实时人脸交换的完整指南

深度解析Deep-Live-Cam:3步实现高效实时人脸交换的完整指南

深度解析Deep-Live-Cam:3步实现高效实时人脸交换的完整指南 【免费下载链接】Deep-Live-Cam real time face swap and one-click video deepfake with only a single image 项目地址: https://gitcode.com/GitHub_Trending/de/Deep-Live-Cam 你是否曾想过&am…

2026/7/27 19:10:05 阅读更多 →

日新闻

【JAVA毕设源码分享】基于SpringBoot的社区智能垃圾管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

【JAVA毕设源码分享】基于SpringBoot的社区智能垃圾管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/27 0:00:54 阅读更多 →
SPI实战指南:从时钟模式到寄存器配置,解决嵌入式通信难题

SPI实战指南:从时钟模式到寄存器配置,解决嵌入式通信难题

1. 项目概述:从寄存器手册到实战指南 如果你手头有一份类似德州仪器(TI)TMS320x240xA系列DSP的SPI模块技术手册,看着里面密密麻麻的寄存器位定义、时序图和公式,是不是感觉头大?这份资料虽然权威&#xff0…

2026/7/27 0:00:54 阅读更多 →
【JAVA毕设源码分享】基于springboot的水果购物管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

【JAVA毕设源码分享】基于springboot的水果购物管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/27 0:00:54 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/27 4:33:59 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/27 6:31:56 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/27 4:01:12 阅读更多 →

月新闻