论坛首页 Java企业应用论坛

为什么我的程序传递DTO

浏览 41869 次
该帖已经被评为精华帖
作者 正文
   发表时间:2006-03-20  
partech 写道
firebody 写道
早点放出这个图就好了。 哈哈。
看到这个图,我明了你的设计意图了。 在Client段通过Remote,直接调用服务端的接口 ,这样的话,DTO的设计就是比较合理的。
整个架构设计很清晰,也是很合理的。
后面的DTO assember在清晰的架构下,也是可以接受的。
可能我一直没有接触到RIA C/s开发模式,其实我前面的讨论一直是B/s的设计遗毒,有点空对空了。

不过,在这个架构的基础上,引入我上面所说的平面数据/数据转换层的设计,不知道会不会在整体架构上会有一个提高就很难说了。我有时间会继续关注这个问题,如果引入我这个设计的话,这样的一个设计会有什么优缺点呢?

对比与上图的DTO模式,一个精巧的类似webwork的模式引入到Server端的Service实现,这样是否会更好一些呢? 讨论一下。。。

我不清楚是否是因为基于B/S结构的程序,表示层在Server上有部分代码,所以没用注意划分表示层和Service层的边界。
实际上,上面的结构在不是RichClient,不需要Remoting的情况下,同样适用。服务层接口明确的定义了,服务层的职责,表示层通过服务接口提供的服务来实现,交互逻辑,提供界面展示,对于RCP或AJAX模式,表示层进而又可以划分为两个子层View,PresentationModel。这是另外一个话题,这里就不展开了。

从Service层关联的上下两层,可以看出,Service层的职责,就是在Domain层边界,处理那些不属于业务范畴的相关事宜,包括:将表示层的业务调用,委托给相应的DomainObject。负责双向的数据转换(包括异常的转换),处理事务等。数据转换是一个相对独立的职责,并且,多个Service中可能包含相同的转换,所以才出现了assembler。

你引入的扩展,俺还不甚明了。文件给你。show一下你的idea吧。

我这里没有Viso ,只能用文字大概描述一下了。
将Xwork的整体设计引入到你的Server端的Service实现,一个统一的入口Service,作专门的Request Dispatcher,就象Webwork的入口Servlet一样,具体的完成客户端某个请求的动作是由Action来完成的。 Xwork已经提供了整体的设计和扩展,Action的运行结果以Result为扩展接口,我们这里的Result一般是一个XML摸板,填充摸板的数据(也就是PO)由Action提供或者也可以PO数据直接放到摸板上下文中,生成的XML数据直接通过IO接口发回客户端。
我想这样的设计思路,曹晓刚或者Dlee他们应该更有发言权,我也是天马行空的想了一下。
整体的边界的输入输出都是XML。

如果你你没有看过Xwork/ognl的结合,我这里具一个简单的例子:
一个更新User的请求:
<Request actionId="updateUser">
<field name="userId">1</field>
<field name="user.userName">newName</field>
<field name="user.age">13</field>
</Request>


数据转换层职责就是Parse这个请求XML报文,ActionDispatcher根据actionId定位到这么一个Action:
class UpdateUserAction implements Action{
  private User user;
  private String userId;
 private UserService userService;
  public void setUserId(String userId);{
            this.user= userService.findUserById(usertId);:
  }
  public User getUser();{
    return this.user; 
 }
  public string execute();{
      this.userService.updateUser(user);; 
      return "success"; 
 }

}


实例一个Action对象,然后通过OGNL将请求参数自动设置到Action中,一个动作自动执行序列如下:

action.setUserId(1);;
action.getUser();.setUserName("newName");;
最后通过一些列的Xwork拦截器调用之后,执行
action.execute();.

返回Success,根举返回的result String,找到定义的摸板,再以这个执行完动作的Action实例作为template的Context,声称结果XML。
0 请登录后投票
   发表时间:2006-03-21  
firebody 写道
我这里没有Viso ,只能用文字大概描述一下了。
将Xwork的整体设计引入到你的Server端的Service实现,一个统一的入口Service,作专门的Request Dispatcher,就象Webwork的入口Servlet一样,具体的完成客户端某个请求的动作是由Action来完成的。 Xwork已经提供了整体的设计和扩展,Action的运行结果以Result为扩展接口,我们这里的Result一般是一个XML摸板,填充摸板的数据(也就是PO)由Action提供或者也可以PO数据直接放到摸板上下文中,生成的XML数据直接通过IO接口发回客户端。
我想这样的设计思路,曹晓刚或者Dlee他们应该更有发言权,我也是天马行空的想了一下。
整体的边界的输入输出都是XML。

