posts - 176, comments - 240, trackbacks - 0, articles - 7

    地址(Address)是现代计算机体系架构中的核心概念,它在程序设计语言上的体现就是C语言中的指针(Pointer)。在C语言中,所有的高级技巧都和指针这个概念相关。指针只是一个存放了一个地址的变量,但是C语言中提供了一个方便的间接访问方式,p->x, 它使得拥有指针在概念上就等价于拥有了指针所指的全部内容。在这种诱导下,我们渐渐模糊了地址和地址所存储的内容之间的区别。这也是指针的指针这样的概念总是让初学者迷惑不解的重要原因。
    指针是对地址的符号化。它所带来的第一大好处是使得我们摆脱了对绝对地址空间的依赖。如同Newton第一定律所阐述的:物理规律与所发生的惯性坐标系无关。同样,数字空间中发生的的事件与所处的绝对地址也是无关的。在符号化的方向上更进一步,如果我们专注于指针的关联语义,而放弃指针的指针这样的混杂概念,就会得到具有独立价值的引用(Reference)概念.
    从表面上看起来,数字空间只是一个无限延展的一维地址空间,每一地址处只能存放一个有限大小的离散数值,似乎它的几何学是贫瘠的。但是因为在软件设计中,一般是不考虑寻址时间的。这意味着在拥有指针的情况下,我们可以“立刻”访问到数字空间的任意遥远的地方。这种超时空的信息传递过程使得我们可以利用“引用”概念轻松的构建一个多维的表示空间。在面向对象的技术背景下,x.y.z这样的形式表示暗示着x,y,z是同时存在的。当z发生变化的时候,通过y.z和x.y的信息传导,x对象本身也发生了某种变化。
    随着web技术的流行,独立的状态/地址空间的存在性逐渐成为系统不可回避的假设, "同时性"的物理约束越来越难以维持. 相对论规定了物理现象的定域性, 在数字空间我们一直忽视了它.但有趣的是, 网络上的传输时延却迫使我们重新发现了"引用"形式下必然存在着的物理过程. 引用本身只是标记了某种信息关联, 并不一定意味着同时性约束. 并发编程领域的所谓的Future对象是对传统引用概念的一种有趣扩展.
   result = obj.callMethod(args) ==>  future = obj.callMethod(args)
future对象可以被自由传递, 只有当实际访问到它的属性的时候, 才会触发时序约束. 

posted @ 2007-12-02 22:14 canonical 阅读(1151) | 评论 (2)编辑 收藏

    判断和循环是程序中最基本的语句结构。而在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) )是非平凡的, 集合比个体的简单加和要更多, 为此架构中需要保留对集合边界的识别能力, 例如需要允许在数据导入完成之后执行特定的业务规则而不是仅仅针对每一数据行执行业务规则.

