Java里提倡使用面向接口编程以减弱组件之间的耦合,在上一篇里已经定义了
@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命令来运行上一节写好的测试代码了。
分享到:
- 2007-12-19 20:59
- 浏览 1869
- 评论(4)
- 论坛回复 / 浏览 (4 / 4142)
- 查看更多
相关推荐
在MATLAB中,可以使用二维数组来记录已经找到的seam,避免重复。 ### 5. 压缩与解压缩 在MATLAB中,一旦seams被确定,就可以进行图像的压缩和解压缩操作。压缩是通过删除seams来减小图像的宽度或高度,而解压缩则...
PDM_IV_Report_SEAM.pdf可能是Seam在项目中的一个报告或者教程,详细解释了如何使用Seam实现产品数据管理和报告生成。这样的文档通常会包含实际代码示例,解释如何配置Seam组件,如何处理数据库交互,以及如何利用...
在实际编程中,Seam Carving 的代码实现涉及以下几个关键步骤: 1. **能量图计算**: 根据选定的能量函数计算每个像素的能量值。 2. **拉链查找**: 使用优先队列或A*搜索算法找到最低能量路径。 3. **像素操作**: ...
在C++中实现Seam Carving,通常会用到OpenCV库,这是一个强大的计算机视觉库,提供了丰富的图像处理函数。以下是对Seam Carving实现过程的详细说明: 1. **读取图像**:首先,我们需要使用OpenCV的`imread`函数读取...
- **工作原理**:此示例展示了如何使用 SEAM 的工作空间管理功能来实现问题跟踪系统。 ##### 1.9 结合Seam和Hibernate的示例:Hibernate预订系统 - **代码分析**:利用 SEAM 和 Hibernate 实现宾馆预订系统。 - *...
Seam使用Java 5的注解实现了双向注射机制。这种机制比传统的依赖注入更加灵活,它可以实现组件之间的动态绑定,并且支持上下文相关的绑定。 ##### 6. 使用注解配置 Seam鼓励使用Java 5的注解特性来配置应用,这种...
6. **使用Seam工作空间管理的完整范例:IssueTracker**:介绍了一个问题追踪系统的实现过程,强调了Seam在多用户协作方面的优势。 7. **结合Seam和Hibernate的范例:Hibernate系统**:展示了一个利用Seam和Hibernate...
本篇文章将深入探讨如何使用Maven来管理Seam项目,一个基于Java EE的轻量级框架,专为富互联网应用程序(RIA)设计。 Seam项目是一个集成框架,它将JSF、EJB、CDI、JPA等Java EE技术紧密融合,提供了丰富的功能和...
8. **Seam组件**:了解如Conversation、Transactions、邮件服务等Seam内置组件的使用方法。 9. **实时性与Ajax**:探索Seam如何实现实时更新和Ajax功能,提升用户体验。 ### Seam官方参考手册 Seam官方参考手册...
- **使用JSF 1.2 RI**:提供了如何在JBoss平台上使用JSF 1.2参考实现来部署和运行Seam应用的具体步骤。 #### 三、结语 通过以上内容的学习,读者可以全面了解JBoss Seam框架的核心功能和技术特点,掌握如何使用...
- 使用 JSF 组件和 Seam 功能实现页面逻辑。 - **1.2.1.10 EAR 部署描述符:application.xml** - 此文件定义了应用的整体结构和依赖关系。 - 包括模块列表和其他元数据。 **1.2.2 工作原理** - **Seam 组件**...
Seam简化了EJB的使用,不需要繁琐的接口和Home接口,可以直接在组件中定义服务方法,降低了学习和使用的难度。 JPA是Java EE的标准持久化框架,Seam与JPA的集成使得数据库操作更加透明。开发者可以通过简单的注解,...
Seam Security以易于配置和使用为特点,允许开发者快速设置应用程序的安全性,并随着应用的成熟易于管理。 1. 安全原则:Seam Security围绕几个关键的安全原则构建,包括身份认证、身份管理和授权控制。身份认证是...
在Matlab中实现SeamCarving算法,可以为图像的无损缩放提供一种有效的方法。下面我们将深入探讨这个算法及其在Matlab中的实现。 SeamCarving算法的核心思想是找到能量最小的接缝,以减少对图像视觉质量的影响。在...
**二、Seam核心概念** 1. **组件(Components)**: Seam的核心是组件模型,它允许开发者定义和管理应用中的对象。组件可以是简单的Java类,也可以是EJB或JSF Managed Beans。Seam自动管理组件的生命周期,包括创建、...
在MATLAB中,可以使用以下步骤实现seam carving: 1. 读取图像并将其转换为灰度图像。 2. 计算图像的能量图,通常是图像的梯度绝对值。 3. 实现seam的查找算法,找到一条或多条低能量的路径。 4. 根据需要调整图像...
- **第5章:Seam组件描述符**:介绍如何使用 Seam 组件描述符来定义组件的行为和配置。 - **第6章:绝对控制反转**:详细介绍 Seam 的绝对控制反转机制,以及它如何优化组件间的依赖管理。 ### 三、Seam的特点与...
用Python实现的Seam Carving算法,参考资料https://karthikkaranth.me/blog/implementing-seam-carving-with-python
#### 二、Seam示例详解 在Seam框架提供的示例中,包含了多个具体应用场景下的实践案例,这些例子不仅帮助开发者快速上手Seam,还能深入理解框架的设计思想和技术细节。 ##### 1. 注册示例 (Registration Example) -...
7. **国际化与本地化**:Seam支持多语言环境,对于中英文双语版本的书籍,这为开发者提供了跨越语言障碍的便利,帮助全球的开发者理解和使用Seam框架。 8. **测试支持**:Seam提供了一套完整的测试工具,包括单元...