如果你你没有看过Xwork/ognl的结合,我这里具一个简单的例子:
一个更新User的请求:
<Request actionId="updateUser">
<field name="userId">1</field>
<field name="user.userName">newName</field>
<field name="user.age">13</field>
</Request>


数据转换层职责就是Parse这个请求XML报文,ActionDispatcher根据actionId定位到这么一个Action:
class UpdateUserAction implements Action{
  private User user;
  private String userId;
 private UserService userService;
  public void setUserId(String userId);{
            this.user= userService.findUserById(usertId);:
  }
  public User getUser();{
    return this.user; 
 }
  public string execute();{
      this.userService.updateUser(user);; 
      return "success"; 
 }

}


实例一个Action对象,然后通过OGNL将请求参数自动设置到Action中,一个动作自动执行序列如下:

action.setUserId(1);;
action.getUser();.setUserName("newName");;
最后通过一些列的Xwork拦截器调用之后,执行
action.execute();.

返回Success,根举返回的result String,找到定义的摸板,再以这个执行完动作的Action实例作为template的Context,声称结果XML。

如果PO都是在Action中修改完成,那么留给Service和Domain层的还有多少东西呢?
如此一个修改用户的服务,我会在Service后面或Domain中,处理修改PO的业务逻辑,简化版本的实现如下:

public interface IUserService{
     void  updateUser(String id,String name,int age...);;
}

public class UserService implements IUserService{
      public void updateUser(String id,String name,int age...);{
                  User user = User.getFinder();.findById(id);;    
                   user.setName(name);;
                   user.setAge(age);;
                   ......
      }
}

然后在Service方法上通过AOP辅以事务,就完成了,简化版本的业务。

下图是Service层应对WebService的Wrapper版本设计。正如你前面提到的方法,可以通过OGNL、CG或反射的方式,来编写通用的转化。一一对应的关系,甚至连一行配置都不需要。
0 请登录后投票
   发表时间:2006-03-21  
partech 写道
firebody 写道
我这里没有Viso ,只能用文字大概描述一下了。
将Xwork的整体设计引入到你的Server端的Service实现,一个统一的入口Service,作专门的Request Dispatcher,就象Webwork的入口Servlet一样,具体的完成客户端某个请求的动作是由Action来完成的。 Xwork已经提供了整体的设计和扩展,Action的运行结果以Result为扩展接口,我们这里的Result一般是一个XML摸板,填充摸板的数据(也就是PO)由Action提供或者也可以PO数据直接放到摸板上下文中,生成的XML数据直接通过IO接口发回客户端。
我想这样的设计思路,曹晓刚或者Dlee他们应该更有发言权,我也是天马行空的想了一下。
整体的边界的输入输出都是XML。

如果你你没有看过Xwork/ognl的结合,我这里具一个简单的例子:
一个更新User的请求:
<Request actionId="updateUser">
<field name="userId">1</field>
<field name="user.userName">newName</field>
<field name="user.age">13</field>
</Request>


数据转换层职责就是Parse这个请求XML报文,ActionDispatcher根据actionId定位到这么一个Action:
class UpdateUserAction implements Action{
  private User user;
  private String userId;
 private UserService userService;
  public void setUserId(String userId);{
            this.user= userService.findUserById(usertId);:
  }
  public User getUser();{
    return this.user; 
 }
  public string execute();{
      this.userService.updateUser(user);; 
      return "success"; 
 }

}


实例一个Action对象,然后通过OGNL将请求参数自动设置到Action中,一个动作自动执行序列如下:

action.setUserId(1);;
action.getUser();.setUserName("newName");;
最后通过一些列的Xwork拦截器调用之后,执行
action.execute();.

返回Success,根举返回的result String,找到定义的摸板,再以这个执行完动作的Action实例作为template的Context,声称结果XML。

如果PO都是在Action中修改完成,那么留给Service和Domain层的还有多少东西呢?
如此一个修改用户的服务,我会在Service后面或Domain中,处理修改PO的业务逻辑,简化版本的实现如下:

public interface IUserService{
     void  updateUser(String id,String name,int age...);;
}

public class UserService implements IUserService{
      public void updateUser(String id,String name,int age...);{
                  User user = User.getFinder();.findById(id);;    
                   user.setName(name);;
                   user.setAge(age);;
                   ......
      }
}

然后在Service方法上通过AOP辅以事务,就完成了,简化版本的业务。

下图是Service层应对WebService的Wrapper版本设计。正如你前面提到的方法,可以通过OGNL、CG或反射的方式,来编写通用的转化。一一对应的关系,甚至连一行配置都不需要。

从上图我更加困惑,甚至怀疑我们的交流是否互相误解。
我所提到的引入Xwork/XML框架优势之一就是消除DTO的引入,但是看了你的上图,既说引入OGNL和XML,又在后面引入DTO作为数据载体,Assembler的代码仍然充斥其中,如果是这样,那还不如直接用DTO好了。