posted @ 2007-11-25 23:37 canonical 阅读(1148) | 评论 (0)编辑 收藏

   由于各个公司的领域,规模,人员配备等差异很大,形形色色的公司中顶着架构师头衔的诸般人等所从事工作的内容以及所承担的责任也是大相径庭。务虚者有之,务实者也有之, 难以一概而论。甚至关于架构一词的具体含义在不同语境下也是很难达成共识的。然而作为架构师,他应该做什么,能够做什么,却是我在自己的职业生涯中需要加以回答的问题。
    软件公司中的工作大致分为销售,技术,财务,打杂这几类。架构师所从事的工作大致上属于技术这一摊,应该是一种高度专业化的技术工作。在我看来,一般所谓架构师的工作主要是负责设计规范整个软件项目/产品/产品线的整体结构,他所摆弄的是各种相关的技术元素。虽然作为公司的技术利益的代表者,架构师会在某种程度上参与到公司的商业活动中(在某些巨型公司中,架构师甚至可以通过标准规范对整个产业结构施加影响),但是他更多的是接收商业需求将其转化为技术约束,而很少是商业目标的制定者。业务架构方面的设计更理想的是由业务专家进行,这个工作多半只需要技术的常识,而不需要对于技术本身的深刻洞察。在另一方面,虽然架构师对于技术实现所需的技术/人力等资源需求会提出自己的估算和建议,但是他一般并不具备相应的手段和责任来具体管理整个实现过程。因此在我看来架构师的管理职责并不是很大。当然,有些架构师会更加接近商业和管理而远离技术,将他们称之为"资深架构师"可能更加合适。在某些大型系统的建设过程中,总体设计人员可以只负责收集各个子系统的技术要求,汇总后制定整体技术规范,所起的作用类似于协调人员,在这种情况下倒是对技术要求较低而对管理素质要求较高了。
    关于架构的一个有趣的事实是,技术架构本身其实很少存在设计问题。大部分问题只在于业务问题如何分解到既定的技术架构上,一般的技术架构也只是现有技术元素的简单组合而已。所谓的架构设计工作并不是在真正的系统全景下进行,它往往是基于已有经验所作的短暂延伸,是对业内其他类似结构的复制变形。我们所面临的大量问题是选型问题,不是创造性问题,而是选择性问题。架构师最富技巧性的工作不是现在确定什么,做出选择,而是确定现在可以不确定什么,可以将哪些选择延迟。
    在一般人看来,架构师对于系统成败必然起着关键性作用,否则他们凭什么属于“活少钱多”的那伙人呢。但真实情况是,商业上的成败很少是由技术架构直接决定的。因为技术开放和快速传播等原因造成了技术的趋同性,在技术层面上,大多数公司很难依靠技术形成差异化优势。竞争优势主要来源于业务理解和与用户的接触性,来自于历史形成的业务格局。而在中国这样一个营销制导的商业世界中,架构师的工作更难说是在构造某种与众不同的东西。只有少数大公司依靠把握标准才形成技术的话语权,大部分人不过是在技术的大潮中随波逐流罢了。“不求有功,但求无过”应该是架构师基本的工作精神。技术失败最常见的原因除了不够专业以外(在中国,“专业”的标准也许是不同的),就是过于自信,试图去创造些新的结构,或者试图全面应用某种不熟悉的技术。架构建设应该是一个逐步改进的过程,不要激进盲动。
    国内的架构师多数是从高级程序员发展而来,在工作期间多半是学习掌握外部知识,以掌握知识的细节程度和广度为优先。因为总是在别人搭好的平台上活动,即使是参与过众多大型系统的建设,对于系统整体结构一般也没有提炼出自己的认识观点。而有些大学设置了专业,宣传培养架构师,但是实际上缺乏系统的实践训练,学生所学到的多半是高举高打的套路,在实战中的表现往往更差。掌握技术细节和自主的整体性思考对于架构师而言都是不可或缺的。
    虽然创新的技术未必是商业中核心的元素,但是真正的创造性仍然是每一个设计师的希冀。作为一名实践者,我们都在某种程度上期望超越所经历的偶然,达到某种普遍的真理,在外部的物质世界中留下自己的精神烙印。在这种意义下,架构师的工作便不是简单的技术背景或者技术理解可以涵盖的了。我相信,在业务层和基础技术设施之间存在着物理性的厚重的通用技术层,其中存在着大量的结构规律等待我们的探索,这也正是Witrix平台一直努力的方向。


posted @ 2007-11-18 21:50 canonical 阅读(437) | 评论 (1)编辑 收藏

   我们总认为认识的最高境界是认识到事物的本质。但是越明晰的认识意味着越明晰的区分,而区分意味着认识到事物的独特性,割裂了它与普遍事实之间的联系。我们是否会说这一本质和那一本质是本质上不同的?本质最根本的意义在于内在的规律,在于内在的协调而不是和普遍事物的对立。我们对本质的认识是如何成为可能的?现代语言哲学发掘的一个基础事实是我们的语言中涉及到抽象事物的部分存在含混性和自我证明的逻辑循环。在抽象的概念上我们很难达到共识, 而这恰恰是通常我们认为所谓本质所寄居的地方. 语言文字是人类所创造的思维的工具,我们对它们的存在早已习以为常。只有研究词源的时候, 我们才能清楚地意识到人们的思维和世界的现象之间的巨大鸿沟. 通过千百年的文化积淀和不断的自我强化, 我们才形成了共同的民族心理结构, 看到同样的文字的时候才能激发我们类似的情感, 才能引起类似的意向,但是具体的过程仍然是不可言说的.
    辩证法的两端都能够成为我们认识的对象,因此我们会感到矛盾对立的存在. 但是随着我们认识方向的转移, 很多矛盾可能被弱化,被消解. 在本世纪初, 相对论和量子论无论在理智或者情感上都是如此让人难以接受, 但是新一代的学生接受起来已经自然了很多. 现在我们只需要盲目的遵守规则,而不再需要去寻求自我证明的解释. 在现代物理的框架下, 惯性不是物质本身的属性, 它来自物质之外. 万有引力不是物质之间的额外的相互作用,而是时空扭曲后造成的内蕴约束. 但是在局部情况下, 并不妨碍我们建立一个形式系统使得这个属性内在化。在很多时候只有偏执的认识才能引导我们穿越未知.
    中国人的认识论是整体性的,但却不是公理化的.传统上我们说微言大义,总试图从真切的细节处领悟超越的真理. 这是和分析法不同的认识的途径, 但也很难说它是归纳法. 思维中的意象是符号化的, 但是也是具体的,拥有自己的形象,并具有某种潜在的活动性。

