目录
1.StudenDaoListImpl.java与StudentDaoArrayImpl.java有何不同?
2.StudentDao.java文件是干什么用的?为什么里面什么实现代码都没有?
3.使用搜索引擎搜索“Java DAO”,选出几句你能看懂的、对你最有启发的话。请结合接口知识去理解。
4.尝试运行Test.java。根据注释修改相应代码。结合参考代码回答使用DAO模式有什么好处?
5.可选:编写一些使用DAO模式的代码。比如使用文件作为购物车存储底层。
要求:阅读附件中的参考代码,并回答以下问题
1.StudenDaoListImpl.java与StudentDaoArrayImpl.java有何不同?
-
数据的存储方式不同:StudenDaoListImpl 使用 List 来存储学生对象,它可以动态扩容,没有固定大小限制。 StudentDaoArrayImpl 使用数组来存储学生对象,有固定的大小。
-
添加对象的方式不同:StudenDaoListImpl调用了ArrayList的add方法来添加学生对象,而StudentDaoArrayImpl根据数组的索引位置来添加学生对象。
-
成员大小的限制:使用StudenDaoListImpl创建对象不需要明确存储学生的数量,而StudentDaoArrayImpl在创建对象时需要指定数组的大小。
-
1. //StudenDaoListImpl: private List<Student> students = new ArrayList<Student>(); //StudentDaoArrayImpl: private Student[] students; 2. //StudenDaoListImpl: public boolean addStudent(Student student) { students.add(student); return true; } //StudentDaoArrayImpl: public boolean addStudent(Student student) { boolean success = false; for(int i=0; i<students.length;i++){ if(students[i]==null){ students[i] = student; success = true; break; } } return success; } 3. //StudenDaoListImpl: StudentDao sdm = new StudenDaoListImpl() //StudentDaoArrayImpl: StudentDao sdm = new StudentDaoArrayImpl(50)
2.StudentDao.java文件是干什么用的?为什么里面什么实现代码都没有?
用于存放StudentDao接口;其中声明了三个抽象方法addStudent(添加学生)、getStuByName(根据名字获取学生对象)和diplayAllStudents(显示所有学生),并没有具体的实现代码。 作为程序员可以面向接口编程,在其他类中根据这个接口来实现自己想要的方法,灵活切换各种业务,同时能使得代码结构清晰。
3.使用搜索引擎搜索“Java DAO”,选出几句你能看懂的、对你最有启发的话。请结合接口知识去理解。
1.“Java DAO是一种将数据访问逻辑与业务逻辑分离的设计模式,有助于提高代码的清晰度和可维护性。”
这句话强调了Java DAO的设计目标,即将数据访问逻辑和业务逻辑分开,使得代码更加清晰易懂,同时也更方便进行维护。
2.“通过DAO模式,我们可以实现对底层数据源的抽象,使得应用程序可以灵活地切换不同的数据源而无需修改业务逻辑代码。”
这句话说明了DAO模式的另一个重要优点,即实现对底层数据源的抽象。这种抽象可以使得应用程序在需要切换数据源时,无需修改业务逻辑代码,只需要更改DAO层的实现即可,大大提高了代码的灵活性和可扩展性。
3.“DAO模式允许我们将底层数据源的实现细节封装在DAO类中,使得应用程序只需要与DAO接口进行交互,而无需关心数据源的具体细节。”
这句话强调了DAO模式的解耦作用。通过将底层数据源的实现细节隐藏在DAO类中,应用程序只需要与DAO接口进行交互,从而降低了应用程序与数据源之间的耦合性(耦合性是指一个类、方法或模块依赖于另一个类、方法或模块的程度),方便了代码的维护和扩展。
4.尝试运行Test.java。根据注释修改相应代码。结合参考代码回答使用DAO模式有什么好处?
由以上截图可以知道,两种数据存储方法运行的结果相同。
使用DAO模式的好处是:
1.将数据访问与业务逻辑分离,提高了代码的可维护性和可测试性。体现在通过调用 addStudent 方法添加学生时,无论是数组还是列表实现,都只需要关注 StudentDao 接口的方法,而不需要关注具体的数据存储方式。这体现了数据访问逻辑与业务逻辑的分离。
2.提供了对数据库操作的抽象层,方便切换不同的数据存储方式。体现在通过创建StudentDao 接口,将对学生对象的操作进行了抽象化。在 Test 类的 main 方法中,根据需要写入不同的具体实现类来实现不同的数据存储方式。这里通过注释切换StudentDaoArrayImpl 和StudenDaoListImpl 来实现数组存储和列表存储。
3.解耦作用。体现在代码中显示所有学生和查询学生的操作通过对 StudentDao
接口的方法调用来实现,该接口提供了统一的数据访问接口,屏蔽了底层存储细节。
5.可选:编写一些使用DAO模式的代码。比如使用文件作为购物车存储底层。
1.实体类:
public class ShoppingCart {
private String customerName;
private List<String> items;
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public List<String> getItems() {
return items;
}
public void setItems(List<String> items) {
this.items = items;
}
}
2.DAO接口:
public interface ShoppingCartDao {
public boolean addShoppingCart(ShoppingCart cart);
public List<ShoppingCart> getAllShoppingCarts();
public ShoppingCart getShoppingCartByCustomerName(String customerName);
}
3.DAO实现类:
import java.io.*;
import java.util.*;
public class FileShoppingCartDao implements ShoppingCartDao {
private String fileName;
public FileShoppingCartDao(String fileName) {
this.fileName = fileName;
}
@Override
public boolean addShoppingCart(ShoppingCart cart) {
try {
// 将购物车对象序列化为字节数组,并写入文件
FileOutputStream fos = new FileOutputStream(fileName, true);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(cart);
oos.close();
fos.close();
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
@Override
public List<ShoppingCart> getAllShoppingCarts() {
List<ShoppingCart> carts = new ArrayList<>();
try {
// 从文件中读取所有购物车对象
FileInputStream fis = new FileInputStream(fileName);
ObjectInputStream ois = new ObjectInputStream(fis);
while (true) {
try {
ShoppingCart cart = (ShoppingCart) ois.readObject();
carts.add(cart);
} catch (EOFException e) {
break;
}
}
ois.close();
fis.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
return carts;
}
@Override
public ShoppingCart getShoppingCartByCustomerName(String customerName) {
List<ShoppingCart> carts = getAllShoppingCarts();
for (ShoppingCart cart : carts) {
if (cart.getCustomerName().equals(customerName)) {
return cart;
}
}
return null;
}
}
4.客户端类:
public class Application {
public static void main(String[] args) {
// 创建购物车DAO实例,指定文件名为"shopping_carts.dat"
ShoppingCartDao dao = new FileShoppingCartDao("shopping_carts.dat");
ShoppingCart cart = new ShoppingCart();
cart.setCustomerName("John");
cart.setItems(Arrays.asList("apple", "banana", "orange"));
dao.addShoppingCart(cart);
List<ShoppingCart> carts = dao.getAllShoppingCarts();
for (ShoppingCart c : carts) {
System.out.println(c);
}
}
}
这样编写代码的好处是使得代码更加模块化和易于维护。通过将数据访问逻辑封装在DAO类中,并将对象的创建和管理交给工厂类或构造函数来处理,可以将代码划分为独立的模块,每个模块具有清晰的职责和功能。这样可以使代码更加清晰和易于理解,同时也方便了代码的维护和修改。此外,通过使用DAO接口来抽象数据访问操作,可以简化代码并提高代码的灵活性。