引入Xwork之后,Service只依赖于PO也就是领域模型实体。
这里可能有些概念冲突,在你的设计中,Service是充当Facade的作用的,而我这里可能与你的Service同等概念的是 :Action 。
另外,对于你的原来Service依赖的DTO,现在已经转为XML,你的设计需要对DTO进行Assemler(DTO--->PO) ,对应的,Xwork的设计(XML--->PO),这个转换过程是在数据转换层自动完成的。
这样依赖,就省掉了DTO的设计和引入DTO Assembler的设计。
0 请登录后投票
   发表时间:2006-03-21  
firebody 写道
从上图我更加困惑,甚至怀疑我们的交流是否互相误解。
我所提到的引入Xwork/XML框架优势之一就是消除DTO的引入,但是看了你的上图,既说引入OGNL和XML,又在后面引入DTO作为数据载体,Assembler的代码仍然充斥其中,如果是这样,那还不如直接用DTO好了。

赫赫,哪有那么多误解?
没错service后面的assembler可以采用Xwork/XML的方式来实现。
但是,Client就一定要接受XML吗?在都是java的环境下,直接传递java对象,会更有效率。由于采用XML接口的Client(如AJAX),不过是调用的机制不同而已。所以可以简单的,把从java接口的调用转化为XML的调用。
下图中,后台服务,同时可以支持多种访问途经。
0 请登录后投票
   发表时间:2006-03-21  
partech 写道
firebody 写道
从上图我更加困惑,甚至怀疑我们的交流是否互相误解。
我所提到的引入Xwork/XML框架优势之一就是消除DTO的引入,但是看了你的上图,既说引入OGNL和XML,又在后面引入DTO作为数据载体,Assembler的代码仍然充斥其中,如果是这样,那还不如直接用DTO好了。

赫赫,哪有那么多误解?
没错service后面的assembler可以采用Xwork/XML的方式来实现。
但是,Client就一定要接受XML吗?在都是java的环境下,直接传递java对象,会更有效率。由于采用XML接口的Client(如AJAX),不过是调用的机制不同而已。所以可以简单的,把从java接口的调用转化为XML的调用。
下图中,后台服务,同时可以支持多种访问途经。

从你的设计来看,我觉得我们对待这个问题还是有不同的设计的。 其实说到底,就是不用DTO,而是使用XML。这么一个核心的区别。

你后面提供的图,说白了就是你原来的设计框架+加上一个XML Assembler。
核心还是以DTO为主要数据载体,不同的接口都是在DTO和外部数据之间做转换。
如果这是一个已有系统的改造,毫无疑问,这是可行的。
但是如果是一个全新的设计,我觉得我们讨论的重点就在于是否使用DTO。

我不知道我所提到的观点和论据,你是否有更多额辩解 。 
0 请登录后投票
   发表时间:2006-03-21  
firebody 写道
从你的设计来看,我觉得我们对待这个问题还是有不同的设计的。 其实说到底,就是不用DTO,而是使用XML。这么一个核心的区别。

你后面提供的图,说白了就是你原来的设计框架+加上一个XML Assembler。
核心还是以DTO为主要数据载体,不同的接口都是在DTO和外部数据之间做转换。
如果这是一个已有系统的改造,毫无疑问,这是可行的。
但是如果是一个全新的设计,我觉得我们讨论的重点就在于是否使用DTO。

我不知道我所提到的观点和论据,你是否有更多额辩解 。 

是的,我同意你对我的方案的看法。那不过是一个简单的封装。
要说到差别,上面我问了一个问题,“是否Client端就一定要用XML呢”?
从效率的角度上看,基于XML的调用,大概会比直接传递javaDTO对象,慢一个数量级。虽说XML确实有它的好处,但缺点也同样明显。另外,如果是java客户端,不可避免,在客户端,还需要再解析为javaDTO,如果不转换,java中直接使用XML,方便性就会大打折扣。
如果,你认为传递XML方式在任何情况下,都能够满足要求,那么,不使用javaDTO,也没啥不可。
使用javaDTO,在效率和编程一致上,确实是有优势的。

另外,一个差别就是对service的使用,我确实看不出你把部分业务代码放到Action里面,有啥额外的好处。
0 请登录后投票
   发表时间:2006-03-21  
partech 写道
firebody 写道
从你的设计来看,我觉得我们对待这个问题还是有不同的设计的。 其实说到底,就是不用DTO,而是使用XML。这么一个核心的区别。

