2007-12-19
Seam 使用心得(二)接口实现
关键字: seam
Java里提倡使用面向接口编程以减弱组件之间的耦合,在上一篇里已经定义了
这一节里面将实现这个接口来通过测试。
现在应用系统有很多良好的分层方法,但是我还是喜欢Evans的领域驱动设计的方法。
1,视图层将使用RichFaces。
2,使用无状态SessionBean作为Facade对领域逻辑进行封装。
3,领域层实现核心业务逻辑,主要包括有实体,值对象,仓库,服务等。
源文件目录结构大致如下:
src
|----action (SLSB)
|----model (Service, Entity, Repository, Vo)
|----test
view
|----css
|----js
……
经过简单的分析model层向facade暴露UserView接口
注:因为EJB2严重的依赖于容器的基础设施,如果在实体bean中包含业务逻辑,将很难进行测试,所以实体bean只能作为数据容器,而背离面向对象的分析和设计方法。但是EJB3已经可以对实体进行透明持久化,并且很容易在容器外进行测试,所以就用User实体实现UserView接口,这里用户注册的并没有跨越多个实体,只涉及用户实体,所以包含了业务方法register的User类代码如下:
考虑到视图层RichFaces和hibernate验证结合可以进行很简单的零脚本ajax验证,所以本例子里面使用了hibernate验证。
由于register方法需要用的UserRepository来访问数据库,所以现在来看一下UserRepository接口。通过隔离基础设施,这就是GOF设计模式中著名的Strategy模式,由于Java语言想要在实体中注入UserRepository在技术上存在困难,所以把UserRepository作为方法的参数传递我个人认为也是一种较为简洁的方法,而且通过接口的隔离不会和基础设施产生强烈的耦合,UserRepository代码如下:
在本例里面UserRepository的实现使用的JPA,这个接口的实现相当容易所以它的实现类UserRepositoryJPAImp代码就不贴出来了,可以直接看提供的源码。
model层的接口已经实现完毕,接下来实现facade,代码如下:
这里facade是很薄的一层,不能包含任何业务逻辑,它主要根据model返回的状态是向显示层发送信息,使用facesMessages组件就可以很容易向Richfaces发送ajax验证的响应信息,并且事务处理统一在facade层进行,由于使用EJB,所以就可以使用容器提供的事务管理。
上述类的结构如下图所示:
facade: Register-->RegisterBean-->UserView&UserRepository
domain:UserView-->User(Eneity)<-->UserRepository-->UserRepositoryJPAImp
至此为止,注册用户所需要的全部接口都已经实现,现在就可以用seam test命令来运行上一节写好的测试代码了。
@Local
public interface Register {
public String register();
}
这一节里面将实现这个接口来通过测试。
现在应用系统有很多良好的分层方法,但是我还是喜欢Evans的领域驱动设计的方法。
1,视图层将使用RichFaces。
2,使用无状态SessionBean作为Facade对领域逻辑进行封装。
3,领域层实现核心业务逻辑,主要包括有实体,值对象,仓库,服务等。
源文件目录结构大致如下:
src
|----action (SLSB)
|----model (Service, Entity, Repository, Vo)
|----test
view
|----css
|----js
……
经过简单的分析model层向facade暴露UserView接口
package org.qpt.domain.user;
import org.qpt.domain.user.User.RegState;
/**
* 用户接口
* @author xiaoqiu
*/
public interface UserView {
String getConfirmPwd();
String getEmail();
String getName();
String getPwd();
/**
* 注册一个新用户
* @param ur 用户仓库接口
* @return 注册结果状态码(共5种状态,上一节已经提到过)
*/
RegState register(UserRepository ur);
void setConfirmPwd(String confirmPwd);
void setEmail(String email);
void setName(String name);
void setPwd(String pwd);
}
注:因为EJB2严重的依赖于容器的基础设施,如果在实体bean中包含业务逻辑,将很难进行测试,所以实体bean只能作为数据容器,而背离面向对象的分析和设计方法。但是EJB3已经可以对实体进行透明持久化,并且很容易在容器外进行测试,所以就用User实体实现UserView接口,这里用户注册的并没有跨越多个实体,只涉及用户实体,所以包含了业务方法register的User类代码如下:
/**
* 用户实体
*
* @author xiaoqiu
*/
@Entity
@Name("user")
@Scope(SESSION)
@Table(name = "users")
public class User implements Serializable, UserView {
private static final long serialVersionUID = 3836699581343986461L;
@Id
@NotNull
@Length(min = 6, max = 15)
private String name;
@NotNull
@Length(min = 6, max = 15)
private String pwd;
@Transient
private String confirmPwd;
@NotNull
@Email
private String email;
@Transient
private String confirmEmail;
public enum RegState {
EXISTS_EMAIL, EXISTS_NAME, PWD_NOT_EQ_IN_TWICE, EMAIL_NOT_EQ_IN_TWICE, SUCCESS
}
@Override
public RegState register(UserRepository ur) {
if (!pwd.equals(confirmPwd)) {
return PWD_NOT_EQ_IN_TWICE;
} else if (!email.equals(confirmEmail)) {
return EMAIL_NOT_EQ_IN_TWICE;
} else if (ur.findByProperty("name", name)) {
return EXISTS_NAME;
} else if (ur.findByProperty("email", email)) {
return EXISTS_EMAIL;
} else {
ur.save(this);
return SUCCESS;
}
}
……
get&set method
}
考虑到视图层RichFaces和hibernate验证结合可以进行很简单的零脚本ajax验证,所以本例子里面使用了hibernate验证。
由于register方法需要用的UserRepository来访问数据库,所以现在来看一下UserRepository接口。通过隔离基础设施,这就是GOF设计模式中著名的Strategy模式,由于Java语言想要在实体中注入UserRepository在技术上存在困难,所以把UserRepository作为方法的参数传递我个人认为也是一种较为简洁的方法,而且通过接口的隔离不会和基础设施产生强烈的耦合,UserRepository代码如下:
/**
* 用户仓库接口
* @author xiaoqiu
*/
@Local
public interface UserRepository {
void save(User user);
User findByName(String name);
List<User> findAllUser();
/**
* 找出该属性是否存在当前值
* @param name 属性名
* @param value 属性值
* @return 该属性存在这个值返回true,否则返回false
*/
boolean findByProperty(String name, String value);
}
在本例里面UserRepository的实现使用的JPA,这个接口的实现相当容易所以它的实现类UserRepositoryJPAImp代码就不贴出来了,可以直接看提供的源码。
model层的接口已经实现完毕,接下来实现facade,代码如下:
@Stateless
@Name("register")
public class RegisterBean implements Register {
@Logger
private Log log;
@In
FacesMessages facesMessages;
@In
private UserView user;
@In("userRepository")
UserRepository ur;
public String register() {
RegState state = user.register(ur);
switch (state) {
case PWD_NOT_EQ_IN_TWICE:
log.info("the register state is " + state);
facesMessages.addFromResourceBundle("myapp.register.pwd.noteq");
break;
case EMAIL_NOT_EQ_IN_TWICE:
log.info("the register state is " + state);
facesMessages.addFromResourceBundle("myapp.register.email.noteq");
break;
case EXISTS_NAME:
log.info("the register state is " + state);
facesMessages.addFromResourceBundle("myapp.register.name.exists");
break;
case EXISTS_EMAIL:
log.info("the register state is " + state);
facesMessages.addFromResourceBundle("myapp.register.email.exists");
break;
case SUCCESS:
log.info("register a new user #{user.name}" + "\nthe register state is " + state);
facesMessages.addFromResourceBundle("myapp.register.success");
break;
}
return state.toString();
}
}
这里facade是很薄的一层,不能包含任何业务逻辑,它主要根据model返回的状态是向显示层发送信息,使用facesMessages组件就可以很容易向Richfaces发送ajax验证的响应信息,并且事务处理统一在facade层进行,由于使用EJB,所以就可以使用容器提供的事务管理。
上述类的结构如下图所示:
facade: Register-->RegisterBean-->UserView&UserRepository
domain:UserView-->User(Eneity)<-->UserRepository-->UserRepositoryJPAImp
至此为止,注册用户所需要的全部接口都已经实现,现在就可以用seam test命令来运行上一节写好的测试代码了。
- 20:59
- 浏览 (588)
- 评论 (4)
- 进入论坛
- 发布在 JBoss SEAM 圈子
- 相关推荐
评论
mygol
2008-01-24
DDD领域驱动设计结合seam不错。
hypercube1024
2007-12-28
这几天有时间的话准备写一下 第三章 视图与导航,但是有一个RichFaces的问题一直没解决-_-!,那就是我原本打算在 离开用户名输入框 的时候触发一个Ajax事件验证是否存在用户名,但是发现这样会报异常,只能在提交的时候触发Ajax事件验证用户名是否重复……
不知道哪位遇到过
不知道哪位遇到过
vtrtbb
2007-12-24
我在运用时候,我直接在coponents.xml里写了数据库session hs
<core:manager conversation-timeout="120000"
concurrent-request-timeout="500"
conversation-id-parameter="cid"/>
<persistence:hibernate-session-factory name="hibernateSessionFactory"/>
<persistence:managed-hibernate-session name="hs"
session-factory="#{hibernateSessionFactory}"
auto-create="true"/>
<transaction:hibernate-transaction session="#{hs}"/>
如果我在DAOImpl里引用这个hs,
public class userDAO {
@In private Session hs
public void saveUser(User user) {
hs.save(user);
}
}
那么
这个hs是空的,也就是说的不到数据库的链接
而在托管bean里却能得到,这是为什么
<core:manager conversation-timeout="120000"
concurrent-request-timeout="500"
conversation-id-parameter="cid"/>
<persistence:hibernate-session-factory name="hibernateSessionFactory"/>
<persistence:managed-hibernate-session name="hs"
session-factory="#{hibernateSessionFactory}"
auto-create="true"/>
<transaction:hibernate-transaction session="#{hs}"/>
如果我在DAOImpl里引用这个hs,
public class userDAO {
@In private Session hs
public void saveUser(User user) {
hs.save(user);
}
}
那么
这个hs是空的,也就是说的不到数据库的链接
而在托管bean里却能得到,这是为什么
nbaertuo
2007-12-24
如何把一个SESSION BEAN注入到另外一个SESSION BEAN中阿?
@In(value="chatroomAction")
ChatRoomAction chatroomAction;
这个代码老是报错:
Could not set field value by reflection: DepartMentAction.chatroomAction on: com.ctazc.zs.web.action.newuser.DepartMentAction with value: class org.javassist.tmp.java.lang.Object_$$_javassist_6
@In(value="chatroomAction")
ChatRoomAction chatroomAction;
这个代码老是报错:
Could not set field value by reflection: DepartMentAction.chatroomAction on: com.ctazc.zs.web.action.newuser.DepartMentAction with value: class org.javassist.tmp.java.lang.Object_$$_javassist_6
发表评论
提醒: 该博客已发表在公共论坛,博客所有留言会成为论坛回贴,留言请注意遵守论坛发贴规则
- 浏览: 556 次
- 性别:

- 来自: 武汉

- 详细资料
搜索本博客
最近加入圈子
最新评论
-
Seam 使用心得(一)测试 ...
你好,我现在也在做jboss seam测试。用到home class在调用get ...
-- by bigcatJavaEye -
Seam 使用心得(二)接口 ...
DDD领域驱动设计结合seam不错。
-- by mygol -
Seam 使用心得(一)测试 ...
请教一个问题,比如在RegisterDataSet.xml中<users ...
-- by lucyuan -
Seam 使用心得(二)接口 ...
这几天有时间的话准备写一下 第三章 视图与导航,但是有一个RichFaces的问 ...
-- by hypercube1024 -
Seam 使用心得(二)接口 ...
我在运用时候,我直接在coponents.xml里写了数据库session hs ...
-- by vtrtbb






评论排行榜