`
carlkkx
  • 浏览: 16405 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

JavaBean和FieldMap 静态定义和动态构建孰优孰劣?

阅读更多
我们来看一个JavaBean
class Bond{
private String id;
private String name;

public void setId(String id){
    this.id = id;
}

public String getId(){
    return this.id;
}

public void setName(String name){
    this.name = name;
}

public String getName(){
    return this.name;
}

然后我们来看看对应的FieldMap如何描述:
FieldMap fm = new FieldMap("Bond").putField("id","060001").putField("name","06国债01");

看起来FieldMap简洁许多,毕竟一个是静态定义一个是动态构建,一个强类型一个弱类型。
假设现在要为Bond这个类型加入发行价格和发行日期这两个属性,这时候定义JavaBean时我们将会陷入一个考量,定义什么类型,比如发行日期我们定义Date呢还是字符串?价格定义double呢还是字符串?对于拿日期来做计算或比较的,显然定义Date更合理,如果拿来是显示的显然某种格式的字符串更合适。无论你怎么定义在遇到不同场景时,必然要来回折腾转换,极为不便。
那FieldMap如何处理这样的问题呢?
假设某个Field是发行日期,它的name是iDate,像下面这样我们拿到的是什么?
fieldMap.getField("iDate").getValue();

答案是构造这个FieldMap时放的什么值就是什么值,比如有可能是yyyyMMdd格式的日期字符串,有可能是java的Date类型,如果你仅仅调用getValue(),那么你得到的是当初放的那个值,但是因为你知道这个Field叫iDate,里面的值一定是个日期,所以你有时候说我希望要拿Date,有时候希望要拿某种格式的字符串。因此你不仅仅可以调用Field的getValue(),你还可以这样:
fieldMap.getField("iDate").getDateValue();
fieldMap.getField("iDate").getDateStringValue();
fieldMap.getField("iDate").getDateStringValue("yyyy/MM/dd");

第一个你将直接拿到Date类型,第二个你将拿到yyyy-MM-dd格式的字符串,第三个你将拿到你自定义格式的日期字符串,比如这里就是yyyy/MM/dd。
很明显看到这里我们发现FieldMap灵活便利的多,因为即使对于同一个类型,它也有很多不同的形式。
分享到:
评论
21 楼 vlinux 2009-12-01  
whaosoft 写道
没有 用过FieldMap ~

FieldMap只是LZ自己定义的数据结构罢了,呵呵。
我在想,是不是可以用来解决我的一些问题,因为目前我遇到的情况是:后台查询出的结构,我如果定义成JavaBean去与之绑定,那么我的JavaBean复用率非常低...此时如果我每个请求都必须用2个甚至多个JavaBean去映射,那我的类会无限膨胀...而且是事实我已经遇到了...

当然,我前边反对的观点是建立在作为后台稳定通用接口上的,此时JavaBean的复用率比较高,用JavaBean绑定XML的方式是要比FieldMap合适。
20 楼 vlinux 2009-12-01  
carlkkx 写道
vlinux 写道
接口就是要隔离你们之间的实现。你不用关心他是怎么解析这个XML的,你要做的不应该只是想办法让你的JavaBean能和这个约定的XML进行绑定么?
你现在作的FieldMap其实也是要想办法将数据绑定到对方定制的XML上而已,但是事实上我们有更灵活的轮子,有很多种框架能将JavaBean和XML数据进行相互绑定、转换的,你不妨可以找找。

也许在我方本更不存在静态定义的javaBean,假设现在突然来了个需求,说客户希望能查询XXX数据,这个时候服务端给出了请求和响应的XML格式,然后客户端开发人员对于这份数据也许压根就不会定义一个静态的JavaBean,原来的话,直接解析XML得到数据然后放到GUI,现在话可能不用解析XML了,直接拿到FieldMap数据结构然后让其显示到GUI。

恩,这里细细品味还是有点味道,因为之前,恩应该说现在正在遇到这种情况。我确实被迫定义了非常多的JavaBean去对付来自后台的查询(一个查询接口得两个JavaBean去映射,请求一个,返回一个,甚至两个)。如果用这样的数据结构确实能解决我不少的问题,不过我还可以直接用JQuery去解析那些XML报文为JSON对象,这是我之前考虑的解决方案。
你觉得呢?用JavaScript去解析XML为JSON对象你觉得怎样?
19 楼 whaosoft 2009-12-01  
没有 用过FieldMap ~
18 楼 vlinux 2009-12-01  
carlkkx 写道

其实并不仅仅是绑定,还有动态构建,就是一开时标题所讲的。因为某一方也许本更就没有静态定义了这样一个数据结构,比如服务方给出了一个XML,那这个XML就是定义,现在通信模块会自动将这个XML构建为FieldMap或FieldMapSet,然后客户端可以直接利用这个FieldMap数据结构,而这个FieldMap并没有预先定义的。所以情况是不仅仅是想办法将数据绑定到对方定制的XML上,而是直接从对方定制的XML上动态构建数据结构。所以客户端数据结构非常轻量,因为没有定义大量的数据类。


恩恩.
我遇到过两种情况
1.作为外部的XML接口
作为约定的XML一般不会轻易更改,如果约定的报文需要更改,不仅要开会讨论,编写概要设计,制定开发计划,上线计划等等。接口不是我们自己内部的interface,想改变就改变的,牵扯到那么多厂商的利益。
2.作为内部的XML接口
内部的接口也不是说想动就动的,你至少得和后台c++开发人员进行沟通。

还有,以上两种情况都不能逃避一个问题:数据用到那里去?你的方法解决的只是解决你那端的数据来源问题,但是并没有解决你是怎么使用这些数据的。

并且,如果是用在多个WEB页面的展示上,我可以想象到你满地都是
fieldMap.getField("iDate").getDateStringValue("yyyy/MM/dd");

的场景,但是突然要更改为yyyy-MM-dd,你就不及其被动了么?用POJO作为Model还是非常有他的实用价值的。

以上只是企图说明,如果XML报文修改,那么在这个修改所导致的工作量中,修改作为XML映射JavaBean的工作量是非常小且可以忽略不计的,至少我的经历是这样。但是如果采用FieldMap的获取数据方式,那么我一旦修改XML报文,你的修改工作量就不止是一个地方的getDateStringValue了
17 楼 carlkkx 2009-12-01  
引用

你现在作的FieldMap其实也是要想办法将数据绑定到对方定制的XML上而已,但是事实上我们有更灵活的轮子,有很多种框架能将JavaBean和XML数据进行相互绑定、转换的,你不妨可以找找。

其实并不仅仅是绑定,还有动态构建,就是一开时标题所讲的。因为某一方也许本更就没有静态定义了这样一个数据结构,比如服务方给出了一个XML,那这个XML就是定义,现在通信模块会自动将这个XML构建为FieldMap或FieldMapSet,然后客户端可以直接利用这个FieldMap数据结构,而这个FieldMap并没有预先定义的。所以情况是不仅仅是想办法将数据绑定到对方定制的XML上,而是直接从对方定制的XML上动态构建数据结构。所以客户端数据结构非常轻量,因为没有定义大量的数据类。
16 楼 carlkkx 2009-12-01  
后面其实还可以做更多自动化,比如设计FieldMap和GUI的绑定。
类似于设计这样的类:FieldMapFormBinder,FieldMapSetListBinder,FieldMapSetTable
然后类似于写下面这样的代码:
new FieldMapSetListBinder(你的JComboBox或JList).query("服务名",查询参数(当然也可能没有));

这样一行代码就完成了一个ComboBox列表的初始化了。
FieldMapFormBinder,FieldMapSetTable要更复杂一点,但是设计好如何方便的表达一些对应关系和转换,
也是可以类似这样做的。
15 楼 carlkkx 2009-11-30  
vlinux 写道
接口就是要隔离你们之间的实现。你不用关心他是怎么解析这个XML的,你要做的不应该只是想办法让你的JavaBean能和这个约定的XML进行绑定么?
你现在作的FieldMap其实也是要想办法将数据绑定到对方定制的XML上而已,但是事实上我们有更灵活的轮子,有很多种框架能将JavaBean和XML数据进行相互绑定、转换的,你不妨可以找找。

也许在我方本更不存在静态定义的javaBean,假设现在突然来了个需求,说客户希望能查询XXX数据,这个时候服务端给出了请求和响应的XML格式,然后客户端开发人员对于这份数据也许压根就不会定义一个静态的JavaBean,原来的话,直接解析XML得到数据然后放到GUI,现在话可能不用解析XML了,直接拿到FieldMap数据结构然后让其显示到GUI。
14 楼 carlkkx 2009-11-30  
引用

我也自己写过一些XML转换Bean的轮子,毕竟转换为强类型更能方便你在其他模块的编程,而且在转换的时候进行检查,明显的错误数据就应该拦截在接口层,不会让你将错误的业务数据带到DAO层、业务逻辑层甚至你永远都没发现...

这个,你说的有一定道理,但是如果客户端的话,也许本更没有静态定义一个Bean的必要,也许他从服务器拿到数据只是显示到GUI,也许GUI也可以更新,也许稍微会要做一些处理,但是笨重的静态定义一个Bean,有时候他们会觉得麻烦。而FieldMap没有静态定义的要求,它完全是动态构建的。
13 楼 vlinux 2009-11-30  
接口就是要隔离你们之间的实现。你不用关心他是怎么解析这个XML的,你要做的不应该只是想办法让你的JavaBean能和这个约定的XML进行绑定么?
你现在作的FieldMap其实也是要想办法将数据绑定到对方定制的XML上而已,但是事实上我们有更灵活的轮子,有很多种框架能将JavaBean和XML数据进行相互绑定、转换的,你不妨可以找找。
12 楼 carlkkx 2009-11-30  
引用

你这句我是不同意的,什么叫他们没有呢?他们已经能正确解析他们定的XML了。实际的情况是:他们有而你没有。你所要做的就是写一个轮子去将JavaBean序列化成服务器先定义的“伪”XML。

实际上原先应该说大家都没有,虽然他们当然能正确解析他们定的XML,但是他们很可能也是没什么自动化工具的,而是手动构建和解析的。我刚刚说他们没有是从我方的角度的,即如果是我方给出格式的话,他们可能就认为我方给的不方便他们的解析,所以从这个角度来说他们没有。当然现实是一般他们给出,所以他们是一哥。
当碰到两种不同语言(编程模型也不同)要沟通的时候,协议必然要在更低的层次上约定,这种更低层次上的协议虽然灵活,但是也麻烦。
11 楼 vlinux 2009-11-30  
carlkkx 写道

有人可能最先想到的是对象直接序列化成XML,但是直接序列化出来的结果未必符合服务器那边的格式要求,除非两边都有序列化和反序列化的工具才行,但是他们没有。所以就变成要XML手动构建手动解析,这实在太麻烦了。

你这句我是不同意的,什么叫他们没有呢?他们已经能正确解析他们定的XML了。实际的情况是:他们有而你没有。你所要做的就是写一个轮子去将JavaBean序列化成服务器先定义的“伪”XML。

carlkkx 写道
    其实一开始构建这个FieldMap原因是要和一个比较老的C语言写的服务器通信,那个服务器通信的协议格式是文本的,一种准XML格式,什么叫准XML格式就是一种不严格的XML。客户端是java写的,GUI基于Swing库的。麻烦之处在于通信API非常底层,基本上就是String来String去,当然对于java这边来说可以将这个String解析成XML Document,然后再解析,但是显然还是非常麻烦。协议一般双方约定,很有可能是服务器的人先给出,其实就是一份XML规格。


这种情况下,是可以利用自定义的Annotation进行format转换的,我也自己写过一些XML转换Bean的轮子,毕竟转换为强类型更能方便你在其他模块的编程,而且在转换的时候进行检查,明显的错误数据就应该拦截在接口层,不会让你将错误的业务数据带到DAO层、业务逻辑层甚至你永远都没发现...
@XML(nullable=false, regex="\\d{0,5}") private Integer spId;//sp编号
@XML(nullable=false, regex="\\d{0,5}") private Integer businessCode;//业务代码
@XML(nullable=false, regex="\\d{0,10}") private Integer locationId;//场地机构代号
@XML(nullable=false, maxByteLength=32) private String phoneReq;//请求手机号
@XML(nullable=false, maxByteLength=32) private String phoneRece;//接收手机号
@XML(maxByteLength=32) private String phoneType;//手机型号
@XML(format="yyyyMMdd") private Date vaildTime;//数据有效期


如果说要简洁,这样我觉得更简洁,不是么?

我觉得LZ的想法还是有他的价值的,但是不应该是用在JavaBean和XML数据的转换上,因为在这上边有更好的解决方法。哪怕使用在Http Form表单上,都已经有很多MVC框架自动帮你作好了,你也可以自定义格式。但是在一些小项目里,没有大框架支撑的时候,我认为LZ的工具就能发挥他的作用:将Form、Ajax提交上来的数据进行处理。但也应该是作成一个工具类,一个对String的扩展而存在
10 楼 carlkkx 2009-11-30  
    其实一开始构建这个FieldMap原因是要和一个比较老的C语言写的服务器通信,那个服务器通信的协议格式是文本的,一种准XML格式,什么叫准XML格式就是一种不严格的XML。客户端是java写的,GUI基于Swing库的。麻烦之处在于通信API非常底层,基本上就是String来String去,当然对于java这边来说可以将这个String解析成XML Document,然后再解析,但是显然还是非常麻烦。协议一般双方约定,很有可能是服务器的人先给出,其实就是一份XML规格。
    有人可能最先想到的是对象直接序列化成XML,但是直接序列化出来的结果未必符合服务器那边的格式要求,除非两边都有序列化和反序列化的工具才行,但是他们没有。所以就变成要XML手动构建手动解析,这实在太麻烦了。于是设计了一个FieldMap数据结构,然后底层的通信API再封装一下,看起来可以这样:
FieldMap fm = new FieldMap("Bond").putField("id","060001").putField("name","06国债01");  
CommonRemoteMsgService.requestRemoteService("服务名",fm,new CommonMsgCallback(){
    public void onMessage(CommonMsg msg){
        if(msg.isError()){
           //错误处理
        }
        else{
          //正常处理
          msg.getFieldMap();
        }
    }
});

上面这段会发向服务器这样的东西:
<?xml version="1.0" encoding="UTF-8" ?>
<Bond>
<id>060001</id>
<name>06国债01</name>
</Bond>
当然和服务器沟通的数据没有那么单纯,光靠FieldMap就可以描述的,所以还提供FieldMapSet。这样一来比起原来
代码更干净和简洁了。
9 楼 carlkkx 2009-11-30  
事实上我并不否定强类型也有它的好处,但是如果一个软件和另一个软件通信,通信数据结构这样定义会灵活方便很多。
8 楼 carlkkx 2009-11-30  
魔力猫咪 写道
JavaBean也是可以动态构建的。Struts的动态Form就是动态构建的。使用的是Apache Commons的提供的工具类。

但是还是有些差别,FieldMap中的Field定义了大量基本类型不同形式的便利方法。
除了上面的Date,还有比如对于数值类型的东西可以这样:
fieldMap.getField("amount").getNumberStringValue();
fieldMap.getField("amount").getNumberStringValue(2);
fieldMap.getField("amount").getDoubleValue();
fieldMap.getField("amount").getBigDecimalValue();
fieldMap.getField("amount").getIntValue();
7 楼 魔力猫咪 2009-11-30  
JavaBean也是可以动态构建的。Struts的动态Form就是动态构建的。使用的是Apache Commons的提供的工具类。
6 楼 carlkkx 2009-11-30  
mock1234 写道
干脆什么field都规定只能是字符串!

干脆规定不允许多个field,任何对象只允许定义一个field存个xml值,然后再解析。

干脆别写软件,让小学生随便写写。我们都想伟大的事。至于是否会造成网络瘫痪、火车翻车、银行错账、心脏起搏器突然加快1000倍、所有程序都缓慢10万倍......无所谓,只要编程的人觉得有优势就成。

LS这段话我有些不解了,至于这么气急败坏吗?
5 楼 carlkkx 2009-11-30  
icefire 写道
fieldMap.getField("iDate")
如果 iDate 是 MM/dd/yy 的格式字符串(02/03/09),
那fieldMap.getField("iDate").getDateStringValue("yyyy/MM/dd");会是怎样?

LS提的问题很好,这说明什么呢?说明使用FieldMap的双方还是要隐含着某种约定的,但是宽松多了,一方以他便利的方式塞Date,另一方以他便利的方式拿某种Date字符串格式,但是如果两方便利的都是字符串,而且还出现LS讲的情况,那么两方就不能各自独善其身。
4 楼 icefire 2009-11-30  
fieldMap.getField("iDate")
如果 iDate 是 MM/dd/yy 的格式字符串(02/03/09),
那fieldMap.getField("iDate").getDateStringValue("yyyy/MM/dd");会是怎样?
3 楼 carlkkx 2009-11-30  
evanerv0079 写道
请问FieldMap是指的那个

FieldMap是我自己定义的一个数据结构,这里要讨论的核心是当我要描述一个事物的时候,是采用静态定义的Bean呢还是动态构建的FieldMap。FieldMap显然要灵活的多。
2 楼 evanerv0079 2009-11-30  
请问FieldMap是指的那个

相关推荐

    JSP结合JavaBean生成静态页面示例

    2. **模板定义**:定义好静态页面的模板,即定义好页面的基本结构和样式。这部分内容可以在`JspToStaticHTMLTest`类中的`getHeadStr()`和`getTailStr()`方法中定义。 3. **内容填充**:将JavaBean中的数据填充到...

    javabean概念和使用

    JavaBean 概念和使用 JavaBean 是一种 JAVA 语言写成的可重用组件。为写成 JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性。...

    javabean和xml互相转换工具类以及jar包

    - **使用DOM(Document Object Model)**:通过创建Document对象,遍历JavaBean的属性,然后创建Element节点和Text节点,构建XML文档结构。 - **使用JAXB(Java Architecture for XML Binding)**:JAXB是Java标准...

    1.值JavaBean和工具JavaBean的区别.pdf

    值JavaBean和工具JavaBean的区别 JavaBean是一种特殊的Java类,它具有封装数据和提供公共方法的功能。在Java开发中,JavaBean通常被分为两类:值JavaBean和工具JavaBean。理解这两者的区别对于Java开发者来说是非常...

    JavaBean 方法的动态调用

    JavaBean的主要目的是提高代码的可维护性和可扩展性,通常用于构建用户界面组件或者作为数据传输对象。在JavaBean中,动态调用方法是一种强大的功能,允许我们在运行时决定调用哪个方法,这主要通过Java的反射机制...

    jsp+javabean构建的web工程

    综上所述,"jsp+javabean构建的web工程"是一个基础但实用的Web开发模式,它通过明确的角色分工,实现了动态网页的高效开发和维护。在实际项目中,开发者需要理解和掌握JSP的语法、JavaBean的设计以及MVC模式的应用,...

    动态生成javabean

    我们可以根据需求构建一个基础的JavaBean类,然后通过反射动态地添加属性并生成getter和setter方法。 3. **使用ASM、ByteBuddy等字节码库**:这些库提供了更底层的字节码操作能力,可以直接生成Java类的字节码,...

    JavaBean和JSP中的标准动作_总结与作业

    JavaBean和JSP是Java Web开发...总结,JavaBean和JSP标准动作是构建动态Web应用的关键工具,它们使得数据管理和页面交互变得更加简洁高效。理解并熟练运用这些概念和机制,对于成为一名合格的Java Web开发者至关重要。

    JavaBean简介

    JavaBean简介 什么是JavaBean? JavaBean的三个组成部分 JavaBean的基本特征 BeanInfo接口 JavaBean的开发模式 使用JavaBean开发应用程序 EJB简介

    JSON入门Java篇-5-用JavaBean来构建JSON.rar

    本教程将聚焦于如何使用JavaBean来构建JSON,帮助开发者更好地理解和运用这一技术。 一、JSON与JavaBean JSON是一种文本格式,易于人阅读和编写,同时也易于机器解析和生成。它基于JavaScript的一个子集,但并不...

    JAVABEAN

    JavaBean遵循特定的规范,使它们能够被其他Java应用或开发工具(如IDEs)识别、可视化和操作。JavaBean的主要目标是提供组件重用,简化开发过程,并促进软件的模块化。 标题"JAVABEAN"指的是这个项目或系统是基于...

    JSP+javaBean+数据库 无限级动态树状菜单

    综上所述,这个项目结合了JSP、JavaBean和数据库技术,通过动态生成和维护无限级树状菜单,为用户提供了一种直观、易用的导航方式。开发过程中,理解数据库设计、JavaBean的业务逻辑以及JSP页面的交互逻辑是非常关键...

    JavaBean示例

    JavaBean主要用于构建Java应用程序的可重用组件,特别是在JavaServer Pages (JSP) 和Enterprise JavaBeans (EJB) 中,它们作为数据容器来传递信息。 JavaBean的核心特性包括: 1. **公共属性**:JavaBean通过公共...

    javabean规范

    JavaBean 是Java编程中的一种惯用模式,它并不是一种严格的语法规范,而是一种设计标准,目的...通过JavaBean、类型转换、静态成员、final关键字、抽象类和接口的合理使用,开发者可以构建灵活、可扩展的Java应用程序。

    JavaBean创建和使用:计算器

    在本示例中,“JavaBean创建和使用:计算器”是一个关于如何构建和运用JavaBean来实现一个简单的计算器功能的教学。我们将深入探讨JavaBean的特性、创建过程以及在实际应用中的使用方法。 首先,JavaBean遵循一定的...

    JSP+JavaBean+Servlet技术实现某网站用户注册和登录功能( 源码打包)

    在IT行业中,Web开发是一项核心技能,而JSP(JavaServer Pages)、JavaBean和Servlet是构建动态网站的重要技术。这个项目“JSP+JavaBean+Servlet技术实现某网站用户注册和登录功能”提供了完整的源码,帮助我们深入...

    JavaBean讲解(上)

    4. 反射机制:JavaBean的属性、事件和方法可以通过反射API动态访问,增强了程序的灵活性。 使用JavaBean的场景: 1. MVC架构:在Model部分,JavaBean用于封装业务逻辑和数据,与View和Controller进行交互。 2. JSP...

    使用JSP、JavaBean和Servlet实现一个简单的留言板设计.zip

    在本项目中,我们主要探讨如何使用JSP(JavaServer Pages)、JavaBean和Servlet技术来构建一个简单的在线留言板系统。这个系统将允许用户提交留言,并将这些数据持久化存储,以便其他用户可以查看和交互。以下是对每...

    基于JavaBean和JSP模式的网上商城设计与实现.zip

    本项目以“基于JavaBean和JSP模式的网上商城设计与实现”为主题,深入探讨了如何利用这两种核心技术构建一个功能完备、用户友好的在线购物系统。 JavaBean是Java编程语言中的一种组件模型,它提供了一种标准的方式...

    JavaBean 和 JSP 中 的标准动作

    JavaBean 和 JSP 中的标准动作学习

Global site tag (gtag.js) - Google Analytics