论坛首页 综合技术论坛

面向集合的框架设计

浏览 26634 次
该帖已经被评为良好帖
作者 正文
   发表时间:2007-11-25  
    判断和循环是程序中最基本的语句结构。而在vonNeumann体系架构下,循环是对集合进行操作所需的基本步骤。一个有趣的事实是,函数式语言所宣称的 生产力的来源很大程度上在于集合操作的便捷性。在数学中我们通过张量分析,泛函分析等可以清楚地意识到集合之间的相互作用是可抽象的,是可以独立理解的, 即我们可以在不涉及具体基元结构的层面上独立的定义并执行集合运算。如何将这种概念独立性在框架层面展开是一个非常深刻的命题。
    在基元结构上应用基础操作p(d)这一微观场景一般情况下是容易理解并实现的, 但通常程序中所定义的大量边界是基于集合变量的, 因此很多代码都是封包和解包操作, 在层层嵌套的循环结构深处我们才能发现真正具有业务价值的基元结构. 将集合操作提升到系统层,减少或简化在应用层需要显式编制的循环结构是框架设计层面需要考虑的问题.
    一个最基本的方法是尽量定义通用的同构操作, 避免构造中间集合. 例如前后台之间通过json等通用协议交换复杂结构的对象, 避免定义特殊的中间处理过程. 一个与之相配合的重要技术手段是通过类查询语句(描述方式)直接构造特定的集合. 例如prototype.js中提供的$$('div div.myclass').each(op)这样的处理方式显然要比在循环过程中基于特定条件过滤要方便的多. 而在AOP操作中切点的集合定义方式也是其提供的核心价值之一. 与集合操作相适应的一种代码风格是流式设计(stream), 这正是jQuery试图鼓吹的主要价值(虽然我个人认为它有些走极端). 流式设计的核心结构实际上是 x += dx, 它不需要集合是一次性构造的, 便于支持一种逐步部分修正的概念模型.
    为了支持集合的隐式构造, 我们需要以通用的方式定义元素到集合的组装规则. 在Witrix平台的前台js框架中我们定义了由独立的html组件到复合查询条件的拼接规则, 定义了由每个html组件的数据校验函数到整个form的数据校验函数之间的组装规则, 定义了由单个html组件提交参数到整个form提交参数之间的组装规则. 在Witrix平台的标准界面上, 框架本身的编制基于js.query.buildCondition(frmQuery), js.validate.validateForm(frmUpdate), ajax.addForm(frmUpdate)等少量集合操作进行, 在不同的应用场景下, 我们只需要关心每一个字段如何显示, 提交哪些属性, 而由系统负责将它们自动组装并在后台进行分派. 面向不同的应用, 框架代码不需要做出任何修改, 确保了系统结构的可重用性.
   Witrix平台的后台处理模型中定义了实体化过程, DaoWebAction基于CRUD等原子操作定义了批量提交, 数据导入导出等复合的甚至是嵌套的集合操作. 在不同的应用中, 我们通过修改bizflow文件中<action id="ViewDetail-default">, <action id="Update-default">等针对单实体的业务规则即可适应不同的业务场景, 而不需要为特定的应用重复编制集合处理过程.
    面向集合+通用组装规则是Witrix平台设计中采用的基本设计手法之一, 它使得我们在一般应用中只需要考虑单实体,单字段等基元结构上发生的特定业务, 大大简化了系统构造过程. 但是也需要认识到从个体到集合的扩张(p(d) -> P(D) )是非平凡的, 集合比个体的简单加和要更多, 为此架构中需要保留对集合边界的识别能力, 例如需要允许在数据导入完成之后执行特定的业务规则而不是仅仅针对每一数据行执行业务规则.
   发表时间:2007-12-03  
非常欣赏楼主从数学角度穷究事物本质的态度。但是读楼主的文章,包括楼主的其他文章,通常读得似懂非懂。建议楼主在抽象的论述以后,再加一点具体的实例/展开。

在我看来,SAX API就是一种“在基元结构上应用基础操作”的API。只不过好东西因为简约而被视之简单,不入主流的法眼。

引用

但通常程序中所定义的大量边界是基于集合变量的, 因此很多代码都是封包和解包操作, 在层层嵌套的循环结构深处我们才能发现真正具有业务价值的基元结构.

不太明了你的意思,开否展开一点?

恕我孤陋寡闻,不知道什么是”流式设计(stream)“,能否提供几个有关的链接?谢谢。
0 请登录后投票
   发表时间:2007-12-03  
我习惯于概念层的推演,而且所阐述的东西多数是我们创造过程中的副产品,与业内常见的观念实际上是有着很大差异的。感觉不明白是因为你没有采用类似的视角,或者还没有独立思考过很多问题。如果你只是从业内已经熟知的概念出发试图理解我所写的内容,显然是不可能的事情。所以我常说know something already known.

