设计模式——数据访问对象模式

news/2024/11/26 11:35:51/

定义与概念

  • 数据访问对象(Data Access Object,DAO)模式是一种用于分离数据访问逻辑和业务逻辑的设计模式。它提供了一个抽象的接口,用于对数据源(如数据库、文件系统等)进行访问,使得业务逻辑层不需要直接处理底层数据存储的细节,从而提高了代码的可维护性和可扩展性。
  • 例如,在一个应用程序中,如果要从数据库中读取和写入用户信息,使用 DAO 模式可以创建一个用户数据访问对象,该对象封装了所有与数据库交互的操作(如查询用户、插入用户、更新用户信息等)。业务逻辑层(如用户管理模块)只需调用这个数据访问对象的方法,而不用关心数据库的具体类型(是关系型数据库还是非关系型数据库)、连接方式以及 SQL 语句的编写等细节。

结构组成

  • 数据访问对象接口(DAO Interface):
    它定义了访问数据的抽象方法,这些方法是业务逻辑层与数据访问层之间的契约。例如,对于用户数据访问对象,接口可能包括getUserById(int id)、addUser(User user)、updateUser(User user)等方法。这个接口使得业务逻辑层可以以一种统一的方式与不同的数据访问实现进行交互。
  • 具体数据访问对象(Concrete DAO):
    实现了数据访问对象接口,负责与实际的数据源进行交互。它包含了具体的数据访问逻辑,如数据库连接的建立、SQL 语句的执行等。以关系型数据库为例,具体的数据访问对象可能会使用数据库连接库(如 ODBC、JDBC 或 C++ 的数据库连接库)来执行 SQL 查询,以获取或修改数据。
  • 值对象(Value Object):
    也称为数据传输对象(Data Transfer Object,DTO),它是一种简单的数据结构,用于在不同层之间传递数据。在 DAO 模式中,值对象通常用于封装从数据源获取的数据或者要写入数据源的数据。例如,用户值对象可能包含用户的姓名、年龄、邮箱等属性,数据访问对象的方法通常会以值对象作为参数或者返回值。
  • 数据源(Data Source):
    这是实际存储数据的地方,如数据库、文件、网络服务等。数据访问对象与数据源进行交互,以实现数据的读取和写入操作。例如,在一个基于数据库的应用程序中,数据源就是数据库管理系统,数据访问对象通过数据库驱动程序与数据库进行连接并操作数据。

工作原理

  • 业务逻辑层需要访问数据时,它通过数据访问对象接口调用相应的方法。具体的数据访问对象接收到请求后,与数据源建立连接(如果尚未连接),然后根据请求的类型(如查询、插入、更新等)执行相应的操作。在操作过程中,可能会涉及将数据源中的数据转换为值对象,或者将值对象中的数据转换为适合数据源存储的形式。操作完成后,数据访问对象将结果(可能是一个或多个值对象,或者是表示操作成功 / 失败的状态信息)返回给业务逻辑层。
  • 例如,在一个学生成绩管理系统中,业务逻辑层需要获取某个学生的成绩信息。它调用学生成绩数据访问对象接口的getStudentGrades(int studentId)方法。具体的数据访问对象(假设使用关系型数据库)首先连接到数据库,然后执行 SQL 查询语句来获取该学生的成绩数据,将数据库中的数据行转换为学生成绩值对象,最后将值对象返回给业务逻辑层。

代码示例

以下是一个简单的 C++ 数据访问对象模式示例,用于访问一个简单的用户信息数据库(这里为了简化,假设数据存储在一个std::vector中,实际应用中可能是真正的数据库)。

  • 值对象 - 用户(User)
class User {
public:int id;std::string name;std::string email;
};
  • 数据访问对象接口 - 用户数据访问接口(UserDAOInterface)
class UserDAOInterface {
public:virtual User getUserById(int id) = 0;virtual void addUser(User user) = 0;virtual void updateUser(User user) = 0;
};
  • 具体数据访问对象 - 用户数据访问实现(UserDAOImpl)
class UserDAOImpl : public UserDAOInterface {
private:std::vector<User> users;
public:User getUserById(int id) override {for (const User& user : users) {if (user.id == id) {return user;}}// 如果未找到用户,返回一个空用户对象(这里可以根据实际情况处理)User emptyUser;return emptyUser;}void addUser(User user) override {users.push_back(user);}void updateUser(User user) override {for (User& u : users) {if (u.id == user.id) {u.name = user.name;u.email = user.email;break;}}}
};
  • 业务逻辑层使用示例(假设这是一个用户管理模块)
class UserManager {
private:UserDAOInterface* userDAO;
public:UserManager(UserDAOInterface* dao) : userDAO(dao) {}User getUser(int id) {return userDAO->getUserById(id);}void addNewUser(User user) {userDAO->addUser(user);}void updateUserInfo(User user) {userDAO->updateUser(user);}
};
  • 客户端使用示例
int main() {UserDAOImpl userDAO;UserManager manager(&userDAO);User newUser;newUser.id = 1;newUser.name = "张三";newUser.email = "zhangsan@example.com";manager.addNewUser(newUser);User retrievedUser = manager.getUser(1);std::cout << "获取用户姓名: " << retrievedUser.name << ", 邮箱: " << retrievedUser.email << std::endl;return 0;
}

优点