posted @ 2007-11-04 22:33 canonical 阅读(439) | 评论 (2)编辑 收藏

   读书在传统意义上是走向精英阶层的一条路径,这种功利目的一直深刻在我们的心中。学校也是按照培养高于平均水平之上的人才而设定的。只是在如今这个人人都是大学生的时代,大学生早已不是什么“天之骄子”。缺乏可以用于创造或者交换的技能和资源,知识阶层的相对贬值也在情理之中。依然持有着自己应该高于普通生活水平的错觉,非要在面子上有所交待,负担高于平均水准的车/房,很多时候只是徒增烦恼而已。
   读书是获取知识的主要途径,即使在影音世界空前繁荣的今天,它仍然是不可替代的。不知是学生的问题,老师的问题,抑或是整个教育机制的问题,现在接触到的很多人既没有从学校学习到必要的知识,也没有掌握基本的学习方法。很多人津津乐道的是某某很聪明,没见他用功也取得好成绩,某某很能来事,没干多久就挣了大钱之类的传闻。不劳而获可以是一种希望,却很难成为发生在自己身上的现实。我见过的聪明人很多,但是真正能做出一些自己的东西的人,都具备某种专注的能力,都要在某个方向上做出一般人难以达到的持久的努力,所付出的成本往往是不为人所知的。
   学习没有捷径,但却是有方法的。有效的阅读需要在一定的时间内完成,在最短的时间内获得整体的阶段性的认识。太厚或者太过艰难的书会耗尽我们的耐心。循序渐进,举一反三,温故知新是平凡的真理。读书一定要做笔记, 否则所获得的印像很快就会因为没有物质凭依而消逝. 笔记不是抄书,而是从自己的视角重新整理并组织,一般最多两三页纸而已。不要纠缠在文字细节上, 而要努力把握其中的一种图景. 物理中非常强调物理图象的重要, 这些图象未必是仿真的, 未必是要把事实世界中的事情复原,它们更多的是符号性的, 所指向的是一种感觉。有些人总是纠缠在什么是OOA, 什么是OOD这样的概念区分上,但是多数时候这些区分都是毫无意义的。我们需要脱离纸面上的图形和文字,想象它们的真实,这绝不是UML那种已经定义了的符号, 而是与世界上更多事物可以发生共鸣的某种形式. 我们所需要的是利剑迎面击来的那一刹那间对它最直接的感受. 思考问题的时候是现在这种感觉和曾经想过或者曾经看过的其他问题的相似, 而不涉及到任何文字上严谨的表述. 很多书上都列出很多条规则, 但是谁能保证这些规则是完备的, 如何才能从唯一的规则实现逐步的分化, 将它们演变出来. 能不能采用自己的语言复述, 能不能找出一个特定的视角重建这些概念的关联. 当把信息抽离到少数符号的时候, 通过空间形象思维我们有可能把握这一点. 空间优于时间, 实际上对于时间的感受我们是通过空间运动来定义的.
   现在的世界与百年之前已经是有着本质的区别,知识成为公开市场上兜售甚至免费公开的东西。在前所未有的开放中,人人都具有了创造的可能,所谓的创意早已成为我们惯常的生活,以至于一阶变化已经无法称其为真正的创造了。但另一方面,真正的思想仍然具有本质的稀缺性。原创的思想往往来自于少数人,其他人往往是在某一方向上进行衍生。现在很多人已经习惯了快餐式的文化消费,却不知更应该去阅读大师的原著而不是经过别人蒸馏后的转述。原创的思想在文字中跃动,它所关注的不仅是眼前的事实,而是整个世界和当前事实之间的关联,试图为它寻求到真正存在的价值。
   读书是一件有趣的事情,但是将一切都归结于某种感官的快乐,无疑是一种过分浅薄的观念。读书之乐趣未必是真的愉悦的感受。
