设计DAO课程的最佳方法是什么?
方法#1: 将DAO类设计为对象。
class Customer {
//customer class
}
class CustomerDAO {
public void saveCustomer(Customer customer) {
//code
}
public Customer getCustomer(int id) {
//code
}
}
//Client code
class client {
public static void main(String[] args) {
CustomerDAO customerDAO = new CustomerDAO();
Customer customer = new Customer();
customerDAO.saveCustomer(customer);
}
}
方法#2: 使用静态方法设计DAO类(又名静态类)
class Customer {
//customer class
}
class CustomerDAO {
public static void saveCustomer(Customer customer) {
//code
}
public static Customer getCustomer(int id) {
//code
}
}
//Client code
class client {
public static void main(String[] args) {
Customer customer = new Customer();
CustomerDAO.saveCustomer(customer);
}
}
在方法#1中,我必须在所有客户端代码中创建DAO类的对象(其他选项是传递DAO的引用)。在方法#2中,我不必创建对象,静态方法可以设计为没有状态跟踪。
那么哪种方法最适合DAO类的设计?
答案 0 :(得分:37)
我建议使用方法#1,但是会使用Spring进行依赖注入,而不是直接实例化DAO。
这样,对于单元测试客户端代码,您可以替换模拟DAO,并验证是否使用适当的参数调用了正确的DAO。 (Mockito在这里很有用。)
如果使用静态方法,则单元测试要困难得多,因为无法覆盖静态方法。
答案 1 :(得分:11)
要有更多的抽象:
interface IDAO<T> {
public save(T t);
public T getById(int id);
//...etc
}
然后
public CustomerDao implements IDAO<Customer>{
public save(Customer c){
//Code here
}
public Customer getById(int id){
//Code here
}
}
和DAO到另一个域
public UniversityDao implements IDAO<University>{
public save(University u){
//Code here
}
public University getById(int id){
//Code here
}
}
现在表示层或主类将包含如下代码:
IDAO dao;
dao=new CustomerDao();
//...
dao=new UniversityDao();
答案 2 :(得分:6)
我也会选择选项1,但我也建议你编程接口。创建一个界面,设置DAO必须提供的功能,然后根据需要实现不同类的功能。
public interface CustomerDao {
public void saveCustomer(Customer customer);
public Customer getCustomer(int id);
}
然后你可以拥有class SimpleCustomerDao implements CustomerDAO {/*code here*/}
。
在main
(以及您需要的其他任何地方),您将拥有:
//Note that you have an interface variable and a real class object
CustomerDao customerDao = new SimpleCustomerDao();
你可以弄清楚这样做的好处!
答案 3 :(得分:5)
请参阅文章如何编写通用DAO(使用Spring AOP): Don't repeat the DAO!
您可以找到技术堆栈的通用DAO实现示例(只是谷歌“不要重复DAO my_technology”)。
答案 4 :(得分:0)
我更喜欢分层方法,这种方法简单告诉我们的是:
您正通过Interface CustomerDAO与客户签订合同
public interface CustomerDAO{
public void saveCustomer(Customer customer);
public Customer getCustomer(int id);
}
您正在拥有像CustomerDAOImpl
这样的具体实施public class CustomerDAOImpl extends CustomerDAO{
public void saveCustomer(Customer customer){
saveCustomer(customer);
}
public Customer getCustomer(int id){
return fetchCustomer(id);
}
}
然后编写管理器来管理这些或封装其他一些DAO,如:
public class ManagerImpl extends Manager{
CustomerDAO customerDAOObj;
// maybe you need to collect
// all the customer related activities here in manger
// because Client must not bother about those things.
UserBillingDAO userBillingDAOObj;
public void saveCustomer(Customer customer){
customerDAOObj.saveCustomer(customer);
}
public Customer getCustomer(int id){
return customerDAOObj.fetchCustomer(id);
}
// Note this extra method which is defined in
//UserBillingDAO which I have not shown, but you are exposing
//this method to your Client or the Presentation layer.
public boolean doBillingOFCustomer(id) {
return userBillingDAOObj.doBilling(id);
}
}
现在表示层或主类将包含如下代码:
public static void main(String... ar){
Manager manager = new ManagerImpl();
manager.saveCustomer();
// or manager.doBillingOfCustomer(); // etc
}