`
hypercube1024
  • 浏览: 85241 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Seam 使用心得(二)接口实现

    博客分类:
  • seam
阅读更多
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命令来运行上一节写好的测试代码了。
分享到:
评论
4 楼 mygol 2008-01-24  
DDD领域驱动设计结合seam不错。
3 楼 hypercube1024 2007-12-28  
这几天有时间的话准备写一下 第三章 视图与导航,但是有一个RichFaces的问题一直没解决-_-!,那就是我原本打算在 离开用户名输入框 的时候触发一个Ajax事件验证是否存在用户名,但是发现这样会报异常,只能在提交的时候触发Ajax事件验证用户名是否重复……

不知道哪位遇到过
2 楼 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里却能得到,这是为什么
 

 

1 楼 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

相关推荐

    seamcarving主要部分matlab实现

    在MATLAB中,可以使用二维数组来记录已经找到的seam,避免重复。 ### 5. 压缩与解压缩 在MATLAB中,一旦seams被确定,就可以进行图像的压缩和解压缩操作。压缩是通过删除seams来减小图像的宽度或高度,而解压缩则...

    seam一些基本功能的实现方法

    PDM_IV_Report_SEAM.pdf可能是Seam在项目中的一个报告或者教程,详细解释了如何使用Seam实现产品数据管理和报告生成。这样的文档通常会包含实际代码示例,解释如何配置Seam组件,如何处理数据库交互,以及如何利用...

    seam_carving 代码实现 seam

    在实际编程中,Seam Carving 的代码实现涉及以下几个关键步骤: 1. **能量图计算**: 根据选定的能量函数计算每个像素的能量值。 2. **拉链查找**: 使用优先队列或A*搜索算法找到最低能量路径。 3. **像素操作**: ...

    Seam Carving的C++实现代码

    在C++中实现Seam Carving,通常会用到OpenCV库,这是一个强大的计算机视觉库,提供了丰富的图像处理函数。以下是对Seam Carving实现过程的详细说明: 1. **读取图像**:首先,我们需要使用OpenCV的`imread`函数读取...

    SEAM 中文开发指南

    - **工作原理**:此示例展示了如何使用 SEAM 的工作空间管理功能来实现问题跟踪系统。 ##### 1.9 结合Seam和Hibernate的示例:Hibernate预订系统 - **代码分析**:利用 SEAM 和 Hibernate 实现宾馆预订系统。 - *...

    Seam框架文档简述

    Seam使用Java 5的注解实现了双向注射机制。这种机制比传统的依赖注入更加灵活,它可以实现组件之间的动态绑定,并且支持上下文相关的绑定。 ##### 6. 使用注解配置 Seam鼓励使用Java 5的注解特性来配置应用,这种...

    Jboss Seam中文版

    6. **使用Seam工作空间管理的完整范例:IssueTracker**:介绍了一个问题追踪系统的实现过程,强调了Seam在多用户协作方面的优势。 7. **结合Seam和Hibernate的范例:Hibernate系统**:展示了一个利用Seam和Hibernate...

    使用 Maven 管理 Seam 项目

    本篇文章将深入探讨如何使用Maven来管理Seam项目,一个基于Java EE的轻量级框架,专为富互联网应用程序(RIA)设计。 Seam项目是一个集成框架,它将JSF、EJB、CDI、JPA等Java EE技术紧密融合,提供了丰富的功能和...

    jboss seam 学习资料,seam in action和官方手册

    8. **Seam组件**:了解如Conversation、Transactions、邮件服务等Seam内置组件的使用方法。 9. **实时性与Ajax**:探索Seam如何实现实时更新和Ajax功能,提升用户体验。 ### Seam官方参考手册 Seam官方参考手册...

    jboss seam 教程

    - **使用JSF 1.2 RI**:提供了如何在JBoss平台上使用JSF 1.2参考实现来部署和运行Seam应用的具体步骤。 #### 三、结语 通过以上内容的学习,读者可以全面了解JBoss Seam框架的核心功能和技术特点,掌握如何使用...

    jboss seam 2.01GA REF DOC

    - 使用 JSF 组件和 Seam 功能实现页面逻辑。 - **1.2.1.10 EAR 部署描述符:application.xml** - 此文件定义了应用的整体结构和依赖关系。 - 包括模块列表和其他元数据。 **1.2.2 工作原理** - **Seam 组件**...

    Seam in Action

    Seam简化了EJB的使用,不需要繁琐的接口和Home接口,可以直接在组件中定义服务方法,降低了学习和使用的难度。 JPA是Java EE的标准持久化框架,Seam与JPA的集成使得数据库操作更加透明。开发者可以通过简单的注解,...

    Seam security

    Seam Security以易于配置和使用为特点,允许开发者快速设置应用程序的安全性,并随着应用的成熟易于管理。 1. 安全原则:Seam Security围绕几个关键的安全原则构建,包括身份认证、身份管理和授权控制。身份认证是...

    Matlab实现SeamCarving算法 放大缩小图片(包含GUI)

    在Matlab中实现SeamCarving算法,可以为图像的无损缩放提供一种有效的方法。下面我们将深入探讨这个算法及其在Matlab中的实现。 SeamCarving算法的核心思想是找到能量最小的接缝,以减少对图像视觉质量的影响。在...

    JBOSS SEAM组件中文手册

    **二、Seam核心概念** 1. **组件(Components)**: Seam的核心是组件模型,它允许开发者定义和管理应用中的对象。组件可以是简单的Java类,也可以是EJB或JSF Managed Beans。Seam自动管理组件的生命周期,包括创建、...

    MATLAB_Seam_Carving_seamcarving_

    在MATLAB中,可以使用以下步骤实现seam carving: 1. 读取图像并将其转换为灰度图像。 2. 计算图像的能量图,通常是图像的梯度绝对值。 3. 实现seam的查找算法,找到一条或多条低能量的路径。 4. 根据需要调整图像...

    seam_in_action

    - **第5章:Seam组件描述符**:介绍如何使用 Seam 组件描述符来定义组件的行为和配置。 - **第6章:绝对控制反转**:详细介绍 Seam 的绝对控制反转机制,以及它如何优化组件间的依赖管理。 ### 三、Seam的特点与...

    用Python实现的Seam Carving算法

    用Python实现的Seam Carving算法,参考资料https://karthikkaranth.me/blog/implementing-seam-carving-with-python

    seam的使用说明文档

    #### 二、Seam示例详解 在Seam框架提供的示例中,包含了多个具体应用场景下的实践案例,这些例子不仅帮助开发者快速上手Seam,还能深入理解框架的设计思想和技术细节。 ##### 1. 注册示例 (Registration Example) -...

    seam in action 中文 english

    7. **国际化与本地化**:Seam支持多语言环境,对于中英文双语版本的书籍,这为开发者提供了跨越语言障碍的便利,帮助全球的开发者理解和使用Seam框架。 8. **测试支持**:Seam提供了一套完整的测试工具,包括单元...

Global site tag (gtag.js) - Google Analytics