读书不能使你更加富有,也不一定能带给你安宁, 不一定对你的工作生活有什么帮助. 它只是Kill Time的一种方式而已. 只是相对于电视影像的强制倾销, 游戏竞技的自我沉迷, 它比较适中的维持了一定的自主性和外部性的平衡. 我常说, 读书只是使你明白自己生活在怎样的一个时代, 自己不是一个蒙昧的原始人. 不清楚相对论, 不知道量子力学, 不了解基因技术, 只是很遗憾的在二十一世纪走过.
  读书也是读书人在社会上得以自持的一种方式,因为毕竟我们还可以说:拽什么拽,没文化,不稀的理你。

posted @ 2007-10-29 21:59 canonical 阅读(497) | 评论 (3)编辑 收藏

    虽然现代物理的标准表述采纳了严密的数学语言,物理学和数学的精神还是有着深刻区别的。数学的目标在于在既定的范围内把有限规则的推理推进到极致。物理学格物以致知,我们所了解到的永远只是这个世界变化的部分。当一种物理机制位于我们的视野之外时,物理学将选择直接无视它。因此物理学对数学是按需使用的,是有限理性的,总要受到所谓物理直观的制约。再完美的物理模型也不过是在不完全信息下建立的一种完备的数学模型。当我们沿着一条推理的链条越走越远的时候,一种本能的怀疑便会油然而生。

posted @ 2007-10-07 21:38 canonical 阅读(422) | 评论 (0)编辑 收藏

        Witrix开发平台基于级列设计理论发展了一系列新的设计思想和软件分解机制。并提出了一种新的Web体系架构。http://canonical.javaeye.com/blog/33824
 

Witrix架构呈"可"字形态,其中定义了三条主要的分界线:
1. 浏览器和服务器之间通过语义结构明晰的URL形成两分结构。http://canonical.javaeye.com/blog/99122
2. 系统前台至后台存在一条预制的非侵入的信道. 它维持了一种无害的可扩展结构. 具体的说,系统从前台js到后台处理,对于所有$为前缀的参数是自动传递的,没有识别出的层将自动把这些参数传递下去.系统通过这一信道实现退化过程。在 我以前的文章中曾经指出过, 每一种可退化形式都对应存在一种非侵入性的可扩展设计。http://canonical.blogdriver.com/canonical/993807.html
3. Witrix内置了对于CRUD模型的支持, 而BizFlow通过类似AOP的方法对CRUD模型进行了扩展。这使得Witrix的模型驱动部分并不是仅仅针对单表或者单实体的维护, 而是可以实现特定的业务逻辑和CRUD逻辑的混杂.

    这三条分界线分别规范了基础状态空间,对已有知识的重用以及面向未来的可扩展性。在这种大的宏观结构下,Witrix应用了如下技术手段:
