Java DAO 模式深度解析与实践
Java DAO模式深度解析与实践
目录
- StudenDaoListImpl与StudentDaoArrayImpl的差异
- StudentDao.java的作用与设计原因
- Java DAO相关概念与接口知识结合理解
- Test.java运行分析与DAO模式的好处
- DAO模式实践:文件存储的购物车实现
1. StudenDaoListImpl与StudentDaoArrayImpl的差异
两个类均实现了StudentDao接口,但底层数据存储结构和方法实现逻辑存在显著差异:
-
存储容器不同
StudentDaoArrayImpl使用数组(Student[]) 存储学生数据,需要在初始化时指定固定大小(通过构造器参数size)。StudenDaoListImpl使用List集合(ArrayList) 存储学生数据,无需指定初始大小,可动态扩容。
-
核心方法实现差异
addStudent方法:- 数组实现需遍历数组寻找
null位置(空闲空间),若数组已满则返回false(添加失败); - List实现直接调用
List.add()方法,因ArrayList支持动态扩容,始终返回true(添加成功)。
- 数组实现需遍历数组寻找
getStuByName方法:- 数组实现需先判断数组元素是否为
null(避免空指针异常),再比较姓名; - List实现无需判断
null(List中不会存储null元素,除非主动添加),直接遍历比较。
- 数组实现需先判断数组元素是否为
-
扩展性差异
数组实现受固定大小限制,数据量超过初始大小后无法添加;List实现无此限制,更适合数据量动态变化的场景。
2. StudentDao.java的作用与设计原因
StudentDao.java是一个接口(Interface),其核心作用是定义学生数据操作的标准契约,包含addStudent、getStuByName、diplayAllStudents三个方法的签名。
接口中没有实现代码的原因是:
接口的设计目标是只规定“做什么”,不关心“怎么做”。它为所有实现类(如StudentDaoArrayImpl、StudenDaoListImpl)提供统一的方法规范,确保不同实现类能被上层代码(如Test.java)以相同的方式调用,从而实现面向接口编程。
3. Java DAO相关概念与接口知识结合理解
通过搜索“Java DAO”,以下内容结合接口知识可获得启发:
-
“DAO(Data Access Object)模式用于隔离数据访问逻辑与业务逻辑,使两者解耦。”
接口在此处承担“隔离”角色:StudentDao接口定义数据访问逻辑的抽象(如“添加学生”),业务逻辑(Test.java中的调用)只需依赖接口,无需关心底层是数组、List还是数据库,实现了解耦。 -
“DAO接口定义数据操作的标准,实现类负责与具体数据源(如文件、数据库)交互。”
这与接口的“契约性”一致:StudentDao定义了“添加、查询、显示”的标准,StudentDaoArrayImpl(数组数据源)和StudenDaoListImpl(List数据源)则分别实现具体交互逻辑,符合“接口定标准,实现做具体”的设计。
4. Test.java运行分析与DAO模式的好处
运行与修改说明
- 原
Test.java使用StudentDaoArrayImpl(数组实现),若修改注释切换为StudenDaoListImpl(List实现):
程序仍可正常运行,输出结果一致(添加3个学生、显示所有学生、查询“Tom”成功)。// StudentDao sdm = new StudentDaoArrayImpl(50); StudentDao sdm = new StudenDaoListImpl();
DAO模式的好处
- 解耦业务逻辑与数据存储:
Test.java的业务逻辑(添加、查询学生)不依赖具体存储方式(数组/List),仅依赖StudentDao接口。 - 易于切换数据源:如需将存储方式改为数据库或文件,只需新增一个实现
StudentDao的类(如StudentDaoDbImpl),无需修改Test.java的业务代码。 - 提高可维护性:数据访问逻辑集中在实现类中,修改存储逻辑(如数组扩容规则)不会影响上层业务代码。
5. DAO模式实践:文件存储的购物车实现
以下是基于DAO模式、以文件为存储底层的购物车示例:
1. 购物车商品类(CartItem.java)
public class CartItem {
private String productName;
private int quantity;
public CartItem(String productName, int quantity) {
this.productName = productName;
this.quantity = quantity;
}
// getter、setter、toString略
public String getProductName() { return productName; }
public int getQuantity() { return quantity; }
@Override
public String toString() { return productName + " x" + quantity; }
}
2. 购物车DAO接口(CartDao.java)
import java.util.List;
public interface CartDao {
boolean addItem(CartItem item); // 添加商品
List<CartItem> getAllItems(); // 获取所有商品
boolean clearCart(); // 清空购物车
}
3. 文件实现类(CartDaoFileImpl.java)
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class CartDaoFileImpl implements CartDao {
private String filePath = "cart.txt"; // 存储文件路径
@Override
public boolean addItem(CartItem item) {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, true))) {
writer.write(item.getProductName() + "," + item.getQuantity());
writer.newLine();
return true;
} catch (IOException e) {
return false;
}
}
@Override
public List<CartItem> getAllItems() {
List<CartItem> items = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = reader.readLine()) != null) {
String[] parts = line.split(",");
items.add(new CartItem(parts[0], Integer.parseInt(parts[1])));
}
} catch (IOException e) {
// 忽略文件不存在的情况(视为空购物车)
}
return items;
}
@Override
public boolean clearCart() {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
writer.write(""); // 清空文件
return true;
} catch (IOException e) {
return false;
}
}
}
4. 测试类(CartTest.java)
public class CartTest {
public static void main(String[] args) {
CartDao cartDao = new CartDaoFileImpl();
// 添加商品
cartDao.addItem(new CartItem("笔记本", 1));
cartDao.addItem(new CartItem("鼠标", 2));
// 显示所有商品
System.out.println("购物车商品:");
for (CartItem item : cartDao.getAllItems()) {
System.out.println(item);
}
// 清空购物车
cartDao.clearCart();
}
}
该示例中,CartDao接口定义购物车操作标准,CartDaoFileImpl实现文件存储逻辑,上层测试代码仅依赖接口,体现了DAO模式的解耦优势——若后续需将存储方式改为数据库,只需新增CartDaoDbImpl实现类,无需修改CartTest的业务逻辑。

浙公网安备 33010602011771号