iteye_14540 2008-10-24 11:07
浏览 328
已采纳

【求解】真的还需要注入DAO吗?

以前在做JAVA开发的时候,通常我们的设计是Service,DAO,Domain。

但最近接触到了ror,对其中的一些设计很是喜欢。比如。

user.save()当然是还有其他数据库操作的。

但是反观Java中的设计就十分猥琐。按三层结构下,我们需要定义一个DAO接口及其实现,Service接口及其实现。

更猥琐的是,Service接口中的定义与DAO定义其中有相同的。

比如:save,update,delete,find。如此。



当然我不知道现在各位是如何设计的,因为差不多本人已有1年未接触JAVA了,但我刚才看了几个帖貌似还是这个状况。



我大概琢磨了一下利用JAVA来实现类似ROR所提供的Model CRUD



先列出该方式存在的问题和需要解决:

1.DAO没有接口设计。只是有个定义而已。

2.如果更换数据库或是数据库操作实现可能无法很优雅的解决。

3.需要创建一个类似Hibernate中Criteria的查询对象,避免绑定数据库操作框架,如Hibernate换到iBatis。

4.或是还有更多无法预料的问题。



好了。列一下代码:



1.先定义一个通用DAO接口,我也不知道为什么要定义这个东西,一个小小的习惯而已。当然。这里完全可以把方法定义加进去。以后再换个其他数据库操作实现只需要加一个类implements这个接口即可,而不需要去查找现在的实现里有哪些方法。

public interface GenericDAO<t, id="" extends="" serializable="">  {
//暂时现在的解决方式中没有任何方法定义
}




2.创建一个通用DAO接口实现,你可以直接往下拉看第三步了。这里代码很长,就是一些通用的数据库操作方法,需要自行实现,具体用JDBC,Hibernate那就自己写了。

public class GenericDefaultDAO<t, id="" extends="" serializable="">
implements GenericDAO<t,id> {
public static<t> List<t> findAll(MyCriteria...myCriteria) {
// TODO Auto-generated method stub
return null;
}
public static&lt;t,id&gt; T find(ID id) {
    // TODO Auto-generated method stub
    return null;
}

public void save() {
    // TODO Auto-generated method stub

}

public static&lt;t&gt; void save(T object) {
    // TODO Auto-generated method stub

}

public void delete() {
    // TODO Auto-generated method stub

}

public static&lt;id&gt; void delete(ID id) {
    // TODO Auto-generated method stub

}

public void update() {
    // TODO Auto-generated method stub

}

public static&lt;t&gt; void update(T object) {
    // TODO Auto-generated method stub

}

}





3.创建自定义DAO类(注意是类不是接口),其中实现自定义类需要的常用查询方法。但是自定义的方法必须使用父类提供的方法实现,这样可保证父类的数据库操作方式改变下层代码无需更改。

public class UserDAO extends GenericDefaultDAO<user, string=""> {
public static List findBySex(String sex){
MyCriteria criteria = new MyCriteria();
//设置criteria参数
this.find(criteria);
}
}




4.创建Model

public class User extends UserDAO{
private String loginName;
private String name;
private String password;
//......很多属性
}






5.使用,很多情况下我们都是在find

User user = User.find("1");
user.setName("风花雪月饼");
user.save();




主要问题就是MyCriteria如何设计的问题。暂时我还没发现其他问题。

至少。我不要再向Service中去注入DAO了。。。多爽的一件事情啊。。。



大概就这些了。还想写点什么,可是在太困了。想不起来了。


问题补充:
主要考虑是扩展性和API的简洁性。

当然这个考虑可能和语言有关。

ROR中通过继承ActiveRecord来实现save等CRUD.

在本次JAVA里的实现实际也是如此。

关于委托模式,首先创建一个MODEL的时候肯定代码要比User user = new User();多吧?



这里可以看到GenericDefaultDAO的定义名,原来是叫GenericHibernateDAO。后来一想,如果我改成iBatis那我需要修改多个Model。

如果叫default,那么届时我增加一个iBatis实现类,也叫这个,然后把现有的改个名字,就完成了数据库操作层的扩展。



我觉得灵活和扩展性应该是可以按一定范围来确定的。而不是把设计模式都完全的应用进去。
  • 写回答

1条回答 默认 最新

  • btprince 2008-10-24 11:07
    关注

    谈谈自己的一点看法:
    其实分了这么多层无非是出于几点考虑,首先是希望能日后好维护,好扩展。个人认为委托比继承更好,使得业务和DAO之间能够很好解耦。比如,可以往user里面注入UserDao也可以是其他的Dao,增强了灵活性和扩展性。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 flink cdc无法实时同步mysql数据
  • ¥100 有人会搭建GPT-J-6B框架吗?有偿
  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名