如果你在编制一个新的应用,存在大量代码可能是
myFunc(){
  for each x in set
    doSomethingValuable(x);
  return packedResult;
}

myOtherFunc(packedResult){
  for each y in pakedResult
    doSomethingOther(y)
}

其实我们真正关心的是循环内部的某个过程,但是我们经常可以观察到它们被某些通用的或者特定的循环(集合遍历)操作所包围着。Witrix的设计方式是强调业务关注点,而把所有的汇总操作尽量抽象完成。比如现在界面上显示一些字段。从抽象的操作上说
  for each field in dsMeta.viewableFields
    show field.viewer

这一过程在平台代码中实现,它是一个通用的集合操作过程。不同的具体应用只是关心具体字段的展现形式,虽然我们必然需要字段集合,但是它不是我们注意力的重心。
  如果考虑到字段在界面上展示有一个布局问题,我们所要修改的是集合内部的结构方式:
  某种结构循环方式(dsMeta.字段组成的布局集合)
    show field.viewer

抽离出集合,实际上是在最大限度上分离结构问题和内容问题。    
   结构是可抽象的,是具有独立意义的。这就是Witrix所提出的面向结构的设计视角。不是强调对象的所谓业务含义,不是强调某种通用语言(例如ruby)的灵活的语法结构。在这之间存在着厚重的具有物理意义的可以进行结构分析的技术层。[url]http://canonical.iteye.com/blog/60758 [/url] http://canonical.iteye.com/blog/126467

stream style就是向流中不断追加内容,o.put(y).put(z).put(t)这种方式,看一下jQuery的代码就知道了。

SAX的事件驱动方式结合模式匹配能力确实可以直接在局部应用转换逻辑,但是缺乏状态空间的配合,它面对复杂问题时是乏力的。

0 请登录后投票
   发表时间:2007-12-04  
谢谢回复。正因为我也有类似的视角,我才会有兴趣进一步了解你确切的想法。

再说SAX。对于一般计算而言(不针对特定的领域)你回复中的伪代码,都可以用SAX实现,包括stream style。当你在最后断言:”但是缺乏状态空间的配合,它面对复杂问题时是乏力的“,你的根据是什么?为什么SAX就必然缺乏状态空间的配合?

0 请登录后投票
   发表时间:2007-12-04  
1. SAX本身只是简单的事件驱动,需要应用层自行维护状态空间。特别是SAX没有内置提供对当前节点位置的描述信息,在比较复杂的情形下,直接使用SAX需要应用层做不少工作。

2. 如果将状态看作是可以附着在某个对象上的标记,显然状态的存在性便于我们识认概念的唯一性。对象还是那个对象,只是状态标记发生了变化。而如果系统中没有状态,则必然产生了一个新的概念。这在很多情况下是不必要的负担。状态的存在使得系统在局部结构上允许出现非常复杂的变化,函数式编程的拥趸们对此多有诟病。但是从另一个方面上说,状态使得我们可以基于局部信息处理很多问题而不需要把它扩大化为一个全局匹配问题。

3. Witrix中的tpl模板语言是一个非常强大的xml动态标记性语言。其中定义了多种状态空间管理策略:调用自定义标签的时候,可以选择是否压栈,是否自动导入外部变量,是否自动屏蔽外部变量等。这些状态空间管理策略对于编制复杂的组件而言是必要的。我们也尝试过多种使用xslt的方式,但是在概念简洁性和结构控制能力上都无法和tpl标签设计相比。

4. 因为我的理论物理学背景,我无法认同函数式编程的世界观。世界比函数的集合要复杂一些。
0 请登录后投票
   发表时间:2007-12-04  
引用
因为我的理论物理学背景


引用
如果将状态看作是可以附着在某个对象上的标记,显然状态的存在性便于我们识认概念的唯一性。对象还是那个对象,只是状态标记发生了变化。


我觉得有这样的背景,却不把状态想象为时空流形是非常奇怪的.

另外提一句,函数式语言的数学实质并不是函数,而是范畴.函数式语言中的函数并不等同于分析上的集合函数。分析中的集合函数函数,只是某一类集合范畴。
0 请登录后投票
   发表时间:2007-12-04  
1. 物理学只是使用数学,世界并不是公式的堆砌。

2. 函数式语言的思想来源是泛函分析,范畴只是函数上可以建立的一种代数结构。泛函中的大量分析结构无法在函数式语言中直接体现。基于范畴论所能推演得到的规律是极为有限的。

3. 函数构成函数似乎是很完备统一的世界。 但是在物理世界中发生的一切却复杂的多。虽然世界可以还原为原子,但是原子构成分子,分子构成宏观物质时,系统的基本性状发生了本质性的变化,并不再是统一的形式。每一个层面上都会产生独立的结构规律。
0 请登录后投票
   发表时间:2007-12-04  