1. 对象化。Witrix中的Jsplet框架以对象的名义提供了对后台的状态和行为空间进行分解的基础手段。 http://canonical.javaeye.com/blog/33873。Witrix 依托于Jsplet对象实现相关性的局域化, 而不需要像一般面向action的框架那样直接访问http session这一全局状态空间. 前台发送的objectName参数同时在系统的不同层面标定了WebAction响应函数, Biz配置, DataSourceMeta元数据, Hibernate实体等一系列相关概念, 使得它们构成一个统一的整体.
2. 标准化。与REST架构风格类似,DaoWebAction规范化了后台响应事件。DaoWebAction上支持的标准事件有Query, ViewDetail,Add, Update, Remove等, 它们构成一个完整的CRUD模型。与REST不同的是,DaoWebAction提供了一个空的响应事件BizAction。它相当于是CRUD模型中的 零元操作。在BizFlow模型下,它将被扩展为一个操作子空间,从而实现对于CRUD模型的超越。而在REST模型下所有的扩展操作必须依附于一个已经 具有固定语义的Method上,例如POST. http://canonical.javaeye.com/blog/99122
3. 实体化。在Witrix中充分发掘了ORM技术的能力, 使得单一业务对象上可以聚集到某一范围内的所有相关结构信息. http://canonical.javaeye.com/blog/111500. 同时在DaoWebAction中通过EntityFilter机制实现了单实体化过程. 这意味着前台应用可以一次性提交多个批量操作, 后台框架负责把它们分解为针对单个实体的一次确定性操作, 在后台实现时只需要考虑单实体的情况即可. 一个简单的例子是前台提交objectEvent=Remove&id=1&id=2&id=3 , WebAction层会为每一个id对应的实体调用BizFlow中的Remove-default操作. 实体化是一个非常重要的过程, 它使我们关注的核心成为单实体, 正是因为明确了单实体作为基本的关注点, 我们才可以建立更加复杂的状态机机制, 驱动系统状态变化.
4. 组件化. 前台的tpl模板和后台的WebAction共享一个thisObj指针, 结合自定义标签机制, 资源(js/css等)管理机制等构成可以重用的组件结构.
5. 偏置的AOP. BizFlow通过一种类似于AOP的操作对DaoWebAction提供的CRUD模型进行扩展, 使得模型的能力得到本质性的扩张. 这种AOP操作与通常意义的AOP的区别在于: 缺省行为在默认情况下发生, 除非显式禁止. 通过这种方式, 反转了base和extension之间的主体地位. 此外BizFlow所提供的不仅仅是行为的扩展,它同时提供了对界面的描述. 在前台tpl页面中通过<ds:BizViewOps/>等无参数的标签调用来定义嵌入坐标. http://canonical.javaeye.com/blog/34941


     与传统的J2EE相比较, Witrix表现出很多变化:
1. 不使用全局的session, 而是使用局域化的thisObj
2. 不定义service层,其功能分解到BizFlow和Handler中,它们都不负责日常的DAO操作。独立的MDA部分负责所有的实体CRUD(Create Read Update Delete)操作。
3. 不定义页面跳转规则,在前台使用拉模式直接表明跳转目标。结合前台stdPage对象在前台控制跳转目标。并可以在BizFlow中配置覆盖的规则,这样就可以针对不同的应用场景定义不同的跳转规则。
4. 不是为每个模块, 每个应用场景编制一组新的页面,而是大多数模块共用少数几个标准页面.
5. 不在与网络无关的service层上定义权限和事务管理。Witrix架构下通过URL明确区分了系统内部和外部, 前台访问后台时调用者的全部意图是以规范化的形式表达在url中的. 因此权限和事务管理作用在WebObject上在概念上也可以认为是约束直接作用在URL上, 这与REST风格是统一的. 当然我们也可以规范service方法的命名等, 但是显然要求一种随意性消失是有代价的, 在URL上我们已经付出了代价,为什么要在service上再付出一次. Witrix中Transaction和Auth的配置更加直观, 因为规范化了WebObject上的事件响应函数,一般我们也不需要进行特殊的配置. Witrix这种设计更加适合于网络这一两分结构的,更加充分的利用这一架构边界所提供的隔离性.
6. 不在页面中使用实体的字段名,而是大量通过元数据表达程序意图。http://canonical.javaeye.com/blog/114066

   一般J2EE多层架构下,所谓的架构分解主要是对程序纵向的分解,但是程序结构方面是没有横向分解的。而witrix架构的一个核心就是横向存在着 CRUD模型和Biz的分解。在系统的所有实现过程中,所有CRUD操作都剥离到MDA模型中,而不需要任何代码编制。典型的, witrix后台代码一般写在handler中,命名为handler而不是service是因为handler中负责的内容和j2ee传统上的 service有所不同,一般service总是要负责某个实体的CRUD操作,大量的findxxx代码。一般提倡的最佳实践是实现某个通用的基类,所 有service都继承该基类获得CRUD能力。但是在Witrix架构中,根本没有这一需要。Handler只要完成自己特定的功能,它不追求操作概念 在其本身的完整性。没有CRUD, handler没有意义。但是handler之所以有意义是因为它提供了CRUD之外的操作。当CRUD成为系统一种自动进行的背景操作时,我们不再需要 明确意识到它的存在。
    我们需要认识到我们最终所需要的东西可能不是规整结构的, 它可能要求对于某个规整结构进行剪裁并增补附加元素. 但是这样的规整结构不应只存在于我们的想象之中,相应的剪裁过程应该是可以增量进行, 反复进行的. 在Witrix平台中, 基本的一种图景变化是: Witrix中不再需要从头开始构造结构, 而只要指定当前业务和背景模型之间的差异部分. 在Witrix中所写的业务代码是对核心模型的扩展。这不仅仅是概念上的,而是实际体系架构上精确的体现。CRUD作为独立的模型吸收了系统中大量的变 化。整个模型内核是采用通用方式借助meta实现功能,并不涉及到特定于业务的类。对于那些我们已经掌握的知识, Witrix提供了超越对象继承,AOP和组件重用的结构抽取手段, 使得知识可以稳步积累.
      数学中存在两种基本的分解方式, 一种是加性分解 (a,b) + (c, d) => (a,b,c,d), 另一种是乘性分解 (a,b) X (c, d) => (ac,bc,ad,bd), 它也对应于张量(Tensor)运算. 在群论(Group Theory)中,直积对于复杂性的化简至关重要,它的重要性要远在加和之上。实际上AOP操作类似于直积分解, 只是它的能力尚未得到充分的探索。 在Witrix中,biz的作用在感觉上很象是陪集(coset)运算:CURD * biz。不同的biz作用到同样的CRUD模型上产生不同的操作集合,而所有biz组成的集合构成独立的整体。   
      Witrix平台中作为内核的MDA部分首先是物理模型驱动, 而不是逻辑模型或者对象模型驱动. 我们通过在物理模型上标注的方法恢复部分对象模型的信息, 但是我们并不试图把整个软件建立为模型. 所建立的仅仅是整个程序模型的内核. http://canonical.javaeye.com/blog/29412 一般业内鼓吹的所谓MDA成功的关键是要提高抽象层次。 但是陪集是更抽象吗。 正规子群更抽象吗。 它们只是系统的指标性表征,使对信息的distill, 是更容易理解的一个侧面而已, 抽象性并不是一个真正的目标。很多时候我们需要的是把系统降维到某个子空间中,形成一种可控性。 但是这个子空间并不一定是更抽象的。
      群作为基本的代数系,一个本质特征是具有逆元。Witrix的MDA中明确定义了逆元结构,即界面上的元素 empty = buttonA + (-buttonA),这一分解公式应用到后台 OpA = Update * (-Update)  * OpA。假设我们已经建立了结构X, 现在需要建立一个与X略有不同的结构Y
       X = a + b + c
       Y = a + d + c = (a + b + c) - b + d = X - b + d
