读书人

元数据、开放数据模型及动态系统-形而

发布时间: 2012-10-26 10:30:58 作者: rapoo

元数据、开放数据模型及动态系统--形而下学篇
普适数据容器

数据集—ataSet)是一个普适的,弱类型的,开放的数据容器。普适是指它可以适应任何基于名值对集合或名值表的数据形式,比如Properties,Database Tables, XML, CSV, JSON, LDAP, ...。弱类型是指所有的容器都用同一个数据结构,存放在容器中的只有两种对象:数值和子结构。数值一律用字符串表示,时间日期用XML标准形式来表示,子结构一律用数据集表示。有关定义域的元数据存放在专门的数据结构中。如果需要类型转换,借助元数据,可以很容易地做到。所以为了突出本质,我宁愿把数据转换的代码放到AccessorWrapper里。事实上在我们的项目里,根本就没有用到类型转换。所谓开放,就是前面说过的,容器可以适应数据模型的变化,以不变应万变。

下面给出两个主要的接口。DataSet继承Iterator和Map,即是为了表明概念继承上的渊源,也是为了与Web模板结合。数据集在元数据只含有字段名,并且不具有滚动性质的情形下,退化为Map。

public interface XSendable{ /** * The xid must be valid xml local tag name. */ String getXID(); void send2(XCarrier carrier) throws SAXException;}public interface XCarrier{ void sendable(XSendable sendable) throws SAXException; void startElement(String name) throws SAXException; void attribute(String name, String value) throws SAXException, IllegalArgumentException; void text(String text) throws SAXException; void endElement(String name) throws SAXException;}public interface XReceivable{ /** * The xid must be valid xml local tag name. */ String getXID(); void startReceivingFromX(); void receiveXAttribute(String name, String value); void startReceivingXContent(); void receiveXText(String text); void startReceivingXNestedElement(Stack<String> elements); void receiveXNestedElementAttribute(Stack<String> elements, String name, String value); void startReceivingXNestedElementContent(Stack<String> elements); void receiveXNestedElementText(Stack<String> elements, String text); void endReceivingXNestedElement(Stack<String> elements); XReceivable mapNestedXReceivable(String xid, Stack<String> elements); void nestedXReceivableStartedReceiving(XReceivable receivable); void nestedXReceivableEndedReceiving(XReceivable receivable); void endReceivingFromX();}

在两边同是Java环境的情况下逻辑上比较清晰, 比如这个 请求即时消息存档 的任务对象:

public class RequestArchivedIMsgs extends Submission{    // shared code    private transient long tid;    private transient long beforeID;    private transient long beforeTime;    private transient int max;    // traverser side code    public RequestArchivedIMsgs(long tid, long beforeID, long beforeTime,            int max)    {        this.tid = tid;        this.beforeID = beforeID;        this.beforeTime = beforeTime;        this.max = max;    }    @Override    protected void sendAttributes2(XCarrier carrier) throws SAXException    {        super.sendAttributes2(carrier);        carrier.attribute("tid", String.valueOf(tid));        carrier.attribute("beforeID", String.valueOf(beforeID));        carrier.attribute("beforeTime", String.valueOf(beforeTime));        carrier.attribute("max", String.valueOf(max));    }    // scener side code    public RequestArchivedIMsgs()    {    }    @Override    public void receiveXAttribute(String name, String value)    {        if ("tid".equals(name))            tid = Long.parseLong(value);        else if ("beforeID".equals(name))            beforeID = Long.parseLong(value);        else if ("beforeTime".equals(name))            beforeTime = Long.parseLong(value);        else if ("max".equals(name))            max = Integer.parseInt(value);        else            super.receiveXAttribute(name, value);    }    @Override    public void realize() throws AccessDeniedException, TheObjectException    {        Persistent<? extends TheTopic> topic = scener.getApp().getTOB()                .get(tid);        if (topic == null || !(topic.o instanceof TheTopic)) return;        scener.getConnection().postGuidance(                new SendArchivedIMsgs(                        scener.getUserAccount().o.getOwningUser(), topic,                        beforeID, beforeTime, max));    }}

它发送到服务器端执行时, 其实是构造一个 SendArchivedIMsgs 对象, 也是通过 XML 流传递回去, 在客户端把自己承载的数据填入到客户端缓存, 然后激发用户界面更新.

对动态结构化的数据, SAX 方式的传递和处理是最高效的. 另外因为是XML, 也有可能用于异构系统.
美国那边已经有开发者在用Flash做WoW的浏览器端界面, 也算是 XT 在异构系统上的尝试的起步了.

楼主如果有兴趣可以下载 WoW 的源码看看, 感兴趣的问题共同研究讨论. 4 楼 LucasLee 2007-01-18 看完了上下篇。有几点感想及疑问。
1.为什么一定要使用XML作为中间数据格式?既然所有使用的情形都是JAVA,为什么不用JAVA类呢?更快,更自然些。可能会说,为以后跟异构系统交互?那么是否又经过了足够的考虑呢。
2.我觉得用法还算比较复杂的。可能为了这个普适性,必须要付出的代价,关键是你们用到了这个普适习性么,如果是,或者你们的应用就是要这么复杂,我觉得尚可理解。
3.我认为用XML做持久层来替代DB,以实现离线测试的想法难以理解。如果仅是存、取单条记录,做这类非常简单的测试那自然可以,但是对于给出SQL稍复杂的查询应该就无能为力了,如果非要做什么离线或者简化测试,似乎不如用一个HSQLDB来做,(当然,这并不是一个简单的路子,我觉得还是在线测试好了)

总结一下,你的架构估计是为了SOA一类的大型系统设计的。我对那些并不熟悉,不过我怀疑的是你们是否值得用这种复杂的结构,不要说太远的未来,或者噱头的问题。

另外一点意见,我对你表述的语言有点搞不清,比如什么矩阵连乘什么的(一看就是学院派的,高!),我的数学不好,是不是可以用简单直白的语言表达呢?搞个大伙都明白的方法。 5 楼 pojo 2007-01-18 引用
另外 数据集 也损失了 OO 理念里同时用 数据 和 行为 来建模解决问题的优势. 不过在异构系统里想全盘 OO 也是不太可能的, 所以在不同平台之间只是传递数据也不失为实践中的好方法.

我想你没有理解我的意思。我没有明言背景是分布系统。我说的是在需要模型的地方(领域层)建模,在除此以外的任何地方,数据就是(毛)数据。

引用
1.为什么一定要使用XML作为中间数据格式?既然所有使用的情形都是JAVA,为什么不用JAVA类呢?更快,更自然些。可能会说,为以后跟异构系统交互?那么是否又经过了足够的考虑呢。

我考虑的是:开放,动态,简单。有了类,就有了约束,就有了耦合,就不开放,不动态。

引用
2.我觉得用法还算比较复杂的。可能为了这个普适性,必须要付出的代价,关键是你们用到了这个普适习性么,如果是,或者你们的应用就是要这么复杂,我觉得尚可理解。

我们的项目是一个类似MS BizTalk或BEA Integration Server的项目。我们实现的是一个引擎,下游的团队用它来开发他们的项目。随着下游项目的加入,Domain Model就要修改,平均一个月改一次。所以项目的性质决定了它必须是动态的开放的。在项目的初始阶段,我们请了BEA来做POC,结果Integration Server不能满足我们的动态需求,另外运行效率也不好。BizTalk也一样。这之后,我们才决定自己做的。

最后的结果是,我们不仅满足了系统对于需求的稳定性,而且我们的系统至少比BEA Integration Server快25倍,比BizTalk快15倍。

那些例子,就是REST Style的WebSerivce。如果你觉得用法复杂,那是我写作的失败。

引用
总结一下,你的架构估计是为了SOA一类的大型系统设计的。我对那些并不熟悉,不过我怀疑的是你们是否值得用这种复杂的结构,不要说太远的未来,或者噱头的问题。

我们的系统已经运行三年多了。第二版是我一个人写的,就用这里说的方法,将整个系统重构。代码是第一版的一半,运行效率是第一版的4倍。第二版也已经运行两年多了,我离开那家公司都快一年了,系统照样在转。

6 楼 歆渊 2007-01-18 嗯, 分布的组件之间只传数据进行互操作的设计现状, 也是传统技术框架造成的, 以后 HBI (Hosting Based Interfacing) 发展起来, 传递带逻辑的数据对象就会很自然了.

从应用上来看, 这个系统结构起到的好像是 ESB (Enterprise Service Bus) 的作用, 兼有一些企业组件开发最佳实践的指导意义. 如果花心思规整包装一下, 差不多可以作为一个SOA方案卖了. 7 楼 LucasLee 2007-01-18 pojo 写道
引用
总结一下,你的架构估计是为了SOA一类的大型系统设计的。我对那些并不熟悉,不过我怀疑的是你们是否值得用这种复杂的结构,不要说太远的未来,或者噱头的问题。

我们的系统已经运行三年多了。第二版是我一个人写的,就用这里说的方法,将整个系统重构。代码是第一版的一半,运行效率是第一版的4倍。第二版也已经运行两年多了,我离开那家公司都快一年了,系统照样在转。


对于你说的成就,我很欣赏。
但似乎你并没有回答我的问题。

我已经大概知道你一个人做了这个系统,然后系统性能比这个那个的商业版本高很多倍。
但是我仍然不清楚你的软件是在什么样的环境下产生的,为了解决什么为题而做。
脱离了这些,我想我们理解也困难。
先告诉我们需求是什么,再说怎么做,为什么。

我猜了一下,既然你提到了Biztalk之类的,那么你做的是否是一个完整的EAI软件呢?或者是一部分?

8 楼 onlydo 2007-02-06 潜水多年,忍不住大吼一声:真不赖 9 楼 jianfeng008cn 2007-02-06 数据集的概念很类似dotnet的ado机制的嘛
10 楼 partech 2007-02-06 SDO 11 楼 pojo 2007-02-07 我是把它当作简化的SDO来用的。 12 楼 xmlspy 2007-02-09 没明白这个是干什么用的;( 13 楼 coolfish 2007-02-12 SDO,楼主从自己的经历中发现了SDO规范中提出解决问题的方法. 14 楼 minimu 2007-02-20 基本上模糊了
其实没有源代码无所谓,甚至不用大量介绍哪些借口什么的,但是至少给出一个清晰的应用脉络,那样容易看明白
15 楼 pojo 2007-02-20 minimu:
引用
基本上模糊了
其实没有源代码无所谓,甚至不用大量介绍哪些借口什么的,但是至少给出一个清晰的应用脉络,那样容易看明白

很抱歉,让你感到困惑了。

我写那篇文章的初衷,是因为我认为DataSet的概念和相关的技术,具有比较普遍的意义,可以应用到许多领域。因为我相信它具有普遍的意义,我也相信它在数学上一定有它的道理。通过写那篇文章,我找到了一些数学上的解释,有些在文章里写了,有些没有写在文章里。

因为是具有普遍意义的东西,所以我没有选择从具象展开,而是从抽象入手。我给出的接口和罗列的类名,以及代码片断,是想给读者提供一个想象的空间。它的具体应用,取决于读者的阅历和想象力。熟悉FP的,也许可以看到一点FP的影子。做过分布系统和SOA项目的,和其它的方法比较一下,也许会同意这是一个非常简洁和高度一致的方法,高度一致意味着高度重用。

空对空的到此为止,下面来点实际的。DataSet,从Java角度看,可以把它看成Map,CachedResultSet,Java Bean,或者像ajoo指出的,看成DynaBean,DynaClass,等等。从XML的角度看,它是一个像DOM一样的数据模型—ata Model),我给它找了一个官方的模型--XDM (XQuery 1.0 and XPath 2.0 Data Model),我只支持Document Node,Element Node,Attribute Node,Text Node,不支持Processing Instruction Node和Comment Node。选这个模型是因为它和我的实现很接近,也是为了支持XPath和XQuery。XPath用JXPath来实现,很容易做到。XQuery的实现还不多,如果看见简单的XQJ的实现,我会把它集成进来。这个方向上再往下走一步,就是XQuery和XSLT的等价置换,比如将XQuery编译成XSLT。如果我能做到这一步,我就可以做许多LINQ可以做的事。这是我几天前看LINQ的视频演示时冒出来的想法。就是现在,我也可以用它做许多WebLogic Integration Server, IBM Message Broke,MS BizTalk可以做的事,用非常少的代码。

上面说的可能还是太宏观,我们再来点微观的。在我的Blog里,我开列了一个栏目--数据集用例。暂时只有一个用例。如果有人出题,或者我看见有合适的用例,我会不断地充实。我希望读者在阅读用例的时候,充分发挥你的想象力。现在的这个例子,它其实可以有许多变化。比如把输入端换成SQL,它就可以根据查询的结果生成网页。EndPoint是纯碎的申明,没有任何逻辑的,它可以是事先配置的,也可以是实时产生的。再把输出端换成HttpResponse,网页就到浏览器了,它就成了一个用XSLT作模版的Web"框架"。输入端还可以换成消息队列,代表异步处理的结果。不管你怎么换,代码还是那几句。像这样简灵活的应用,恐怕用Ruby也做不到吧。 16 楼 nihongye 2007-02-20 为什么不直接使用DOM? 17 楼 magic_seek 2007-03-09 <p>上午看了上篇,下午看了下篇,看完后对楼主的DateSet和DataSetMetadata两个接口感觉比较亲切,我可以想到接口里每一个方法的用途,甚至包括那个系统本身不是必须的columnLabel。不过因为我们的最终应用不同,后面的东西就大相径庭了。</p>
<p>看了各位的回复,感觉能够理解楼主本意的不是太多(我也不一定理解正确),觉得还是应该推广这个数据集的概念,因为它是非常有用的东西,而且它也是通用的,未来的编程中可能会处处用到它。</p>
<p>如果大家用过JDBC来实现一个通用的数据库管理程序(如SqlServer的查询分析器),那么一定会使用到Connection的Metaata和ResultSet的Metadata,通过Connection和ResultSet的元数据我们可以管理数据的任意一张表的任意一条数据。</p>
<p>不过数据库的表是二维的,同一张表里不能表示任意复杂数据,所以如果我们想保留通过元数据而操作任意一张表的数据的功能而且还能表示任意复杂的数据的话,那么我们可以把二维表扩展到树形结构当中,我们知道XML几乎可以表示任意一个你想要的复杂数据,所以如果ResultSet扩展到了树形结构中那么它也能表示任意复杂的数据。</p>
<p>有了以上的步骤后,那么就可以设计出类似楼主的DataSet和DataSetMetaData的两个接口了。有了接口那么就可以编写实际的应用了,这时你会发现你的程序似乎可以管理任何一个复杂的数据,而且更重要的是象实现一个通用数据管理这样的程序是不需要考虑数据所代表的含义的,也就是说可以不管这些数据的实际用途,不用去管它们是什么业务模型,所以这时完全可以为管理数据而做一套功能模块来,使用这个模块你可以忽略很多诸如数据转化和数据存储等方面的细节,你只需专心考虑最终如何处理这些数据就可以了,这样会大大提高程序的灵活性和开发效率。我想楼主的框架程序应该也是这样的。</p> 18 楼 gqdou 2007-05-11 我们是做银行业务的,楼主的这个思想与我们现在的系统中数据模型用xml来传递非常相象,我一直想从开源领域找到这样的产品,今天算了看到了,谢谢分享。 19 楼 gqdou 2007-05-11 我们是做银行业务的,我们的系统中数据模型是定义在xml里,然后对xml进行实例化后,将这个对象在v层,c层,m层各个层进行传递,并能随时动态修改这个对象,或者添加一个对象节点。我一直欣赏这样的设计,试图在java开源领域找到这样的设计,今天算是头一次碰到了。 20 楼 eboge 2007-05-11 很好, 学习中

读书人网 >软件架构设计

热点推荐