|
|
|
一个困惑的关于域建模的若干个问题
作者:eway
发表时间:2004年10月22日 09:44
回复
原贴网址:
http://www.jdon.com/jivejdon/thread/17193.html
一个User类:
public class User{ private int ID; private String name; private String password; private int GroupID; .... public void setPassword(String password){ ... } public void changePassword(String password){ ... } .... }
问题1:新增一个用户,从域模型角度去看其实就是new User(),而修改用户密码就setPassword();而从另一个角度看,修改密码却可以看成User类的一个行为,可以为User类设计一个方法changePassword(),新增用户可以用一个createUser(User user)来实现。那么具体的实现在实际项目中怎样进行取舍选择? 问题2:如果使用createUser(User user)这种方式实现,那么createUser的方法应该不能放到User类中了,毕竟对象不能自己create自己,可是实体bean似乎就是这样的方式实现create??为什么?? 问题3:既然User类不能create自己,那么创建一个UserManager类,包含createUser方法,这种情况下,User类的changePassword方法是否也放到UserManager类中? 问题4:如果使用new User方式来创建用户,那么删除用户的操作用什么方式进行? 问题5:怎么理解实体bean?他是域对象建模的结果么?那么怎么理解实体bean的create,remove?自己可以create,remove自己?
|
|
Re: 一个困惑的关于域建模的若干个问题
|
发表: 2004年10月22日 10:37
|
回复
|
|
|
|
|
|
|
|
Re: 一个困惑的关于域建模的若干个问题
|
发表: 2004年10月24日 13:32
|
回复
|
|
|
|
看了几天没人回答,我就来试试吧,我也是新手,呵呵,共同探讨。
User是个domain model,你可以用DAO模式去操作这个model 创建一个UserDAO,就是你自己的UserManager。
public interface UserDAO { public Customer createUser(...); public boolean updateUser(...); public boolean deleteUser(...); public Collection selectUser(...); }
|
|
|
|
Re: 一个困惑的关于域建模的若干个问题
|
发表: 2004年10月25日 07:54
|
回复
|
|
|
|
|
可是DAO只不过应该充当一个域模型和数据源之间的中介。DAO的作用不就是为域模型提供底层数据源屏蔽么。
|
|
|
|
Re: 一个困惑的关于域建模的若干个问题
|
发表: 2004年10月25日 13:23
|
回复
|
|
|
|
User中不应该有public void changePassword(String password){方法
使用UserManger来创建管理User,实体Bean是域模型的一个实现结果。实体Bean中有的create,remove方法,其实这两个方法不是对Model操作,而是管理实体Bean自己的,不是操作User的。
实体bean或EJB如同一个载体,例如是太空船等,具体Model放在太空船中,是船中货物,那么对于Model来讲,船是载体,载体自己有自我管理的能力,如发动:create;停止:remove,是不是类似有生命体一样,可以自己活动的,所以对于EJB经常又有生命周期的说法。
不知是否理解?
|
|
|
|
Re: 一个困惑的关于域建模的若干个问题
|
发表: 2004年10月25日 16:56
|
回复
|
|
|
|
多谢banq,ejb的create和remove是做生命周期管理用的。 不过有一个问题确实十分迷惑?怎么区分对象的操作?像public void changePassword(String password)这样的方法不应该算是域模型类User的操作么?如果是User的操作,那么按照面向对象,对象就是由属性和操作组成的,为什么放到User里不合适?如果不是User的操作,那么到底什么样的方法能算是User的操作呢?怎么划分
|
|
|
|
Re: 一个困惑的关于域建模的若干个问题
|
发表: 2004年10月27日 00:16
|
回复
|
|
|
|
现在这个问题确实成了个问题了, 是不是就是所谓的Transaction Script和Domain Model的差别?我是最近看了透明的blog时候想到这确实是个问题。这个东西值得研究研究。
|
|
|
|
Re: 一个困惑的关于域建模的若干个问题
|
发表: 2004年10月28日 18:24
|
回复
|
|
|
|
简单一个问题,包含的东西真是很多,这种真是那种“贫血的domain model” 看看martin fowler对这个问题的看法吧。 http://martinfowler.com/bliki/AnemicDomainModel.html
|
|
|
|
Re: 一个困惑的关于域建模的若干个问题
|
发表: 2004年10月29日 07:48
|
回复
|
|
|
|
|
是啊,^_^,看来人家是不赞同贫血的域模型的。一个无方法域模型的确是不符合面向对象设计的思想的。
|
|
|
|
Re: 一个困惑的关于域建模的若干个问题
|
发表: 2004年11月10日 19:01
|
回复
|
|
|
|
我回答的“User中不应该有public void changePassword(String password){方法,使用UserManger来创建管理User”
是基于下面这个原则: 1.EJB的Entity Bean是域模型持久化的一个实现方式,其他有JDBC、O/R Mapping等。
2.EJB的Session Bean作为Transaction Script实现。某种程度上是一种过程。
3.设计模式、可复用的部分以POJO实现,可被Session Bean调用。必要时,使得Session Bean成为接口实现参与复用设计。
这点和贫血模型是抵触的,我不赞成贫血模型,至少我现在的项目都是所谓贫血模型。
从与UML衔接来看,顺序图一般由SLSB实现,域模型由普通的Java类(POJO)实现,如只有set get的User类,实体Bean/JDO/Hibernate只是域模型持久化的一个形式。
如果在域模型中嵌入changePassword这样的方法,我以前这么做过,有兴趣者可参考我的书的第二章,Jsp/JavaBeans/JDBC实现的用户注册系统,这种情况下这么做比较简单。
但是,当引入EJB这样的组件模型(Component Model)之后,我发现使用贫血模型的好处是可以方便的实现组件化编程,因为你只要将一个域模型分离抽象出来,就可以形成一个可重用的组件(构件)库,例如,用户登陆验证每个系统都需要,现在它已经成为我的一个组件库,可以复用在多个项目。下一步就差通过SOA更有效率地输出这种重用的服务。
|
|
|
|
Re: 一个困惑的关于域建模的若干个问题
|
发表: 2004年11月10日 22:37
|
回复
|
|
|
|
1.setPasswd是User类的责任,可以作为User的一个方法出现。而如何实例化一个User对象,如何新增一个用户就不是他的责任了。 2.同上 3.如果需要个UserManager类管理User,可以有createUser方法,createUser可以是这个类的责任 4.上步中createUser后UserManger肯定要持有实例化的User对象,通常是放数组或vector之类的容器里,deleteUser用户的操作就不用我讲了吧 5.尸体bean专家讲过了,偶没的说了
不知道阿拉有没理解错您的意思
|
|
|
|
Re: 一个困惑的关于域建模的若干个问题
|
发表: 2004年11月11日 09:40
|
回复
|
|
|
|
|
这个问题也就理论上讨论讨论,实际上关系不大,也许那个flower的peaa这本书已经说过了。按我的理解,可以分为两个类,一个管理user的生存周期(UserMng),一个就是user domain(User)本身了。象创建,生成,查找,删除之类的都在UserMng里,象changePasswd应该在user里。其实可以把passwd看作一个user属性,叫setPasswd也行。当然还有象修改别人密码的需求,可以先通过find user,再user.setPasswd().
|
|
|
|
Re: 一个困惑的关于域建模的若干个问题
|
发表: 2004年11月11日 22:07
|
回复
|
|
|
|
我比较同意neooen的看法,bang的部分看法我也同意,但关于他反对所谓的贫血模型,呵呵。域模型说白了就是数据的载体,应该只有自己的一些属性和属性状态变化的方法,就setter和getter方法。关于对它的系列化应该由专门负责这样事情的操作类来处理,就象上面所说的userManger一样。现在看看下面的代码: public class User extends AbstractValueObject { private int ID; private String name; private String password; private int GroupID; .... public void setPassword(String password){ ... } public void changePassword(String password){ ... } ....}
public interface AbstractDAO extends Serializable { public abstract int insert(AbstractValueObject abstractvalueobject) throws SQLException;
public abstract int update(AbstractValueObject abstractvalueobject) throws SQLException;
public abstract int delete(Object obj) throws SQLException;
public abstract int insert(AbstractValueObject abstractvalueobject, Connection connection) throws SQLException;
public abstract int update(AbstractValueObject abstractvalueobject, Connection connection) throws SQLException;
public abstract int delete(Object obj, Connection connection) throws SQLException;
public abstract AbstractValueObject findByPrimaryKey(Object obj) throws SQLException;
public abstract AbstractValueObject findByPrimaryKey(Object obj, String[] sqls) throws SQLException;
public abstract Collection findAll() throws SQLException;
public abstract Collection findBySql(String s) throws SQLException;
public abstract Collection findBySql(String s, Connection connection) throws SQLException;
public abstract Page getPageBySql(String s, Integer start, Integer count) throws SQLException;
public Collection getPageColBySql(String findSql, Integer starIndex, Integer pageSize, Integer pageCount) throws SQLException;
}
public UserDAO impletments AbstractDAO { .........}
public UserManager {
private startic UserDAO dao = new UserDAO public createUser(User user) { dao.create(user); ................
}
public changePassword(User user) { //user已经在外面user.setPassword(newPassword); dao.update(user); ................... }
}
在EJB的Entity Bean其实不是和user类似,而是和UserDao类似,不信你看看他的skelet实现类(了解RMI的理论),呵呵,里面是什么,是jdbc。所以不要误会了,虽然它能给外面提供域模型实例集合。看下面: public java.lang.String EJBCreate(ForumValueObject vo) throws CreateException { System.out.println("ejbCreate(vo)"); String forumId = vo.getForumId(); String forumName = vo.getForumName(); String forumCnname = vo.getForumCnname(); String forumProductid = vo.forumProductid; com.topfounder.common.database.TPClob tmpTPClob = vo.getContent(); String content = tmpTPClob == null ? null : tmpTPClob.getContent(); String admin = vo.getAdmin(); java.sql.Date registerdate = vo.getRegisterdate(); String topic = vo.topic; String remark = vo.getRemark(); EJBCreate(forumId, forumName, forumCnname, forumProductid, content, admin, registerdate, topic, remark); return null; }
其实 它就是系列化域模型,这里JDBC你没有看到,但在它的具体实现(skelet)里就看到了。 我反对批评所谓的贫血模型,在贫血模型加上不伦不类的逻辑操作才是怪物,我在说一下,域模型就是一个数据载体。
|
|
|
|
Re: 一个困惑的关于域建模的若干个问题
|
发表: 2004年11月12日 09:35
|
回复
|
|
|
|
|
实在不同苟同上面这位兄弟的观点“在贫血模型加上不伦不类的逻辑操作才是怪物”,请阅读domain-model design这本书。目前普遍存在两种设计方式,一种是使用Manager也就是service方式来管理业务逻辑,还有一种就是楼上所不赞成的domain object来管理业务逻辑。其实service的方式并没有什么不好,但是它的职责应该描述的更清晰,它不应该是实现全部的业务逻辑,而只是调用各个domain object的方法,对外来提供服务而已,可以说它是代理domain object的方法或者是系统facade。真真实现业务逻辑纳入domain object并没有什么奇怪,它真实的反映了领域模型的行为,更符合OO,当然回带来更多的好处。
|
|
|
|
Re: 一个困惑的关于域建模的若干个问题
|
发表: 2004年11月12日 09:42
|
回复
|
|
|
|
谢谢nekesai的肯定,不过看了您贴出来的代码,乱乱的没怎么看明白。 不过看到了一个问题
public UserManager {
private startic UserDAO dao = new UserDAO
public createUser(User user) {
dao.create(user); ................
}
public changePassword(User user) { //user已经在外面user.setPassword(newPassword);
dao.update(user); ................... }
} 这个方法好像是userManager的,和dao发生了什么关系,还和User有什么关系,我觉的如果真的要用userManager.changePassword,还是把changePassword委托给User来做最好。
不知道我有没理解错您的意思
|
|
|
|
这个主题共有 52 回复 / 4 页 [
1 2 3 4
下一页
]
| |
|
|
|
|