虽然Y的两种构造方式在数学上是等价的, 但在物理上并不等价。第一种方式对原有系统进行分解后再组装,而第二种方式没有打破原有的东西,不需要拆分。拆分总是可能存在问题的,正如你把所有电脑零 件拆装下来再装上很可能会发现多出几个零件。一般情况下第二种方式的构建成本要低. 特别是当一切都纠缠在一起的时候, 一种细粒度的逆元结构对于一种试图重用的结构是非常关键的. 可重用性的障碍不仅仅是来自于无法追加新的功能,很多时候也在于无法屏蔽原先已经提供的功能。目前所有的设计原则都未能适时识别出逆元的重要性。所有的设 计教条其实所指的方向都是加和, 如何分解出更小的组元, 如何把它们加和在一起, 如何从细部开始进行重新构建, 而不是说依赖于现有已经形成的宏观结构, 如何进行细粒度的调整. 所谓的AOP技术思考的关键点也在于如何给系统增加功能, 很少有人想到场景是为系统减少功能并把这种概念大规模正式应用的, 虽然说AOP已经在某种程度上具有了这种能力, 但是真正应用它仍然需要对AOP进行进一步的诠释. 当然,现在的软件业连基本结构的构造问题都没有完全搞清楚, 更别提所谓结构稳定性的问题了.
     从物理上说,Y = X - b + d的分解方式具有特殊的意味。如果没有逆元,我们必然需要分解。但是如果发掘了背景这一概念,在逆元运算下,对背景不是分解让其成为可见的部分,而是采用 追加的,增删的方法对背景结构进行修正,则我们有可能在没有完整背景知识的情况下,独立的理解局部变化的结构。即背景是透明的,知识成为局部的。      
    Witrix试图提供的一种图景是永远只写代码片断,而所有的代码片断组合在一起又构成一个可理解的整体。这个整体可以独立理解,不需要额外的结构元素。 Witrix架构所追求的是在不完全信息下建模,不进行整体建模。整体模型 + 不断变化的局部修正 构成 最终模型。平台技术的目标是让一切应该发生的自动发生,让一切不该发生的无法发生。这一模型的构建并不是trivial的,在概念和实现方面都要作出很多 的努力。
     