  • 分离关注点:
    将数据访问逻辑与业务逻辑分离,使得业务逻辑层可以专注于业务规则的实现,而数据访问层专注于数据的存储和读取。这样可以提高代码的可读性和可维护性,例如,在一个大型的企业级应用中,开发人员可以分别负责业务逻辑和数据访问逻辑,降低了代码的耦合度。
  • 可替换数据源:
    由于业务逻辑层通过数据访问对象接口与数据访问层交互,因此可以很容易地替换数据源而不影响业务逻辑层。例如,如果从关系型数据库切换到非关系型数据库,只需要实现一个新的具体数据访问对象,而业务逻辑层的代码基本不变。
  • 便于单元测试:
    业务逻辑层可以独立于数据源进行单元测试。开发人员可以使用模拟的数据访问对象来提供测试数据,从而更容易地验证业务逻辑的正确性。例如,在测试用户管理模块时,可以创建一个模拟的用户数据访问对象,返回预设的用户数据,以测试用户管理模块的各种功能。

缺点

  • 增加代码复杂度:
    引入数据访问对象模式会增加系统的层次结构和代码量。对于简单的应用程序,可能会显得过于复杂。例如,在一个小型的命令行工具中,如果只有少量的数据访问操作,使用 DAO 模式可能会增加不必要的代码开销。
  • 性能问题可能被掩盖:
    在数据访问对象的抽象过程中,可能会忽略一些底层数据源的性能优化点。例如,在数据库访问中,如果不考虑数据库连接池、查询优化等性能相关的因素,可能会导致系统性能下降。同时,数据访问对象的多层调用也可能会引入一定的性能开销。

http://www.ppmy.cn/news/1550050.html

相关文章

如何进行Apache的配置与调试?

1. Apache简介 Apache 是一个提供HTTP服务的WEB软件&#xff0c;由apache 基金会进行运营并开源。 2. Apache特性 1. 模块化&#xff1a;很多功能都不是由apache本身来完成的&#xff0c;而是由apache自身携带的模块和其扩展模块来完成的&#xff0c;因此一个完整的Apache的…

【Electron学习笔记(一)】Electron基本介绍和环境搭建

Electron基本介绍和环境搭建 Electron基本介绍和环境搭建前言正文1、Electron介绍1.1 什么是Electron1.2 Electron技术架构1.3 Electron工作流程 2、Electron环境搭建2.1 创建项目目录2.2 检查 Node.js 和 npm 的版本信息2.3 初始化 npm 包2.4 将 electron 包安装到应用的开发依…

【大数据分析深度学习】在Hadoop上实现分布式深度学习

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈智能大数据分析 ⌋ ⌋ ⌋ 智能大数据分析是指利用先进的技术和算法对大规模数据进行深入分析和挖掘&#xff0c;以提取有价值的信息和洞察。它结合了大数据技术、人工智能&#xff08;AI&#xff09;、机器学习&#xff08;ML&a…

深度学习实战人脸识别

文章目录 前言一、人脸识别一般过程二、人脸检测主流算法1. MTCNN2. RetinaFace3. CenterFace4. BlazeFace5. YOLO6. SSD7. CascadeCNN 三、人脸识别主流算法1.deepface2.FaceNet3.ArcFace4.VGGFace5.DeepID 四、人脸识别系统实现0.安装教程与资源说明1. 界面采用PyQt5框架2.人…

Android 14 screenrecord录制视频失败的原因分析

文章目录 1. 权限问题2. 存储空间不足3. 命令被中断4. 目标路径问题5. Android 14 的新限制6. 文件系统同步问题7. 录制失败检查步骤总结&#xff1a; 在 Android 14 系统上&#xff0c;使用 screenrecord 命令录制视频后&#xff0c;生成的文件大小为 0&#xff0c;可能的原因…

【Android】静态广播接收不到问题分析思路

参考资料&#xff1a; Android 静态广播注册流程(广播2)-CSDN博客 Android广播发送流程(广播3)_android 发送广播-CSDN博客 https://zhuanlan.zhihu.com/p/347227068 在Android中&#xff0c;静态广播如果静态广播不能接收&#xff0c;我们可以从整个流程中去分析&#xff…

通信综合—8.通信网络安全

一、信息系统安全概述 1.信息系统的构成和分类 信息系统是将用于收集、处理、存储和传播信息的部件组织在一起而成的相关联的整体&#xff0c;般是由计算机硬件、网络和通信设备、计算机软件、信息资源和信息用户组成。它是以处理信息流为目的的人机一体化系统。信息系统主要…

蓝桥杯不知道叫什么题目

小蓝有一个整数&#xff0c;初始值为1&#xff0c;他可以花费一些代价对这个整数进行变换。 小蓝可以花贵1的代价将教数增加1。 小蓝可以花费3的代价将整数增加一个值,这个值是整数的数位中最大的那个(1到9) .小蓝可以花费10的代价将整数变为原来的2倍, 例如&#xff0c;如果整…