canonical 写道

1. 物理学只是使用数学,世界并不是公式的堆砌。

2. 函数式语言的思想来源是泛函分析,范畴只是函数上可以建立的一种代数结构。泛函中的大量分析结构无法在函数式语言中直接体现。基于范畴论所能推演得到的规律是极为有限的。

3. 函数构成函数似乎是很完备统一的世界。 但是在物理世界中发生的一切却复杂的多。虽然世界可以还原为原子,但是原子构成分子,分子构成宏观物质时,系统的基本性状发生了本质性的变化,并不再是统一的形式。每一个层面上都会产生独立的结构规律。

我提到的时空流形其实恰恰并不是一个数学概念,而是一个物理概念.如果一个人真的很对相对论有一定的了解,那么我认为他会认为函数式语言看待状态变化的观点是一个自然而然的事情,而非是一个累赘.可以说相比于命令语言,函数式语言对状态的理解更加符合物理经验而有悖于日常经验,而命令式语言则恰恰相反。更为重要的是,函数式语言对状态的理解与并行计算模型完美契合的,因为从物理学的角度来说状态的本质其实就是时间与并发也是物理学中的相对性,没有相对性一切系统都是可以没有状态的,更加确切一点说是函数式语言对状态的理解与物理世界中的时空观互为契合.

函数式语言本质上来自递归论,这一部分是与分析学相去甚远的数理逻辑。递归论讨论的是离散对象的能行问题,也就是说递归论讨论的是自然数的问题,而分析学则着重讨论实数或者复数域的问题.非离散对象比如说分析学里通常处理的那种处处稠密的连续对象,是几乎没有办法进行能行判定的,也就是说无法用计算机进行处理.因为实数集的势要比自然数集的势高,无法在自然数和实数之间一一对应。因此所谓的泛函的大量分析结构无法用函数式语言直接体现,不如说这些分析结构无法用计算机进行处理.再换一种说法,不是因为函数式语言的数学基础太纯粹以至于无法涵盖现实世界的所有的问题,而是计算机本身无法处理现实世界中的所有问题。函数式语言无法处理的问题,命令式语言一样处理不了.因为lambda演算本来就是与图林机等价的.

范畴不是一种代数结构,而是用于分析学结构和数学结构之间关系。所谓的代数结构一般是指运算封闭的集合.但是首先范畴的对象不是Set,而是Collection.这两者是有非常大区别的.范畴的对象可以是代数结构,这个时候对象之间的态射就是集合之间的保持映射。但是范畴并不限于带结构的集合,范畴对象之间的态射也未必是函数。比如我们Relation Category的对象是所有集合,态射是所有集合之间的Relation.或者举个离集合更远的例子,deductive system 就可以做为一个Catrgory,它的对象是所有的proposition,态射是proposition之间的proof a|-b.
第二集合论中的函数作为范畴它的特性范畴论中成立的,在集合论中未必成立。比如说如果一个函数如果在集合论上是surjective的,那么在范畴论中必定是一个epimorphism,但是反过来如果范畴论中是一个epimorphism但是在集合论中未必是surjective.两个幺半群(Z,+,0),(N,+,0)如果令一个包含函数i:(N,+,0)->(Z,+,0)将N的自然数映射到Z的正整数部分,显然所有的负数没有domain,i不是一个surjective.但是很容易证明i是一个epimorphism.


0 请登录后投票
   发表时间:2007-12-04  
如果可以投票的话,我想知道有多少人看懂了楼上的话。。。-_-
0 请登录后投票
   发表时间:2007-12-04  
1. 并发和流形没有什么关系. 相空间中发生的事情并不就是物理学本身。数学上等价的东西在物理上存在着不同,这就是物理学。我们对事物的理解存在着多种视角,但是在某种情况下一种视角会相对更加简单。而数学模型中未考虑到的因素在不断的视角变换中最终被弱化。

2. 函数式语言和命令式语言的计算能力相同,但是在具体的情形下它们的描述能力是不同的。我所关心的不是语言层面的问题,因为语言本身的能力并不足以解决现实开发中的所有问题。即现实开发中所需要处理的结构问题并不是在语言层面得到充分解决的,这是我们需要做工作的地方。

3. 范畴论是从同调代数发展起来的一种非集合论的代数语言,我这里所指的代数结构只是指代数学所研究的一种结构问题。它虽然可以推进我们对于程序基础结构的理解,但是并不足以解决我们所面临的现实问题。此外,一个重要的问题是,一个抽象的概念,当我们物理性的去实现它的话,就必然面临着各种现实的模型之外的约束。如何小心找到合适的实现路径,不触碰可能让模型失效的边界,是我们需要解决的问题。

0 请登录后投票
论坛首页 综合技术版

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