题外:
     今天中午参加同学的婚礼, 席间和一个与同方有些渊源的同学谈到ezOne的现状, 大致的评语是: 垃圾, 自己人也不用. 听来也让人有些感叹. 中国原创的技术总是欺骗的代名词,  这一断言不应总是得到证实.

posted @ 2007-09-23 23:53 canonical 阅读(1221) | 评论 (0)编辑 收藏

  建筑学的隐喻在软件业中一直很流行。开发软件和建筑楼房从某种意义上说都是一种构造过程,而建筑学的成熟无疑让很多软件工程师非常羡慕。Design Pattern的始作俑者坦承受到建筑学著作的影响更是让一些人对建筑学的精深顶礼膜拜不已。不过,建筑决不只是表面上的形象/功能设计,也决不是民工就可以干的活计,在现代建筑设计背后是土木工程的蓬勃发展。正是框架结构的出现和材料工艺的进步才使得批量生产的大型现代建筑成为可能。
  虽然建筑学有着它不为人知的复杂性的一面,但是与软件开发相比,它也有着简单贫瘠的一面。现在架构师言必称设计模式,但是估计很少有人读过Christopher Alexander的原著"A Pattern Language"。在Alexander的概念中,所谓的模式"describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice". 关键在于这些模式在建筑学中往往映射为某种独立的原子化的实体(entity), 因此可以把它们作为一种语言的基础组分,构成所谓的Pattern Language. 例如现在要开发一个门廊,你可以从"私家的沿街露台(140)"开始,在"有阳光的地方(161)"做成一个"有围合的户外小空间(163)", 选择"6英尺深的阳台(167)", 保留"小路和标志物(120)", 注意"天花高度变化(190)"和"角柱(212)"的位置,在"各式座椅(251)"的旁边安排一个"高花台(245)". Alexander共定义了253个模式,括号中的便是模式的编号。很明显,物理空间的不可重入性直接规范了建筑设计空间的有限性。
  在软件设计中,类似VB/Delphi的可视化界面设计的操作过程与此类似:理想情况下界面开发基本就是用各种界面元素填满一个Form的过程。但是软件的一个本质复杂性在于它的基本结构单元是函数,而设计空间中同一个功能点对应的实现函数的个数和形式并不存在有限性的约束,函数的组合形式也不是线性延展的。建筑基本上依赖的是静力学,而软件无疑需要用动力学来刻画。即使是界面开发,我们所关注的也决不仅仅是静态摆放问题,而更重要的往往是界面元素动态相关和动态变化的问题。
  在Web开发领域,一直有人鼓吹模仿VB/Delphi的快速开发工具,但是我并不认为这其中的设计哲学是与软件的本质相匹配的。软件中所蕴含的无限的动态变化不应该仅仅通过有限的配置过程来应对,我们需要更加强大的结构抽象和结构构建手段。

posted @ 2007-09-09 20:00 canonical 阅读(867) | 评论 (0)编辑 收藏

    程序中大量的工作其实都是在定义结构以及结构之间的关系. 一般情况下我们应该识别出结构,并把它们封装到函数,对象和组件中去. 但是封装并不永远都是有利的. 将某个结构独立出来, 在某种程度上也就割裂了它和其他元素之间的关系, 这会引发结构融合的障碍, 也会造成思维上的负担. 事实上如果程序整体具有足够的可理解性和概念稳定性, 我们并不需要独立识别出什么子部分. 一个简单的例子是数组循环. 一般情况下我们应该尽量把循环查找等操作封装到函数中, 避免多重循环嵌套时产生过于复杂的代码块. 但是如果数组或者语言本身提供了each, map等函数式操作符,则这种封装需求就大大减弱了.
    随着系统结构的日益复杂化, 在系统中会积累大量的背景知识.此时当我们需要完成一个功能的的时候, 往往不再需要指定所有的信息, 而只需要指定背景知识之外的部分信息即可. 例如在界面上通过一个分页表格来显示实体列表这样一个功能, 在Witrix平台中通过模型驱动的标准页面即可自动完成. 一般的定制需求往往是过滤显示部分数据, 在表格行上增加一些操作按钮, 定制表格的表头等. Witrix平台实现这些需求并不需要封装出一个独立的表格组件, 调用它的属性修改方法等, 而是把定制部分嵌入到BizFlow的配置中, 这里并没有明确的结构界限.
  <biz id="default">
    <filter>
       <eq name="status" value="1" />
    <filter>
     <tpls>
        <tpl id="thead>
         <thead>
          <tr rowspan="2">...</tr>
          <tr>...</tr>
         </thead>
        </tpl>
        <tpl id="rowOps">
          <ui:FlatButton .../>
        </tpl>
     </tpls>
      其他与表格无关的信息
  </biz>
  注意到对于我们理解业务而言, 我们并不需要知道表格具有分页, 排序, 隔行变色等功能. 所有和业务相关的代码聚集到BizFlow文件中, 它们构成一个可以独立理解的整体, 在此过程中也通过背景知识实现了大量结构的消解.

posted @ 2007-09-02 09:45 canonical 阅读(806) | 评论 (3)编辑 收藏

   传统上报表引擎主要完成两项工作:结构描述和结构转换。一般报表设计人员通过可视化设计工具完成对报表结构的描述,然后报表引擎根据这些描述生成不同格式的报表文件,如PDF格式,XLS格式等。这一图景中报表设计工具扮演着关键角色,因为它不仅仅是向用户提供一个直观的界面,更重要的是配置过程本身就是一种分步骤的结构构造过程。理想的情况是用户指定报表中具体有哪些单元格,表格具体有哪些列,而在运行期报表引擎负责向单元格中填充数据。但是对于设计期只能进行动态描述,无法预先确定所有结构元素的报表(例如交叉表的列只能在执行时确定),这种报表模型就会出现问题。一般处理方式都是在报表引擎中内置所有可能的动态报表模型。无论设计工具多么复杂,其内置的原理如果是基于静态结构模型,就无法建立一种抽象机制,这样我们就只能通过重复劳动来应对众多结构类似但是略有不同的报表。
   Witrix平台的报表引擎是对程序友好的,它引入了编译期结构运算,在报表编译时可以通过程序吸收大部分结构差异性。在Witrix平台中,报表制作分为三个阶段:设计期 -> 编译期 -> 运行期。报表引擎负责完成三种工作:结构描述,结构生成和结构转换。具体实现动态结构生成的过程其实非常简单。目前所有的Witrix配置文件都通过基础配置引擎进行解析,它定义了统一的dynamic和extends元机制。
   <report dynamic="true">
定义了dynamic="true"的报表定义文件首先作为tpl模板文件来运行,其运行结果再作为报表格式解析。在这种模型下,报表引擎并没有内置如何把动态结构拼接出来的知识,这些知识存在于编译期,而tpl标签的抽象能力使得我们可以把复杂的报表结构生成过程抽象成简单的标签调用形式。
   <report dynamic="true">
      <body>
        <table>
         <thead>
            <c:forEach var="_h" items="${cols}">
             ....
        </table>
      </body>
   </report>

==>
   <report dynamic="true">
      <body>
         <rpt:GenCrossTable tableMeta="${tableMeta}" loopVar="tableData" />
      </body>
   </report>

   在编译期通过tpl封装可以解决大部分结构生成问题,在运行期报表引擎主要负责的结构问题就简化为数据行展开和单元格合并等确定操作。
   Witrix报表引擎的另一个特点是运行期结构生成过程和结构转换过程同时进行,因此不需要在内存中构造一个完整的报表数据对象,大大减轻了内存压力。Witrix报表引擎输出的文件格式目前有html, XML格式的Word文件和XML格式的Excel文件等。每一种输出格式相当于定义了一种渲染模型,它们都是对报表模型的一种展现方式。从某种程度上说这些模型的结构都是等价的,但是完成模型转换所需要的操作往往不是局域化的。例如在html的table中某一单元格具体对应哪一列是受到其他单元格的rowspan和colspan属性影响的, 在Excel中则需要明确指定列的index属性。为了简化运行期逻辑,内置的报表模型必须提供一些冗余结构,从而兼容多种渲染模型。

posted @ 2007-09-02 09:45 canonical 阅读(1649) | 评论 (1)编辑 收藏

仅列出标题
共18页: 上一页 1 2 3 4 5 6 7 8 9 下一页 Last