你后面提供的图,说白了就是你原来的设计框架+加上一个XML Assembler。
核心还是以DTO为主要数据载体,不同的接口都是在DTO和外部数据之间做转换。
如果这是一个已有系统的改造,毫无疑问,这是可行的。
但是如果是一个全新的设计,我觉得我们讨论的重点就在于是否使用DTO。

我不知道我所提到的观点和论据,你是否有更多额辩解 。 

是的,我同意你对我的方案的看法。那不过是一个简单的封装。
要说到差别,上面我问了一个问题,“是否Client端就一定要用XML呢”?
从效率的角度上看,基于XML的调用,大概会比直接传递javaDTO对象,慢一个数量级。虽说XML确实有它的好处,但缺点也同样明显。另外,如果是java客户端,不可避免,在客户端,还需要再解析为javaDTO,如果不转换,java中直接使用XML,方便性就会大打折扣。
如果,你认为传递XML方式在任何情况下,都能够满足要求,那么,不使用javaDTO,也没啥不可。
使用javaDTO,在效率和编程一致上,确实是有优势的。

另外,一个差别就是对service的使用,我确实看不出你把部分业务代码放到Action里面,有啥额外的好处。

如果是这样的设计架构的话,那么客户端就没必要再转换为JavaDTO了,客户端的数据模型就是以XML为主了,至于说java parse XML接口会不会带来开发的方便性,我觉得这是很片面的观点。 如果作为一个架构的设计的话,我想你们开发组会专门封装一个read/write XML的接口的,这样的接口易用性的设计就是负责开发这个接口的设计的问题了。
0 请登录后投票
   发表时间:2006-03-21  
firebody 写道
如果是这样的设计架构的话,那么客户端就没必要再转换为JavaDTO了,客户端的数据模型就是以XML为主了,至于说java parse XML接口会不会带来开发的方便性,我觉得这是很片面的观点。 如果作为一个架构的设计的话,我想你们开发组会专门封装一个read/write XML的接口的,这样的接口易用性的设计就是负责开发这个接口的设计的问题了。

虽然,一些混合java类和XML的编程方式,在不断的吸引我们的眼球,但我不认为,已经达到了无缝结合的地步。表示层,使用XML,不仅仅只是读写,比如:数据绑定问题如何解决?如果你认为XML可以媲美于java对象的使用,那俺也没啥好说的。另外,效率方面的问题,可以完全忽略麽?

前阵子研究了一下,基于EMF实现的SDO,结构很小,很优美。但对SDO的支持,却少得可怜。

如果,SDO哪天,能够满足我的各种要求,那么我会毫不犹豫地抛开javaDTO,投向SDO的怀抱。但在这之前,javaDTO就是我的选择。

http://java.sys-con.com/read/46652.htm
0 请登录后投票
   发表时间:2006-03-21  
partech 写道
firebody 写道
如果是这样的设计架构的话,那么客户端就没必要再转换为JavaDTO了,客户端的数据模型就是以XML为主了,至于说java parse XML接口会不会带来开发的方便性,我觉得这是很片面的观点。 如果作为一个架构的设计的话,我想你们开发组会专门封装一个read/write XML的接口的,这样的接口易用性的设计就是负责开发这个接口的设计的问题了。

虽然,一些混合java类和XML的编程方式,在不断的吸引我们的眼球,但我不认为,已经达到了无缝结合的地步。表示层,使用XML,不仅仅只是读写,比如:数据绑定问题如何解决?如果你认为XML可以媲美于java对象的使用,那俺也没啥好说的。另外,效率方面的问题,可以完全忽略麽?

前阵子研究了一下,基于EMF实现的SDO,结构很小,很优美。但对SDO的支持,却少得可怜。

如果,SDO哪天,能够满足我的各种要求,那么我会毫不犹豫地抛开javaDTO,投向SDO的怀抱。但在这之前,javaDTO就是我的选择。

http://java.sys-con.com/read/46652.htm

操纵XML确实没有Object要来的直接。 如果要达到直接数据绑定,可能这对客户端XML接口设计的要求比较高。
你说的数据绑定的难题,可以举个例子吗?
效率方面的问题,我认为跟你选择Parser很有关系,我推荐使用SaxParser,不过性能一般不会很差。
0 请登录后投票
   发表时间:2006-03-21  
firebody 写道
操纵XML确实没有Object要来的直接。 如果要达到直接数据绑定,可能这对客户端XML接口设计的要求比较高。
你说的数据绑定的难题,可以举个例子吗?
效率方面的问题,我认为跟你选择Parser很有关系,我推荐使用SaxParser,不过性能一般不会很差。

就像http://www.martinfowler.com/eaaDev/PresentationModel.html里面描述的绑定。View同PresentationModel之间的绑定。即使采用ajax,我同样可以采用PresentationModel的结构。

效率不光在解析上,比较一下Remoting的效率,差别是明显的。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics