<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-canonical-随笔分类-设计理论</title><link>http://www.blogjava.net/canonical/category/4849.html</link><description /><language>zh-cn</language><lastBuildDate>Sun, 25 May 2008 22:05:08 GMT</lastBuildDate><pubDate>Sun, 25 May 2008 22:05:08 GMT</pubDate><ttl>60</ttl><item><title>主从分解而不是正交分解</title><link>http://www.blogjava.net/canonical/archive/2008/05/26/202801.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Sun, 25 May 2008 16:41:00 GMT</pubDate><guid>http://www.blogjava.net/canonical/archive/2008/05/26/202801.html</guid><wfw:comment>http://www.blogjava.net/canonical/comments/202801.html</wfw:comment><comments>http://www.blogjava.net/canonical/archive/2008/05/26/202801.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/canonical/comments/commentRss/202801.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/canonical/services/trackbacks/202801.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 说到分解，很多人心中的意象大概只有正交分解。正交分解无疑是最重要的一种分析方法，它也是所谓&#8220;分而治之&#8221;思想最常见的实现策略。但是正交分解一般潜在的假定是分解后的子部分是大致均衡的，它们是相对具有独立价值的，可以彼此脱离独立发展。这是分解后实现系统解耦的重要原因。<a href="http://canonical.javaeye.com/blog/33885">http://canonical.javaeye.com/blog/33885</a> 但是物理学中另一种重要的分析学思想是微扰论(Perturbation). 针对一个复杂的物理现象，首先建立一个全局的规范的模型，然后考虑各种微扰条件对原有模型的影响。在小扰动情况下，模型的变化部分往往可以被线性化，被局域化，因而问题得到简化。微扰分析得到的解依赖于全局模型的解而存在，因而这是一种主从关系的分解方式。但是如果主体模型是我们已经熟知的物理现象，则我们关注的重点可以全部放在扰动解上，认为所有特定的物理规律都体现在扰动解中。如果微扰分析得到的物理元素足够丰富，则微扰模型本身可以成为独立的研究对象，在其中我们同样可以发现某种普适的结构规律。<br />
&nbsp;&nbsp;&nbsp; Witrix平台中系统化的应用主从分解模式，通过类似AOP的技术实现了业务模型与平台技术的自然结合。<a href="http://canonical.javaeye.com/blog/126467">http://canonical.javaeye.com/blog/126467</a> 最近我们的一个产品的新版本即将在全国范围内部署，如何有效的控制众多相近的二次开发版本，同时确保主版本的快速升级，是在架构层面必须解决的问题。<a href="http://canonical.javaeye.com/blog/73265">http://canonical.javaeye.com/blog/73265</a> 在Witrix平台中，各部署版本并不是直接修改主版本源代码得到，而是将差异化代码放在单独的目录中进行管理，由系统运行平台负责将差异化定制代码与主版本代码进行动态融合，实现部署版本的客户化。在这一过程中，系统模型本身支持逆元结构至关重要，否则某些多余的元素无法通过差异性描述去除，则将出现局部模型失效的情况。<br />
&nbsp;&nbsp;&nbsp; Witrix平台定义了特殊的_custom目录，它的内部目录结构与defaultroot目录相同，系统平台优先使用该目录下文件所提供的功能实现。同时定义了系统参数global.app_id和global.default_app_id，它们分别用来区分当前程序版本以及程序主版本代码。例如当global.app_id=beijing,global.default_app_id=main的时候，系统中装载ui.xml这个标签库时经历如下过程，<br />
1.&nbsp;&nbsp; &nbsp;装载平台内置的标签库，文件路径为 /_tpl/ui.xml.<br />
2.&nbsp;&nbsp; &nbsp;根据global.default_app_id设置，装载/_custom/main/_tpl/ui.xml, 其中定义的标签实现将覆盖平台缺省提供的标签实现。对于那些不需要特殊定制的标签，继续使用平台提供的缺省实现。<br />
3.&nbsp;&nbsp; &nbsp;根据global.app_id设置，装载/_custom/beijing/_tpl/ui.xml, 其中定义的标签实现将覆盖产品主版本的标签实现。<br />
<br />
基础平台中对于代码动态融合定义了精细的融合策略，将通过编译技术检查扩展标签的接口与缺省实现的接口相兼容，由此确保代码扩展后不会破坏主版本中的已有调用代码。<br />
&nbsp;&nbsp;&nbsp; 在基础平台的实现中，很多实现代码都是类似<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">df:WhenAllowFinishWf</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">df:FinishWfButton&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">df:WhenAllowFinishWf</span><span style="color: #0000ff;">&gt;</span></div>
<br />
这样的类似废话的标签调用。但是通过这些标签的标记，我们确立了系统的逻辑结构，标定了系统中可以被安全替换的逻辑片断。
<img src ="http://www.blogjava.net/canonical/aggbug/202801.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/canonical/" target="_blank">canonical</a> 2008-05-26 00:41 <a href="http://www.blogjava.net/canonical/archive/2008/05/26/202801.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>不完全的计算</title><link>http://www.blogjava.net/canonical/archive/2008/03/16/186614.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Sun, 16 Mar 2008 07:04:00 GMT</pubDate><guid>http://www.blogjava.net/canonical/archive/2008/03/16/186614.html</guid><wfw:comment>http://www.blogjava.net/canonical/comments/186614.html</wfw:comment><comments>http://www.blogjava.net/canonical/archive/2008/03/16/186614.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/canonical/comments/commentRss/186614.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/canonical/services/trackbacks/186614.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 在与一些年岁较大的C程序员接触的过程中，可以比较明显的感受到C的思维方式与面向对象思想的不同。C的世界很清澈，先做A, 再做B, 我们所期待发生的计算过程与源代码的结构是直接一一对照的。这意味着程序将要执行的计算过程在编写代码的时刻就已经确定下来。面向对象首先需要确定的是类，对象等中间元素，而并不是最终的计算过程。对象可以之间可以产生很复杂的结构关系，透过这种中间逻辑结构我们来理解最终要发生的计算过程。在事件驱动的应用场景下，面向对象是一种更加有效的描述，<br />
&nbsp; o.someFunc()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o.onEventA();<br />
&nbsp;&nbsp;&nbsp; sub1.someFunc();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ==&gt;&nbsp;&nbsp;&nbsp;&nbsp; sub1.onEventA();<br />
&nbsp;&nbsp;&nbsp; sub2.someFunc();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sub2.onEventB();<br />
如果把对象看作是函数+状态的集合，则对象组装的关系实际上是函数集合之间的一种组装关系。当具体的事件发生的时候，将触发对象上确定的响应函数，此时在各个层面上所实际发生的计算才能被确定下来。<br />
<br />
<br />
<br />
<img src ="http://www.blogjava.net/canonical/aggbug/186614.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/canonical/" target="_blank">canonical</a> 2008-03-16 15:04 <a href="http://www.blogjava.net/canonical/archive/2008/03/16/186614.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>WebMVC之前世.今生</title><link>http://www.blogjava.net/canonical/archive/2008/02/18/180551.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Mon, 18 Feb 2008 14:02:00 GMT</pubDate><guid>http://www.blogjava.net/canonical/archive/2008/02/18/180551.html</guid><wfw:comment>http://www.blogjava.net/canonical/comments/180551.html</wfw:comment><comments>http://www.blogjava.net/canonical/archive/2008/02/18/180551.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/canonical/comments/commentRss/180551.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/canonical/services/trackbacks/180551.html</trackback:ping><description><![CDATA[&nbsp;&nbsp; 所谓WebMVC即Model2模型是目前Web开发领域的主流模型，Struts/Struts2框架是其典型实现。在概念层面上，这种程序组织模型是怎样建立起来的?与其他Web开发模型(如面向对象模型)具有怎样的联系? 它未来可能的发展方向在哪里? 结合Witrix开发平台的具体实践，基于级列设计理论我们可以看到一条概念发展的脉络。<a href="http://canonical.javaeye.com/blog/33824">http://canonical.javaeye.com/blog/33824</a><br />
<img src="http://www.blogjava.net/images/blogjava_net/canonical/web_app_structure.jpg" alt="" border="0" height="992" width="747" /><br />
&nbsp;&nbsp; 1. 外部视角：原始的servlet规范提供了一个简单的面向IO的程序响应模型。一次前台访问由一个特定的servlet负责响应，它从request中读取输入流，在全局session中保持临时状态，向response中写入输出流。在此基础上，JSP提供的模板概念翻转了程序和输出文本之间的相对地位，简化了文本输出过程。至此，这种整体的程序模型基本上只是规范化了外部系统访问Web服务器的响应模型，并没有对后台程序的具体实现制定明确的约束条件。因此在最粗野的后台实现中，读取参数，业务处理，生成页面等处理步骤是纠缠在一起的，很难理解，也很难重用。每一个后台页面都是一个不可分析的整体。<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&lt;%</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;String&nbsp;paramA&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;request.getParameter(</span><span style="color: #000000;">"</span><span style="color: #000000;">paramA</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;ResultSet&nbsp;rsA&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
</span><span style="color: #000000;">%&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;result&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;%=</span><span style="color: #000000;">rsA.getString(</span><span style="color: #000000;">0</span><span style="color: #000000;">)&nbsp;</span><span style="color: #000000;">%&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;String&nbsp;paramB&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;request.getParamter(</span><span style="color: #000000;">"</span><span style="color: #000000;">paramB</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;ResultSet&nbsp;rsB&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
</span><span style="color: #000000;">&lt;%</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;rsB.close();<br />
&nbsp;&nbsp;&nbsp;rsA.close();<br />
&nbsp;&nbsp;&nbsp;conn.close();<br />
</span><span style="color: #000000;">%&gt;</span></div>
<br />
<br />
2. 自发分离：在复杂的程序实践中，我们会自发的对业务处理代码和界面代码进行一定程度的分离。因为我们可以直观的感受到这两种代码的稳定性并不匹配。例如不同业务处理过程产生的结果都可以用一个html表格来展现，而同一个业务处理过程产生的结果页面可能经常发生变化。一般我们倾向于将业务代码写在页面上方，而界面代码写在页面下方，并使用一些原始的分解机制，例如include指令。这种分离是随意的，缺乏形式边界的。例如我们无法表达被包含的页面需要哪些参数，也难以避免全局变量名冲突。需要注意的是，分层的一般意义在于各个层面可以独立发展，它的隐含假定是各层面之间的交互是规范化的，只使用确定的数据结构，按照确定的方式进行交互。例如业务层和界面层通过标准的List/Map等数据结构交互，而不是使用具有无限多种样式的特殊的数据结构。(在弱类型语言环境中，实体对象的结构和Map是等价的).<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&lt;%</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;List&nbsp;header&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
&nbsp;&nbsp;&nbsp;List&nbsp;dataList&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
</span><span style="color: #000000;">%&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #000000;">&lt;%</span><span style="color: #000000;">@&nbsp;include&nbsp;file</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">/show_table.jsp</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">%&gt;</span></div>
<br />
<br />
&nbsp;&nbsp; 3. 规范分离：JSP所提供的useBean和tag机制，即所谓的Model1模型，是对程序结构分离的一种规范化。业务代码封装在java类中，一般业务函数与web环境无关，即不使用request和response对象, 允许单元测试。tag机制可以看作是对include指令的增强，是一种代码重用机制。tld描述明确了调用tag时的约束关系。调用tag时需要就地指定调用参数，而include页面所依赖的参数可能是在此前任意地方指定的，是与功能实现分离的。此外tag所使用的参数名是局部对象上的属性名，从而避免了对全局变量的依赖。很遗憾的是，jsp tag所封装的仍然是原始的IO模型，对程序结构缺乏精细的定义，在概念层面上只是对文本片段的再加工，难以支撑复杂的控件结构。早期jsp tag无法利用jsp模板本身来构造，无法构成一个层层递进的概念抽象机制，更是让这种孱弱的重用模型雪上加霜。在其位却无能谋其政，这直接造成了整个j2ee前台界面抽象层的概念缺失，以致很多人认为一种前台模板重用机制是无用的。在Witrix平台中所定义的tpl模板语言，充分利用了xml的结构特点，结合编译期变换技术，成为Witrix平台中进行结构抽象的基本手段。实际上，xml能够有效表达的语义比一般人所想象的要多得多。<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">　</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">jsp:useBean&nbsp;id</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">myBiz</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">/&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;</span><span style="color: #000000;">&lt;%</span><span style="color: #000000;">&nbsp;List&nbsp;dataList&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;myBiz.process(paramA)&nbsp;</span><span style="color: #000000;">%&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">ui:Table&nbsp;data</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">&lt;%=&nbsp;dataList&nbsp;%&gt;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">/&gt;</span></div>
<br />
&nbsp;&nbsp; <br />
&nbsp; 4. 框架分离：在Model1模型中，页面中存在着大量的粘结性代码，它们负责解析前台参数，进行类型转换和数据校验，定位特定的业务处理类，设置返回结果，控制页面跳转等。一种自然的想法是定义一个全局的程序框架，它根据集中的配置文件完成所有的粘结性操作。这也就是所谓面向action的WebMVC模型。这一模型实现了服务器端业务层和界面层在实现上的分离，但是对于外部访问者而言，它所暴露的仍然是原始的自动机模型：整个网站是一个庞大的自动机，每次访问都触发一个action，在action中可能更改自动机的状态（作为全局状态容器的session对象或者数据库）。struts作为面向action框架的先驱，它也很自然的成为了先烈。struts中所引入的FormBean, 链接管理等概念已经在实践中被证明是无益的。一些新兴的框架开始回归到通用的Map结构，直接指定跳转页面，或者利用CoC(Convention Over Configuration)缺省映射.<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;RegisterAction&nbsp;</span><span style="color: #0000ff;">extends</span><span style="color: #000000;">&nbsp;Action&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;ActionForward&nbsp;perform&nbsp;(ActionMapping&nbsp;mapping,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ActionForm&nbsp;form,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletRequest&nbsp;req,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletResponse&nbsp;res)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;RegisterForm&nbsp;rf&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(RegisterForm)&nbsp;form;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;mapping.findForward(</span><span style="color: #000000;">"</span><span style="color: #000000;">success</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
}</span></div>
<br />
&nbsp;&nbsp; <br />
5. 横向延展：分层之后必然导向各个层面的独立发展，我们的视野自然也会扩大到单个页面之外，看到一个层面上更多元素之间的相互作用．在面向对象语言大行其道的今天，继承(inheritance)无疑是多数人首先想到的程序结构组织手段．后台action可以很自然的利用java语言自身的继承机制，配置文件中也可以定义类似的extends或者parent属性．但是对于前台页面一般却很少有适用的抽象手段，于是便有人致力于前台页面的对象语言化：首先将前台页面采用某种对象语言表达，然后再利用对象语言内置的结构抽象机制．放弃界面的可描述性，将其转化为某种活动对象，在我看来是一种错误的方向．而JSF(JavaServerFace)规范却似乎想在这个方向上越走越远．JSF早期设计中存在的一个严重问题是延续了面向对象语言中的状态与行为绑定的组织方式．这造成每次访问后台页面都要重建整个Component Tree, 无法实现页面结构的有效缓存．而Witrix平台中的tpl模板语言编译出的结构是无状态的，可以在多个用户之间重用．<br />
<br />
&nbsp; 6. 相关聚合：对象化首先意味着相关性的局域化，它并不等价于对象语言化. 当面对一个大的集合的时候，最自然的管理手段便是分组聚合：紧密相关的元素被分配到同一分组，相关性被局域化到组内．例如，针对某个业务对象的增删改查操作可以看作属于同一分组. struts中的一个最佳实践是使用DispatchAction, 它根据一个额外的参数将调用请求映射到Action对象的子函数上．例如/book.do?dispatchMethod=add. 从外部看来，这种访问方式已经超越了原始的servlet响应模型，看起来颇有一些面向对象的样子，但也仅仅局限于样子而已．DispatchAction在struts框架中无疑只是一种权宜之计，它与form, navigation等都是不协调的，而且多个子函数之间并不共享任何状态变量（即不发生内部的相互作用），并不是真正对象化的组织方式．按照结构主义的观点，整体大于部分之和．当一组函数聚集在一起的时候，它们所催生的一个概念便是整体的表征：this指针．Witrix平台中的Jsplet框架是一个面向对象的Web框架，其中同属于一个对象的多个Action响应函数之间可以共享局部的状态变量（thisObj），而不仅仅是通过全局的session对象来发生无差别的全局关联．<a href="http://canonical.javaeye.com/blog/33873">http://canonical.javaeye.com/blog/33873</a> 需要注意的是，thisObj不仅仅聚集了后台的业务操作，它同时定义了前后台之间的一个标准状态共享机制，实现了前后台之间的聚合．而前台的add.jsp, view.jsp等页面也因此通过thisObj产生了状态关联，构成页面分组．为了更加明确的支持前台页面分组的概念，Witrix平台提供了其他一些辅助关联手段．例如标准页面中的按钮操作都集中在std.js中的stdPage对象上，因此只需要一条语句stdPage.mixin(DocflowOps);即可为docflow定制多个页面上的众多相关按钮操作．此外Witrix平台中定义了标准的url构建手段，它确保在多个页面间跳转的时候，所有以$字符为前缀的参数将被自动携带．从概念上说这是一种类似于cookie，但却更加灵活，更加面向应用的状态保持机制．<br />
<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">　　</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;DaoWebAction&nbsp;</span><span style="color: #0000ff;">extends</span><span style="color: #000000;">&nbsp;WebContext{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IEntityDao&nbsp;entityDao;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;metaName;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;Object&nbsp;actQuery(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;thisObj.put(</span><span style="color: #000000;">"</span><span style="color: #000000;">pager</span><span style="color: #000000;">"</span><span style="color: #000000;">,pager);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;success();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;Object&nbsp;actExport(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Pager&nbsp;pager&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(Pager)thisObj.get(</span><span style="color: #000000;">"</span><span style="color: #000000;">pager</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;success();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<br />
<br />
&nbsp; 7. 描述分离：当明确定义了Action所聚集而成的对象结构之后，我们再次回到问题的原点：如何简化程序基元（对象）的构建？继承始终是一种可行的手段，但是它要求信息的组织结构是递进式的，而很多时候我们实际希望的组织方式只是简单的加和。通过明确定义的meta(元数据)，从对象中分离出部分描述信息，在实践中被证明是一种有效的手段。同样的后台事件响应对象(ActionObject)，同样的前台界面显示代码(PageGroup)，配合不同的Meta，可以产生完全不同的行为结果, 表达不同的业务需求。<a href="http://canonical.javaeye.com/blog/114066">http://canonical.javaeye.com/blog/114066</a> 从概念上说，这可以看作是一种模板化过程或者是一种复杂的策略模式 ProductWebObject = DaoWebObject&lt;ProductMeta&gt;。当然限于技术实现的原因，在一般框架实现中，meta并不是通过泛型技术引入到Web对象中的。目前常见的开发实践中，经常可以看见类似BaseAction&lt;T&gt;, BaseManager&lt;T&gt;的基类，它们多半仅仅是为了自动实现类型检查。如果结合Annotation技术，则可以超越类型填充，部分达到Meta组合的效果。使用meta的另外一个副作用在于，meta提供了各个层面之间新的信息传递手段，它可以维系多个层面之间的共变(covariant)。例如在使用meta的情况下，后台代码调用requestVars(dsMeta.getUpdatableFields())得到提交参数，前台页面调用forEach dsMeta.getViewableFields()来生成界面. 则新增一个字段的时候，只需要在meta中修改一处，前后台即可实现同步更新，自动维持前后台概念的一致性。有趣的是，前后台在分离之后它们之间的关联变得更加丰富。<br />
<br />
8. 切面分离: Meta一般用于引入外部的描述信息，很少直接改变对象的行为结构。AOP(Aspect Oriented Programming)概念的出现为程序结构的组织提供了新的技术手段。AOP可以看作是程序结构空间中定位技术和组装技术的结合，它比继承机制和模板机制更加灵活，也更加强大。<a href="http://canonical.javaeye.com/blog/34941">http://canonical.javaeye.com/blog/34941</a> Witrix平台中通过类似AOP的BizFlow技术实现对DaoWebAction和前台界面的行为扩展，它可以在不扩展DaoWebAction类的情况下，增加/修正/减少web事件响应函数，增加/修正/减少前台界面展现元素。当前台发送的$bizId参数不同的时候，应用到WebObject上的行为切片也不同，从而可以自然的支持同一业务对象具有多个不同应用场景的情况（例如审核和拟制）。在BizFlow中定义了明确的实体化过程，前台提交的集合操作将被分解为针对单个实体的操作。例如前台提交objectEvent=Remove&amp;id=1&amp;id=2,将会调用两次&lt;action id="Remove-default"&gt;操作。注意到AOP定位技术首先要求的就是良好的坐标定义, 实体化明确定义了实体操作边界，为实体相关切点的构造奠定了基础。<a href="http://canonical.javaeye.com/blog/33784">http://canonical.javaeye.com/blog/33784</a><br />
<br />
9. 背景消除：在Witrix平台中, (DaoWebAction + StdPageGroup + Meta + BizFlow)构成完整的程序模型，因此一般情况下并不需要继承DaoWebAction类，也不需要增加新的前台页面文件，而只需要在BizFlow文件中对修正部分进行描述即可。在某种程度上DaoWebAction+StdPageGroup所提供的CRUD(CreateReadUpdateDelete)模型成为了默认的背景知识。如果背景信息极少泄漏，则我们可以在较高抽象层次上进行工作，而不再理会原始的构造机制。例如在深度集成hibernate的情况下，很少会有必须使用SQL语句的需求。BizFlow是对实体相关的所有业务操作和所有页面展现的集中描述，在考虑到背景知识的情况下，它定义了一个完整的自给自足的程序模型。当我们的建模视角转移到BizFlow模型上时，可以发展出新的程序构造手段。例如BizFlow之间可以定义类似继承机制的extends算子，可以定义实体状态驱动的有限自动机，可以定义不同实体之间的钩稽关系（实体A发生变化的时候自动更新实体B上的相关属性），也可以定义对Workflow的自然嵌入机制。从表面上看，BizFlow似乎回归到了前后台大杂烩的最初场景（甚至更加严重，它同时描述了多个相关页面和多个相关操作），但是在分分合合的模型建立过程中，大量信息被分解到背景模型中，同时发展了各种高级结构抽象机制, 确保了我们注意力的关注点始终是有限的变化部分。而紧致的描述提高了信息密度，简化了程序构造过程。<a href="http://canonical.javaeye.com/blog/126467">http://canonical.javaeye.com/blog/126467</a><br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">bizflow&nbsp;</span><span style="color: #ff0000;">extends</span><span style="color: #0000ff;">="docflow"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #008000;">&lt;!--</span><span style="color: #008000;">&nbsp;引入docflow模型，包括一系列界面修正和后台操作　</span><span style="color: #008000;">--&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">biz&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="my"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">tpls</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">tpl&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="initTpl"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">script&nbsp;</span><span style="color: #ff0000;">src</span><span style="color: #0000ff;">="my_ops.js"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">&gt;&lt;/</span><span style="color: #800000;">script</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">script</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stdPage.mixin(MyOps);&nbsp;//&nbsp;引入多个页面上相关按钮对应的操作<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">script</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">tpl</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">tpls</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">biz</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">bizflow</span><span style="color: #0000ff;">&gt;</span></div>
<br />
<br />
<br />
<img src ="http://www.blogjava.net/canonical/aggbug/180551.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/canonical/" target="_blank">canonical</a> 2008-02-18 22:02 <a href="http://www.blogjava.net/canonical/archive/2008/02/18/180551.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关系模型与ORM</title><link>http://www.blogjava.net/canonical/archive/2008/01/06/173154.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Sun, 06 Jan 2008 11:04:00 GMT</pubDate><guid>http://www.blogjava.net/canonical/archive/2008/01/06/173154.html</guid><wfw:comment>http://www.blogjava.net/canonical/comments/173154.html</wfw:comment><comments>http://www.blogjava.net/canonical/archive/2008/01/06/173154.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/canonical/comments/commentRss/173154.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/canonical/services/trackbacks/173154.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 关系数据库模型在理论上主要解决的是消除数据冗余的问题。关系模型的数学基础是所谓的集合论，而集合的基本含义正是一组具有某种原子性的互不相同的元素。面向对象技术是对相关性进行局域化的一种手段（相关的数据和操作聚集到同一对象名义下），在这一局域化过程中，相同的元素被识别出来，成为独立的对象。从某种意义上说，关系模型与对象模型是殊途同归的过程，是从不同侧面对同一事物的反映。关系模型中，我们关注的重点是元素组成的集合，允许的连接关系定义在集合之上。而在对象模型中，我们关注的首先是横向关联的实体，实体之间具有稳定的联系。在概念层面上，从对象模型映射到一种关系存储模型只是一个分组问题。为了断开实体之间的直接联系，关系模型创造了一个id字段，而对象模型并不是需要显式id的。在关系模型中，关联并不是通过某种存在的结构来表达的（一个实体持有另一个实体的指针，拥有直接联系），而是将直接关联问题弱化为某种计算过程，我们必须检查id的值（不是某种直接的存在性），通过某种运算过程才能重新发现数据之间的关联。<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 通过id（伴随一个匹配计算过程）来进行间接关联对于保证模型的一致性是非常关键的。在ORM中恢复了对象的强关联其实会造成很多潜在的复杂性。例如为了维护对象层面结构的一致性，在更新父子关系的时候，我们需要同时调用 child.setParent(parent); parent.getChildren().remove(child); 当关联结构更加复杂的时候，这里所需要的维护工作是随之增加的。不过，在ORM中，对象的形态是暂时性的。在ORM的一次session的操作过程中，对于对象状态的修改可以是不一致的。例如我们可以只调用child.setParent(parent); 而不需要同时&nbsp; parent.getChilren().remove(child); 只要我们在此次session操作中，不需要同时用到parent.getChildren(). 这种关联的暂时性对于很多ORM应用来说是必不可少的。<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 对象模型中可以直接表达的结构关系比关系模型要丰富一些，例如继承关系，many-to-many, one-to-list等。但是所有这些都不是真正本质性的差异。抛弃概念诠释，基类与众多派生类之间的关系基本上可以等价于一组one-to-one关系。而当关联对象本身的重要性凸现出来的时候，当我们无法把它约化为对象上的一些附属特性的时候（例如数组的下标），我们必然要建立相应的关联对象，而这正对应于关系模型中的中间关联表。中间关联表上增加额外的字段是一个自然的扩展过程，而对象模型上做这样的扩充往往表现为形态上的重大的不兼容的变化，例如从getManyToManyEntity() -&gt; getToManyRelation(), 这实际上意味着这里的对象形式是偶然的，简化的。 <br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 在原始的关系数据库模型中，所有的表之间的地位是平等的，所有字段之间的地位是平等的（主键和外键在参与数据关联时和其他字段的处理方式一致）。这种概念上的均一性和普遍性往往被认为是理论的优美之处。但是现实世界是复杂的，发展的方向就是逐步识别出不同之处，并找出自然的表达形式将这些不同表达出来。均匀的关系模型是对称性最高的，最简化的模型。在面对物理约束时，它隐含的假设是集合之间很少发生相互作用，单表（表单到数据表之间的映射）和主从表是最广泛的情况。试着想象一下关系模型，在思维中一般我们只能看到两个数据表，当考虑到多个表的时候，因为这些表之间没有明确的可区分性，因此它们的意象是模糊的。只有明确意识到主键，外键，主表，从表，字典表，事实表，纬度表这些不同的概念的时候，当对称性出现破缺的时候，我们思维中的模型才能够丰富化起来。<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 关系模型理论应用到数据库具体应用中时，并不需要死守关系范式教条，它们只是描述了某种极端化的对唯一性的追求。面对具体应用的时候，理论本身也在不断丰富化。我并不把现实应用中必然需要增加冗余字段看作是关系理论失效的结果。从关系完全分解，到关系完全不分解之间，我们可以建立大量的模型。建立冗余字段的时候，我们存在着大量可能的选择，到底哪一种选择是最优的，理论方面仍然可以给我们以具体的指导。理论在各种不同纯化程度的关系模型中都可以给我们以直观的建议。数据仓库理论中建立的snowflake模式和star模式，强调了针对主题域的允许部分冗余的关系分解。这里实际上是强调了表之间的不同性。不再是所有的表都处于同一地位。Fact Table和Dimension Table之间的区别被识别出来，并被明确处理。在我看来，这是原始关系模型的一种自然发展，它也是关系模型理论的一部分。理论不应该是单一的，而是提供一个模型级列，在不同的复杂性层次上，我们可以根据理论的指导选择具体的实现模型。<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 关于ORM <a href="http://canonical.javaeye.com/blog/111500">http://canonical.javaeye.com/blog/111500</a><br />
&nbsp;&nbsp;&nbsp; 关系模型中的所谓关系是在使用时刻才定义的，所有建立关系的方式在某种程度上都是等价的，也是外在的。而在ORM中主键与外键之间的关联被独立出来，成为模型内置的部分。这在很多时候简化了数据查询的结构构造过程。<br />
&nbsp;&nbsp;&nbsp; 在ORM中主键因为缓存的存在而显出与其他字段的区别。ORM的使用使得数据存储的分解策略得到扩充。并不是所有的表的更新频度都是一致的，而且表中的数据量大小也不同。字典表一般较小，而且很少更新，可以安全的复制。在整个数据存储框架中，ORM作为独立的技术元素参与数据存储过程，通过主键提供缓存服务，产生了新的数据分布模型，提供了新的性能优化契机。<br />
<br />
<br />
<img src ="http://www.blogjava.net/canonical/aggbug/173154.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/canonical/" target="_blank">canonical</a> 2008-01-06 19:04 <a href="http://www.blogjava.net/canonical/archive/2008/01/06/173154.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>代码之外的结构</title><link>http://www.blogjava.net/canonical/archive/2007/12/15/167994.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Sat, 15 Dec 2007 11:46:00 GMT</pubDate><guid>http://www.blogjava.net/canonical/archive/2007/12/15/167994.html</guid><wfw:comment>http://www.blogjava.net/canonical/comments/167994.html</wfw:comment><comments>http://www.blogjava.net/canonical/archive/2007/12/15/167994.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/canonical/comments/commentRss/167994.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/canonical/services/trackbacks/167994.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 我在各种场合一直都在强调结构问题是独立的，在程序语言之外存在着独立的，可研究的，富有成效的结构问题。<a href="http://canonical.javaeye.com/blog/147424 ">http://canonical.javaeye.com/blog/147424 </a>在这个方向上更进一步，我们注意到所有的代码并不是天然出现的，而是由人所编制的，因此代码世界内部并不构成封闭的，自足的某个世界。代码中的结构问题并不是由代码本身完全解决的，即在代码之外仍然存在着技术上可研究的结构问题。<br />
&nbsp;&nbsp;&nbsp; 我们在编制代码的同时也在编制着大量的说明文档。这些文档描述了代码片断之间的相互关系，描述了代码未来的扩展方向，描述了代码之间的可能的交互方式，同时也描述了针对现有代码实现的很多具体约束。例如我们在文档中约定某个量要在10和20之间，但在代码中却不一定显式进行了判断。针对代码结构的很多具体约束条件和相关性描述可能只在文档中体现，只在程序员的头脑中存在，而并不一定忠实的在代码结构中得到表达。<br />
&nbsp;&nbsp;&nbsp; 我在设计领域基本持有一种物理实在论，即某种技术相关的约束应该在技术世界中通过技术手段得到表达。只是这里的技术手段却不一定指在应用中加上特定的代码实现，虽然我们在代码实现中更直接的表达设计要求无疑是需要提倡的。为了在程序中有效的维护结构相关性，我们并不一定需要抽象出所有可能重用的代码，并不一定需要确保某一概念在程序中只有精确的唯一的表达。程序中难以直接精确表达的弱关联，仍然可以通过开发/设计工具等技术手段得到有效的维护。我们需要保证的是代码世界中知识的自恰性，而自恰性并不等于唯一性。<a href="http://canonical.javaeye.com/blog/33788">http://canonical.javaeye.com/blog/33788</a><br />
&nbsp;&nbsp;&nbsp; 在Witrix中我们采用一种物理模型驱动的开发方式，<a href="http://canonical.javaeye.com/blog/29412">http://canonical.javaeye.com/blog/29412</a> 由pdm模型出发，自动生成hibernate的hbm文件，java实体类，元数据meta文件，前台Action注册文件等。生成的配置文件通过syncWithModel标记与模型保持着稳定的关联。所有配置文件都支持手工修改，开发工具识别syncWithModel标记，当pdm模型发生变化的时候，工具自动将变化信息同步到各个配置文件中。注意到这里并不是采用一个统一的元数据模型的方式，各个配置文件所表达的信息在一定程度上是重复的，也可能是不一致的。例如后台数据库允许保存100个字节，但是前台meta中我们可能配置只允许录入20个字节。根据不同应用场景的需要，我们可以在各个层面对每个配置文件进行独立的调节. 当然,在一般情况下并不存在这种需要。整个开发过程中，信息表达的自恰性并不是在应用程序代码中得到定义的,而是因为开发工具的存在而在技术上得到保证的。放松模型之间的唯一匹配要求，我们可以得到更加丰富，更加灵活的软件结构。实际上我认为RoR(RubyOnRails)采用直接映射的ActiveRecord的方式虽然有效保证了系统变动中知识的一致性，但是如果不允许在各个层面上都能够自然的定义某种偏离，它在复杂应用中的价值就要打上大大的折扣。<br />
<br />
<img src ="http://www.blogjava.net/canonical/aggbug/167994.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/canonical/" target="_blank">canonical</a> 2007-12-15 19:46 <a href="http://www.blogjava.net/canonical/archive/2007/12/15/167994.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>结构的独立性</title><link>http://www.blogjava.net/canonical/archive/2007/12/10/166820.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Mon, 10 Dec 2007 15:57:00 GMT</pubDate><guid>http://www.blogjava.net/canonical/archive/2007/12/10/166820.html</guid><wfw:comment>http://www.blogjava.net/canonical/comments/166820.html</wfw:comment><comments>http://www.blogjava.net/canonical/archive/2007/12/10/166820.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/canonical/comments/commentRss/166820.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/canonical/services/trackbacks/166820.html</trackback:ping><description><![CDATA[&nbsp;&nbsp; 设计考虑的是最终需要什么，最终我们要提供的调用接口是什么，我们所直接需要的某个有价值的，直接存在的，直接可以接触的结构是什么，而不是它所依据的原理是什么，不是它的具体构造过程或者构造方法是什么。比如说我们在程序中完全不需要内置Map这一结构，因为它可以通过列表等结构组合构建出来，但是很显然，Map这一概念的直接存在对我们来说是方便的，是经济的，是有效的。我们在思考的时候并不需要考虑它是采用List实现还是采用Set实现，或者任何它本身的构造结构。这一概念在我们的思想中成为某种原子化的东西。<br />
<br />
&nbsp;&nbsp;&nbsp; 那么，我们到底需要构建哪些概念，才能够最方便的基于这些概念应对万千应用系统的开发呢。 这是我们需要在结构空间作出探索的。 这里的思维方向不是把系统推向某种纯粹化，某种极致的简单化，而是让它更加物理化，揭示出更多的层次，更加关切在物理约束情况下如何实现灵活性的最大化。一种概念在物理上如果被证明能够在很多场景下成为不变的基元，则它便是有价值的，是可以进行物理诠释的。<br />
<br />
&nbsp;&nbsp; 很多人习惯于接受语言存在的现实，接受设计后的结果，但是作为程序语言设计者，他们又是如何工作的？他们是否真的是从纯粹的数学关系推演得到所有的语法特征，还是他们预先已经在心中设定了应该出现的语法特征，然后去寻找它的数学表达，只是借此清除思维中潜在存在的矛盾性呢？<br />
<br />
&nbsp;&nbsp;&nbsp; 语言中存在的所有特征是经过全局考虑的，是清除了所有概念的矛盾冲突的。但是在现实中，我们偶然构造的结构却可能是局限于当下的信息构造的，因此它们相会的时候，可能会出现不协调，可能会出现结构障碍。例如同样是关闭操作，有些人命名为close, 另一些人命名为destroy. 可能一个具有额外参数，另外一个没有。这里可能需要一种adaptor接口的封装，也可能使用ruby那种method-missing的动态判断。对于更加错综复杂的结构问题，其解决方案就不是那么显然的了，但这并不意味着我们无办法可想。究竟设计何种结构边界才能最小化结构融合时所要付出的代价呢？结构被识别并表征出来以后，是否允许它在一定范围内有所变形？在变形中我们需要保持的拓扑不变量是什么？结构动态调整的时候，我们是否需要定义调整的物理代价，是否能够定义某种动力学？<br />
<br />
&nbsp;&nbsp; 我所阐述的只是在计算机理论中从数学视角向物理视角的转换，它不是必然给你提供某种超越当下的能力，而是提供一种不同的眼光看待所有的一切。视角变换后，我们发现了一些新的命题，而在原先的视角下在我们的话语体系中原本是无法表达这些命题的。串行程序假设了只有1颗CPU, 而函数式语言假设了可以有无限多个CPU, 你不觉得1至无穷之间缺点什么吗。我们可以创造一些东西把1至无穷之间的空白补齐，概念空间是连续的。<br />
&nbsp;<br />
<br />
<img src ="http://www.blogjava.net/canonical/aggbug/166820.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/canonical/" target="_blank">canonical</a> 2007-12-10 23:57 <a href="http://www.blogjava.net/canonical/archive/2007/12/10/166820.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于抽象性的一些说明</title><link>http://www.blogjava.net/canonical/archive/2007/12/09/166520.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Sun, 09 Dec 2007 14:25:00 GMT</pubDate><guid>http://www.blogjava.net/canonical/archive/2007/12/09/166520.html</guid><wfw:comment>http://www.blogjava.net/canonical/comments/166520.html</wfw:comment><comments>http://www.blogjava.net/canonical/archive/2007/12/09/166520.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/canonical/comments/commentRss/166520.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/canonical/services/trackbacks/166520.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp; 没有人否认抽象的意义，但是抽象是否就是抽象到无穷大，这是个可以明确定义的问题，也是数学领域正在解决的问题。在我们的思考中没有明确定义何处是边界，
没有明确的限制，这便是导向无穷的一种思维方式，它和现实中是否真的允许消耗无限多的资源，创建无限多的对象无关。当我们认为自己明白了终极的意义，明白
了一种推向无穷的抽象，这并不是理解了世界的全部，我们仍然要明白如何解决一些更加小范围，但是却又普遍发生的事情。
<br />
例如现在我的系统中只需要10个相互依赖的线程，如果我们定死了10这个数字，显然我们可以发展一种这个领域特有的高效的一些算法结构。而抽象到通用语言
中的时候，显然我们只能假设线程数是任意大，或者是充分大的，而无法充分利用10这一领域信息，因此在这个意义上我说通用语言不是有效的。
<br />
说到10这个确定的数字，不过是一种极端化的比喻。我常说概念是连续的，并不是非此即彼的，因此并不是从一种普遍情况到一种最特殊的情况之间不再有其他情
况了。在这中间环节，存在着非常深刻的复杂的物理事实。但是这些事实却又是某种有限性向我们揭示出来的。（请不要把这里的有限性理解为算术中的10以内）
<br />
<br />
现在来一个理论推演吧：
<br />
1. 任何系统都在一定约束下运行，即它们需要符合某些约束条件
<br />
2. 通用语言描述了某些结构，但是这些结构是充分通用的，能够应用到尽可能广泛的领域的
<br />
3. 线程数=10这个约束过份特殊，显然通用语言是不会考虑这个约束。实际上目前在通用语言设计中，无限资源假定基本都是默认的。
<br />
4. 我们承认某些现实的约束通用语言是不会考虑的
<br />
5. 在最特殊的，明显不会考虑的约束以及非常通用，一般通用语言必然考虑的约束之间，是否存在着更多的，非平凡的结构呢
<br />
6. 假如10年以内我们所有的硬件都只能支持10个内核，在我的产品研发中假定10个线程有问题吗。难道我在开发的时候就不再需要抽象了吗。我在其他方面仍然是需要建立抽象的。
<br />
7. n个抽象约束+1个具体约束，以及 n个无限约束+1个有限约束 仍然是有效的抽象形式。原谅我在这里又使用了有效一词，它真的很难理解吗。
<br />
8. 不是在我们的思维中存在着具体的或者有限的物理量,就意味着这种思维是不抽象的.
<br />
<br />
函数式语言或者任何一种其他我们已知的与Turing机等价的语言，它们在某种数学的含义上说是"没有差别的"。但是在我们的实际使用过程中，显然我们是
能够感受到它们之间的结构差异的。否则那些不断发明新的函数式语言的人的大脑都进水了吗？在具体使用中，总有人偏好这个语言,有人偏好那个语言,
总是某种情况下应用某个语言会方便一些,另一些麻烦一些。难道在所有函数式语言中开发类似ErLang解决的那些程序结构都是一样方便的吗？
<br />
<br />
有些人的论调是无论啥都逃不出函数式语言的思想。但是假如现在限定你必须使用java语言来开发商业应用，难道你罢工吗？如果你不使用函数式语言，你所做
的工作就不是程序工作了？你所解决的难道不是程序结构问题了吗？现在就是有一个结构问题要解决, 它是和语言无关的. 语言提供了就可以直接用,
语言没有提供我们可以写代码构造. 难道除了语言直接体现的结构之外, 程序本身就无法构造任何具有通用价值的结构了吗？</p>
<p>   我在说到函数式语言的时候，基本的态度只是说不要太沉迷于一种特殊的抽象方式，应该多看看别的视角。在不同的情况下存在着做事情的不同的最优方式。思维中不要只允许永远，而容不下现在。
<br />
<br />
非此即彼，天下唯我,是我们思维中经常陷入的一个误区。现在计算机领域所谓的理论主要是基于数学视角的，没有考虑物理世界因为我们观察的有限性，因为资源
的有限性所造成的种种约束，此外数学中目前也没有考虑到物理世界真实的各种复杂性的存在。在我们想到一种计算机理论的时候，图像过于简单化，这种简单化被
认为是优美的全部。其实我们应该思维更加开放一些。
</p>
<img src ="http://www.blogjava.net/canonical/aggbug/166520.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/canonical/" target="_blank">canonical</a> 2007-12-09 22:25 <a href="http://www.blogjava.net/canonical/archive/2007/12/09/166520.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于语言有效性的一些澄清</title><link>http://www.blogjava.net/canonical/archive/2007/12/09/166472.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Sun, 09 Dec 2007 09:19:00 GMT</pubDate><guid>http://www.blogjava.net/canonical/archive/2007/12/09/166472.html</guid><wfw:comment>http://www.blogjava.net/canonical/comments/166472.html</wfw:comment><comments>http://www.blogjava.net/canonical/archive/2007/12/09/166472.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/canonical/comments/commentRss/166472.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/canonical/services/trackbacks/166472.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 数学上的有效性与物理中的有效性是不同的，例如对于密码学问题，如果通过穷举法破解密码成功时，经过这些密码加密的数据已经过了有效期限，此时我们在数学上定义穷举法不是一种有效的破解方法。但是物理层面上我们说只要一种方法比另一种方法能够更快的解决问题，我们就说第一种方法比第二种方法有效，而无论密码被破解的时候该密码是否已经过了有效期限。<br />
<br />
&nbsp;&nbsp;&nbsp; 我所表述的论题并不是说特定的领域结构无法在某个特定的通用语言中有效实现。我想很多人对我的话语都有些误解。<br />
<strong>如果我们认为一种通用语言是比较稳定的,则它一般选择只内置一些通用的不带有领域特定含义的概念. 而缺乏领域知识,或者说因为通用语言故意的摒弃领域依赖, 它在处理领域相关的问题的时候并不是有效的.这种有效性不是数学含义上的,而是可以进行物理度量的.</strong> <br />
现在ErLang对通信领域具有良好的支持，你可以说它对于通信领域的结构是有效的。但是显然在ErLang中编写界面就不如面向对象语言得心应手。在ErLang中实现界面结构的时候，它对于界面结构的表述就不是那么符合我们直观的，对我们的实现过程来说就不是那么经济的。因此在界面结构的实现上，目前我们可以说ErLang相对于面向对象语言而言就是不那么有效的。也许你会说ErLang做XX发展之后怎见得就更差。但是如果允许引入未来这一具有无限可能性的因子，我们基本上无法针对现实的情况作出判断。例如我们目前并无法证明广义相对论相对于牛顿力学是更加精确的，如果允许在太阳星系中增加越来越多的隐蔽的摄动星体的话。按照库恩的科学革命论，每一个科学时代都具有着自己的科学范式，它总是具有着充分的自我辩护能力。范式的更新意味着格式塔的崩溃。回顾历史，哥白尼刚提出日心说的时候，并不是在计算精度，计算简洁性上真的远胜托勒密的地心说，只是日心说的哲学隐喻撼动了人心。<br />
<br />
&nbsp;&nbsp;&nbsp; 我说<strong>实际上现在的通用语言也是无法有效承载Domain Specific Structure的</strong>，这并不是意指在通用语言中无法针对特定应用作出特定扩展来支持特定的结构，而是说Domain Specific Structure是任意多的，作为通用语言它不应该把越来越多的结构内置在语言中(这不是很多人对ruby的希冀吗)，这么做对它来说首先是不经济的。同时某些特殊的结构在一定的场景下是有用的，但是把它抽象出来扩展到通用领域的时候，会出现有效性的丧失。例如现在我的系统中只需要10个相互依赖的线程，如果我们定死了10这个数字，显然我们可以发展一种这个领域特有的高效的一些算法结构。而抽象到通用语言中的时候，显然我们只能假设线程数是任意大，或者是充分大的，而无法充分利用10这一领域信息，因此在这个意义上我说通用语言不是有效的。<br />
<br />
&nbsp;&nbsp;&nbsp; 传统上数学使用的一种逼近范式是：当n趋于无穷大的时候，偏差趋于无穷小。现在物理学对数学的一种常见要求却是：当n限定在有限数量范围的时候（例如10以内），我们如何才能尽量减少偏差。这要求对小样本数学进行深入的研究，它所具有的物理内涵也是不同的。<br />
<br />
&nbsp;&nbsp;&nbsp; 在物理的视角下，我们所关心的不是世界在终极的意义上能否分解为函数的复合，不是要导向一种宗教式的顶礼膜拜，而是强调要尊重自己所直接感受到的，充分利用我们因为在这个世界上存在而获得的直观意象，发掘自己的直觉，这样我们才能在无限复杂的世界上借助有限的信息做出选择。<br />
<img src ="http://www.blogjava.net/canonical/aggbug/166472.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/canonical/" target="_blank">canonical</a> 2007-12-09 17:19 <a href="http://www.blogjava.net/canonical/archive/2007/12/09/166472.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于通用语言能力的一些澄清</title><link>http://www.blogjava.net/canonical/archive/2007/12/09/166375.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Sat, 08 Dec 2007 16:16:00 GMT</pubDate><guid>http://www.blogjava.net/canonical/archive/2007/12/09/166375.html</guid><wfw:comment>http://www.blogjava.net/canonical/comments/166375.html</wfw:comment><comments>http://www.blogjava.net/canonical/archive/2007/12/09/166375.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/canonical/comments/commentRss/166375.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/canonical/services/trackbacks/166375.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 我在前面的文章中列举了大量物理学相关的例子来试图说明采用物理视角的必要性,但是可能因为物理事实大家不熟悉,结果直接被无视了. 在本文中我想有必要举一个软件领域的例子。只是在实际思考的过程中,我主要还是基于物理概念进行推理.<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 首先我所谓&#8220;<strong>现在的通用语言</strong>&#8221;，它并不意指&#8220;<strong>现在至未来所有通用语言之合集</strong>&#8221;，而是指&#8220;<strong>目前正在被使用的某一种通用语言</strong>&#8221;，这种差别便体现了我所强调的不同的价值观和不同的视角。不是一种覆盖一切的全称判断，而是在特定物理约束下的物理实体。<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 现在无论我们设计什么大型系统，一般总是要优先考虑微内核设计。但是很显然，如果我们的编程控制能力极强（强大到不现实的地步），我们可以把所有的代码实现为一个大的整体。一个整体的好处是勿用质疑的，否则Linux Torvalds就不会有信心和Tanenbaum PK。但即使是Linux, 随着系统越来越庞大，在内核中也补充了很多模块管理策略。我并不把这种情况看作是一种现在技术能力不到位所造成的结果，而是把它看作是在现实的物理约束下所促成的一种必然的选择。<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 按照类似的逻辑，我认为在通用语言层面不应该导入越来越多的特征，实际上也不可能把所有可能的结构方式都内置在语言中（这种不可能不是数学意义上的不可能）。这会破坏一种语言的纯洁性，使得它极难维护和发展。为了扩大通用语言的有效应用范围，一种显然的方式是在语言中定义一些支持结构再次抽象的机制，通过可插拔的方式实现与domain相关的知识的融合。ruby这样的语言提供了大量的元编程机制, Witrix平台中tpl模板语言也发展了一系列编译期结构构造技术, 但是显然它们都不能说是结构抽象技术的终极形态. 目前我对所有通用语言所提供的结构抽象和结构组装能力都是不满意的,因此在Witrix中发展了一些领域特定的结构融合手段.例如根据"继承"关系的结构诠释(继承可以看作是两个一维集合之间的覆盖关系), 我们扩展了extends的结构操作方式, 定义了广义的extends算子. 这些特定的结构关系目前在领域特定的BizFlow语言中体现, 它们在通用语言中是难以想象的, 而把它们放置在通用的语言中也是不合适的(这种复杂的结构融合操作如果不能结合领域知识进行直观的理解, 必将导向一种思维的混乱). 这就是我所谓"现在的通用语言无法有效承载Domain Specific Structure"的含义. 这种说法其实类似于"集合论是无法包容所有数学结构的". 我们在集合论中只研究最普遍的关系,而特定的结构在特定的学科中研究. <br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 关于ErLang的例子, 我的原意是用来说明结构问题是独立的,它是<strong>和具体语言无关</strong>的.即基于消息传递发生数据关联的超轻量级进程模型这一结构不是和ErLang语言绑定的. 为此我特意加了一段说明:"这里不是要证明某种语言中无法描述这些结构，而是说结构是客观存在的，它并不是要在基础语言层面得到充分解决的".<strong> 即使在语言层面我们并不解决这个结构问题, 它仍然客观存在着,我们仍然可以用其他的技术手段去定义,去解决. 解决了这个结构问题就必然会带给我们价值,而无论我们使用何种实现语言</strong>.<br />
<br />
&nbsp;&nbsp;&nbsp; "什么原因，什么样的约束条件,导致了现在的通用语言是无法有效承载消息传递发生数据关联的超轻量级进程模型". 这一命题并不是我原文中论点的合理推论.我并不是要说某一种特定的领域结构无法在一种特定的通用语言中得到支持.而是说如果我们认为一种通用语言是比较稳定的,则它一般选择只内置一些通用的不带有领域特定含义的概念. 而缺乏领域知识,或者说因为通用语言故意的摒弃领域依赖, 它在处理领域相关的问题的时候并不是有效的.这种有效性不是数学含义上的,而是可以进行物理度量的. 现在也有很多人认为ErLang并不是真正的通用语言,它是针对通信领域进行了特定结构调整的, 是内置了领域特定结构的. 而目前在ErLang上建立GUI的努力也并不算是成功. <br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 在前文中我举了一个例子试图说明:"在限定的物理约束下，我们的选择范围会大大缩小". "比如说我现在有无穷多种方式从北京跑到上海，但是如果限定只允许用1升汽油，那么我们的选择就近乎于0". 这里并不是要说明加上物理约束之后,我们便没有任何选择了.而是说物理约束对无穷多的可能方式起了<strong>限定选择</strong>的作用, 它最终造成我们在具体的物理场景下可能只有非常有限的选择. 例如现在允许用100升汽油, 有多少种运输方式可以满足我们的要求? 如果允许1000升呢? 但是如果不考虑所有物理约束, 我们是否能够证明说: 飞机和拖拉机的运输能力是完全一致的, 因为它们都能从北京开到上海. <br />
<br />
&nbsp;&nbsp;&nbsp; 我的观点是结构问题是独立存在的,它具有自身的价值, 研究它也需要建立特定的价值观. 一个结构可以体现为语言上的某种语法特征, 也可以通过框架等实现, 或者表现为某种设计模式,某种编程技巧. 我们在思考结构问题的时候并不是从特定语言的机制出发的, 当语言不直接支持的时候我们可以发展特定的实现技术支持它. 在未来的日子里某个结构可能被证明具有普适的价值,它会被吸收到某个通用语言中成为所有程序的支撑结构, 但是更多的结构永远都不会进入通用语言, 而是居留在某个特定的领域. 通用语言的发展并不是完全基于抽象的数学分析而进行的, 它可以从更加丰富的物理世界中吸取营养. 当一种结构进入通用语言的时候, 它所带来的绝对不只是一组数量关系,而是同时带来一系列经过实践检验的物理诠释. <br />
<br />
&nbsp;&nbsp;&nbsp; 我所谓的领域并不是指业务领域, 而是结构领域, 一个可以定义特定结构的物理场景. 一个特定的结构仍然可以支撑着任意多的具体应用. 例如CRUD操作可以作为数据管理模型. BizFlow作为界面和单实体的交互模型.<br />
<br />
&nbsp;&nbsp;&nbsp; 函数式语言为我们提供了一种具体的技术工具, 但是在现实的开发中, 为了有效的处理结构问题, 显然我们需要多种视角的组合, 而不是把所有可想见的图景都纯化为函数. 我们对世界的体验是多样化的. 这就是我所谓"世界比函数的集合要复杂"的含义. <br />
<img src ="http://www.blogjava.net/canonical/aggbug/166375.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/canonical/" target="_blank">canonical</a> 2007-12-09 00:16 <a href="http://www.blogjava.net/canonical/archive/2007/12/09/166375.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对语言与结构的说明</title><link>http://www.blogjava.net/canonical/archive/2007/12/08/166187.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Fri, 07 Dec 2007 18:51:00 GMT</pubDate><guid>http://www.blogjava.net/canonical/archive/2007/12/08/166187.html</guid><wfw:comment>http://www.blogjava.net/canonical/comments/166187.html</wfw:comment><comments>http://www.blogjava.net/canonical/archive/2007/12/08/166187.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.blogjava.net/canonical/comments/commentRss/166187.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/canonical/services/trackbacks/166187.html</trackback:ping><description><![CDATA[&nbsp;&nbsp; 每当我在文字中对函数式语言有些不敬之意时,便好像动了某些人的奶酪,以至我的言辞总在被曲解后遭到排斥。我想这就是因为视角差异过大所造成的. 但是谦虚谨慎是传统的美德, 不能容纳他人的观点只会妨碍自己在某些方向的探索。<br />
&nbsp;&nbsp; 首先请不要轻易怀疑我的知识水平。当然如果总无法聚集起足够的注意力来理解别人话语中的细节，我也无话可说。<br />
&nbsp;&nbsp; 容纳他人的观点就意味着不要总在自己的话语体系中试图找到反例. 一个人总是受限于他的知识范围，因此他也经常在自己的知识范围内篡改曲解别人的意见。我从未说过 "一个具体的问题是现有的通用语言无法描述的". 我说的是"现实开发中所需要处理的结构问题并不是在语言层面得到充分<strong>解决</strong>的", "<strong>现在</strong>的通用语言也是无法<strong>有效</strong>承载Domain Specific Structure的". 请注意我对定语和动词的选择。其实我已经举了大量的例子来进行说明，但可能因为大多数人不是物理背景,对相关的内容不熟悉，所以直接无视了。这也很对，符合物理学的精神。<br />
<br />
&nbsp;&nbsp; 可能大多数人都知道函数式语言和命令式语言都是和图灵机等价的，因此它具有某种终极能力，怀疑它无异于怀疑我们世界存在的基础。但是请注意，这种等价性是数学性的。它潜在的要求是无限的能量和时间消耗。如果在限定的物理约束下，我们会发现我们的选择范围会大大缩小。所以我说"函数式语言和命令式语言的计算能力相同，但是在具体的情形下它们的描述能力是不同的". 比如说我现在有无穷多种方式从北京跑到上海，但是如果限定只允许用1升汽油，那么我们的选择就近乎于0。飞机和汽车的运输能力是相同的吗。物理学的一个基本精神在于一种物理性的约束是始终存在的。而事实上，我们在实际工作中也总是在各种有限的物理条件下工作。<br />
<br />
&nbsp;&nbsp; 也许有些人认为这种区分是无关紧要的，我们只关心某种终极的东西。但是物理学中有着太多的例证，说明在有限约束下，整个系统呈现出完全不同的性质。在通信领域我们都知道Shannon定理，它的物理诠释是在有噪声的信道上可以<strong>有效</strong>的进行<strong>准确</strong>的信息传递。但是这一诠释只能在有限的数学精度（远大于我们实际需求的精度）上成立, 在绝对准确的数学意义上，这是不可能的事情。<br />
<br />
&nbsp;&nbsp; 你觉得现在的通用语言做起领域相关的东西来很方便吗，这就是我所谓无法有效承载的含义。在这里我也没有否认"未来的牛语言可以轻松搞定目前难题"的可能性。<br />
<br />
&nbsp;&nbsp; 因为所有的软件设计最终都要落实到某种代码实现上，所以怎么会有什么神秘的软件结构是现有的语言无法描述的呢。但是ErLang中那种高并发，支持错误恢复的程序结构是在其他语言中能够轻松实现的吗。很多人不是在潜意识中认为ErLang的成功是函数式语言排他性的成功吗，不是认为命令式语言无论如何实现不了ErLang的程序结构的吗。很显然，在命令式语言中是无法直接实现ErLang中的程序结构的，否则它就变成了函数式语言，但是所有发生在ErLang世界中的事实都一样可以发生在命令式语言的世界中。ErLang语言的编译器可以是使用命令式语言实现的，在终极的意义上，语言之间能有什么区别呢？<br />
<br />
&nbsp;&nbsp; 我说"实际上现在的通用语言也是无法有效承载Domain Specific Structure的", 这还有另一层含义。通用语言设计总是要考虑到内置结构的某种通用性，设计时能够凭依的信息较少，因此不可能直接制造某种复杂的领域相关的结构。而目前已知的通用语言中提供的结构抽象的手段也不够强大（实际上我认为任何语言都不会强大到内置所有结构，也无法提供所有的结构抽象手段）， 相当于是把领域结构问题推给程序员解决。这就如同C语言把内存管理推给程序员解决一样。现在ruby比较流行不就是因为它能够动态处理很多结构问题吗，但是它现在所作的一切就是足够的了吗。难道二十年之后再来看这个语言，不能够发现它存在着巨大的改进空间吗。我们目前在Witrix中通过tpl模板语言，bizflow extends等机制，结合整体框架设计实现了一些与ruby不同的结构构造方法。这些手段都极大的增强了我们面对领域问题时的信心，也确保了我们的领域知识是技术层面上可积累的。但是即使这样，我对程序发展的现状就是满意的吗？难道不存在更加丰富的结构知识等待我们去发现吗？一般人总是习惯接受已经存在的现实，在有限的职业生涯中把它们当作不变的真理，却没有耐心的去思考如何去改变。<br />
<br />
&nbsp; 我认为很多结构问题不是需要在语言层面得到解决的，而是应该在独立的结构层（平台，框架）进行解决。这意味着没有必要在语言层面直接内置某种特定的结构，内置某种特定的结构抽象手段。这基本类似于说不要把集合论扩大到包含所有的数学关系，请在别的学科分支中进行研究。需要注意的是，我所谓的领域知识不是特定的业务知识，而是从业务知识中可以分析得到的某种更加通用的普适的结构知识，甚至是可以使用数学进行精确描述的。<br />
<br />
&nbsp; 现代软件发展的时间还很短，与数学和物理学这样深刻的学科相比，它无疑是相对幼稚的，是待成长的，是更加的不完美的。在程序构建的基本问题上并没有抽象出什么可以实际操作的精确规律。这是所谓Pattern在软件业流行的部分原因：我们希望用这种半形式化的方式捕获某种思考的结果。但是软件真的除了基于抽象数学的全局的全称性的证明之外，不能够在局部进行某种更加复杂，更加严谨的分析吗。<br />
<br />
&nbsp;&nbsp; 我们说结构问题是独立的，这也意味着它和具体的实现语言具有某种意义上的分离性。通过一种语言书写的结构可以在另一种语言中得到表达。我们可以建立语言中立的技术结构。一种所谓的结构在概念上具有某种确定的形态，我们可以脱离具体的语言来理解它。例如我说"面向对象的继承关系从结构观点上看是两个一维集合之间的覆盖关系". 在java中我们可以直接使用语言提供的继承机制，而在C语言中我们就需要建立某种结构体，手动维持所有的指针关联。而在Witrix平台中，我们从继承的结构诠释出发，定义了更加复杂的extends算子，这就需要利用java语言编制特定的parser来实现了。但是显然，在思考的时候我们所有的思维指向是结构本身，而不是任何通用语言的语法。<br />
<br />
&nbsp;&nbsp; 在物理学中，通过摄动分析我们可以清楚地意识到：同样一个物理现象对应的数学模型可以是众多的，但是在特定的参数区我们会选择某种特定的数学表述，并确定其中的待定参数。<br />
<br />
&nbsp;&nbsp; delta函数是物理学家狄拉克引入的，在Schwatz引入分布概念建立广义函数论之前，物理学家们已经使用这一函数工作了很多年。后来Abraham Robinsen利用数理逻辑方法，建立了非标准分析，通过模型论的方法精确定义了无穷小的概念，从更加直接的角度论证了delta的合理性。但是在物理学家看来，这些数学又有什么区别呢？物理学只是按照物理的诠释进行工作，具体的数学只是它可选的工具而已。<br />
<br />
&nbsp;&nbsp; 物理的真理并不是蕴含在数学中的，它需要我们独立的探索，从与数学不同的观点进行思考，检验，最终我们才能做出真正的发现。广义相对论可以采用Riemman几何进行描述，但是它的物理诠释却是Einstein提出的. 没有人说Riemann或者Hilbert发现了广义相对论。另外一方面，因为Einstein的工作触发了对于微分几何的更加深入的研究，靠着物理直觉的导引，我们将这一数学分支推进到了难以想象的深度。"数学是无法涵盖物理学的". 这不是说最终物理学无法采用数学语言进行描述，而是说在这一发展过程中，所有思想的推动来源于物理学的经验，来源于我们在这个物质世界上所进行的反复验证。不是在一个封闭的小屋中，整天摆弄各种数学符号，我们就能够发明所有的物理公式所对应的数学。实际上，现在学术界普遍承认，没有物理学的推进，很多数学的进展是不可能发生的。<br />
<br />
&nbsp;&nbsp; 物理系每天都在演算着Feynman路径积分, 但是所有人都知道这是没有什么严格的数学依据的.目前并无法定义路径积分的收敛性,但是所有人对此避而不谈. 只要形式演算合法,物理预测符合实验, 合理性的证明只是数学家们的事情. 在量子场论中所采用的重整化(Renormalization)方法不过是回避无穷大问题的一种形式手段.我们仍然无法在数学层面对所有的演算都给予合理化解释. 在更多的物理分支中工作，你就会发现物理学家的胆子不是一般的大。也许在未来我们能够发现这些物理过程背后数学机制的精确定义, 但也许最终我们也无法找到合适的定义方式. 但这对物理学家来说, 并不是很大的打击.因为指引我们的是物理直觉，是独立于数学的物质世界的意象。<br />
<br />
&nbsp;&nbsp; 我所想讨论的不是某种终极意义上的可能性，不是绝对概念之间的冲突，而是在物理现实的约束下，我们如何才能有效工作的问题。我已经反复表述了自己的观点: "<strong>结构是可抽象的，是具有独立意义的。这就是Witrix所提出的面向结构的设计视角。不是强调对象的所谓业务含义，不是强调某种通用语言（例如ruby）的灵活的语法结构。在这之间存在着厚重的具有物理意义的可以进行结构分析的技术层</strong>". 也许有人觉得我说的这是废话, 但是当系统化的执行一种思想的时候,就会揭示出未预料到的可能性. 整个Witrix平台简单的说起来就是"<strong>面向结构的级列分析</strong>", 但是如何找到合适的技术形式来体现这一思想,却绝对不是一件平凡的事情. "在Witrix中我们实现的代码重用程度和程序整体结构控制能力是超越了目前所有已知的公开技术的。这不是什么哲学，而是我们在残酷的商业竞争中得以生存的资本".<a href="http://canonical.javaeye.com/blog/126467 ">http://canonical.javaeye.com/blog/126467 </a><br />
<br />
&nbsp;&nbsp; 在我看来，计算机领域充斥着纯数学的深沉遐想和从工程实践而来的轻佻常识，还没有注意到物理学所能带来的不同的同样深刻的视角。我常说，好好学习物理是必要的，因为这个世界远比你想象的要复杂的多。<br />
<br />
<br />
<img src ="http://www.blogjava.net/canonical/aggbug/166187.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/canonical/" target="_blank">canonical</a> 2007-12-08 02:51 <a href="http://www.blogjava.net/canonical/archive/2007/12/08/166187.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于函数式语言的一些说明</title><link>http://www.blogjava.net/canonical/archive/2007/12/06/165900.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Thu, 06 Dec 2007 14:12:00 GMT</pubDate><guid>http://www.blogjava.net/canonical/archive/2007/12/06/165900.html</guid><wfw:comment>http://www.blogjava.net/canonical/comments/165900.html</wfw:comment><comments>http://www.blogjava.net/canonical/archive/2007/12/06/165900.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/canonical/comments/commentRss/165900.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/canonical/services/trackbacks/165900.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 我的观点并不是什么具体的程序结构问题不能用函数式语言处理.我所要表述的是这和函数式语言中能否加入结构解决任意复杂问题无关。为什么所有的问题不能在集合论中解决，为什么要有独立的数学学科。物理学所有的定律都使用数学表述，是否意味着物理学的真理蕴含在数学之中。<br />
&nbsp;&nbsp;&nbsp; 我说<strong>实</strong><strong>际上现在的通用语言也是无法有效承载Domain Specific Structure的</strong><em><strong>。</strong></em>其实与以下说法是类似的<br />
<strong>数学是无法涵盖物理学的，现在的已知的数学工具是无法有效承载尚未得到充分探索的领域的物理的</strong><br />
&nbsp;&nbsp;&nbsp; 我说<strong>我所关心的不是语言层面的问题</strong><em><strong>。</strong></em>这类似于说<strong>不要把所有物理问题都推到数学层面去解决</strong>。<br />
&nbsp;&nbsp;&nbsp; 我们应该研究独立的结构，应该建立单独的价值观和方法论。不要谈及一个技术进展的时候就说某某语言好，不是一说到DSL的优点就要去抱ruby的大腿。此外，我的观点也不是去做业务分析，不是去如何更好的实现业务到基础技术结构的映射。<br />
&nbsp;&nbsp;&nbsp;
<strong>不是强调对象的所谓业务含义，不是强调某种通用语言（例如ruby）的灵活的语法结构。在这之间存在着厚重的具有物理意义的可以进行结构分析的技术层。</strong><br />
&nbsp;&nbsp;&nbsp;
我想说这个结构层面现在并未得到充分的关注，我们对于结构的问题并不是非常清楚，对程序结构的稳定性更是少有经验。我们在Witrix中做了大量的工作，试图做到如下的图景：<br />
&nbsp;&nbsp;
<strong>永远只写代码片断，而所有的代码片断组合在一起又构成一个可理解的整体</strong><br />
&nbsp;&nbsp;
<strong>对背景不是分解让其成为可见的部分，而是采用追加的，增删的方法对背景结构进行修正，则我们有可能在没有完整背景知识的情况下，独立的理解局部变化的结构。即背景是透明的，知识成为局部的。</strong><br />
<a href="http://canonical.javaeye.com/blog/126467">http://canonical.javaeye.com/blog/126467</a><br />
&nbsp;&nbsp;&nbsp;
在Witrix中我们实现的代码重用程度和程序整体结构控制能力是超越了目前所有已知的公开技术的。这不是什么哲学，而是我们在残酷的商业竞争中得以生存的资本。<br />
<br />
号外：<br />
&nbsp; 不要把具体的技术和一种技术思想混为一谈。一种实现总是包容了太多的思想。思想错了，实现对了。实现死了，思想活着。<br />
<img src ="http://www.blogjava.net/canonical/aggbug/165900.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/canonical/" target="_blank">canonical</a> 2007-12-06 22:12 <a href="http://www.blogjava.net/canonical/archive/2007/12/06/165900.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于函数式语言的只言片语</title><link>http://www.blogjava.net/canonical/archive/2007/12/05/165664.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Wed, 05 Dec 2007 14:09:00 GMT</pubDate><guid>http://www.blogjava.net/canonical/archive/2007/12/05/165664.html</guid><wfw:comment>http://www.blogjava.net/canonical/comments/165664.html</wfw:comment><comments>http://www.blogjava.net/canonical/archive/2007/12/05/165664.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.blogjava.net/canonical/comments/commentRss/165664.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/canonical/services/trackbacks/165664.html</trackback:ping><description><![CDATA[1. 函数式语言可以合理的看作是泛函分析思想的一种体现，从历史发展的时间上看大概也是具有这种可能性的。在Backus的论文中对函数式语言的一种乐观的情绪甚至扩大到functional algebra can be used to tranform programs and to solve equations whose "unknowns" are programms in much the same way one transform equations in high school algebra。这种信心只能来源于泛函分析和方程论，来自于数学分析学的发展。将函数的函数作为分析对象就构成泛函分析。泛函分析的最核心的思想当然不等价于它所研究的那些无穷维空间，不等价于种种正交基的构造。它的思想核心在于函数的函数具有独立的分析价值，具有脱离数量空间的具体的结构。这也是函数式语言试图推销的一种理念。<br />
<br />
<br />
2. 最近这些年来一种称为"范畴"(Category)的东西在计算机理论研究中频频出现。范畴论是从同调代数发展而来的一种较新的代数语言，但它显然也不是可以解决任何问题的灵丹妙药。多一种表达方式当然在某种程度上可以增进我们的理解。但是范畴本身只是研究一种基础结构，它本身并没有承载所有的物理事实，基于它不可能对所有的规律一网打尽。不是明白了范畴，就懂了程序。范畴论是一种基础性的语言，有些人致力于基于范畴论来构建数学的其他分支，取代集合论的地位。将计算的本质重新归结于范畴论是无意义的，它不过是对事实的另一种陈述方式。说&#8220;函数式语言是基于范畴&#8221;是无意义的，因为这和说&#8220;所有现代数学都基于集合论&#8221;一样。无法发现新的相互作用关系，所有的概念都只是同义反复。不是一拿起数学，就找到了组织。<br />
<br />
3. 我对函数式语言并没有什么反对意见。它是非常重要也非常优美的一种技术思想。但是现在一些函数式语言的狂热支持者似乎对函数世界充满了乌托邦式的幻想，一种大一统的世界观让人迷醉，但是它却解决不了现实的问题。所以我说无法认同函数式编程的世界观。作为一种具体的技术工具，问题不在于函数式语言是否体现了计算的本质，而在于它是否向我们提供了称手的兵器。现在我要计算两个小球相互碰撞的问题，我可以操起广义相对论，量子力学啥的开始大干一场，也可以用个牛顿力学小试牛刀，甚至可以只用反射关系摆个等式。但是在绝大多数情况下我们都会说这里面的物理是弹性反射而不是相对论。在理论分析中我们经常使用平面波假设，但只要实际关心的对象不在波包的边缘，没有人会认为平面波不是真实的物理机制。理论物理不是理想物理。在具体的参数设定下，我们只会使用特定的物理学。<br />
&nbsp;&nbsp; 对世界的认识并不是非此即彼的。并不是说函数式语言好它就永远都好，要把所有对立面都灭掉。也不是说函数式不好，命令式就必然的好，就必然的能够解决问题。函数式语言的世界观过分单纯而排他，这是我反对的，我同样无法认同面向对象的本体论论调。就像CISC和RISC架构之争一样，最终我们在现实的物理约束下，运行的最好的芯片是两者思想的结合。这是我们面对物理世界的基本态度。<br />
&nbsp;&nbsp; <br />
4. 函数式语言中时间是个有趣的概念。命令式语言中因为赋值语句的存在，使得我们可以观测到状态的变化，因此必然要定义时间。而函数式语言是无状态的，可以是无时间概念（对Lazy Caculation的依赖是否体现了深层次上对时间概念的需求？）。有些人认为函数可以看作是相空间中的迁移函数，是与相对论协调的，因而反映了时间的本质等等。相对论主要是解决了物理规律的协变性的问题，在此过程中它使人们认识到了时空之间奇异的对称性。但是广义相对论的表述中时间也是可逆的。真正定义了时间之箭的是热力学第二定律。根据Landauer's principle: 擦除(erase)1比特信息，耗散到环境中的能量至少是k*T*ln2, 或者说熵增至少是k*ln2. 这意味着只要我们对眼前的黑板不停的写了擦，擦了写，就必然无法回到过去。物理世界是复杂的。<br />
<br />
5. 如果将状态看作是可以附着在某个对象上的标记，显然状态的存在性便于我们识认概念的唯一性。对象还是那个对象，只是状态标记发生了变化。而如果系统中没有状态，则必然产生了一个新的概念。这在很多情况下是不必要的负担。状态的存在使得系统在局部结构上允许出现非常复杂的变化，函数式编程的拥趸们对此多有诟病。但是从另一个方面上说，状态使得我们可以基于局部信息处理很多问题而不需要把它扩大化为一个全局匹配问题。<br />
<br />
6. 函数构成函数似乎是很完备统一的世界。 但是在物理世界中发生的一切却复杂的多。虽然世界可以还原为原子，但是原子构成分子，分子构成宏观物质时，系统的基本性状发生了本质性的变化，并不再是统一的形式。每一个层面上都会产生独立的结构规律。<br />
<br />
7. 函数式语言和命令式语言的计算能力相同（可以相差一个任意长度的多项式时间），但是在具体的情形下它们的描述能力是不同的。我所关心的不是语言层面的问题，因为语言本身的能力并不足以解决现实开发中的所有问题。即现实开发中所需要处理的结构问题并不是在语言层面得到充分解决的，这是我们需要做工作的地方。<br />
&nbsp;&nbsp; 关于现实中的结构问题，我无意去定义什么万能的描述能力。你可以用微分几何，积分几何，广义变分等等手段去证明圆盘是某种意义下的周长最短的东西，但是这一切对你发明轮子并无本质上的助益。不过可以说说现实中的结构。这里不是要证明某种语言中无法描述这些结构，而是说结构是客观存在的，它并不是要在基础语言层面得到充分解决的。实际上现在的通用语言也是无法有效承载Domain Specific Structure的。<br />
A. ErLang大概是目前世界上应用最为深入的函数式语言了。它确实发挥了函数式语言无显式状态变量的优势。但是它对程序构建本质上的帮助更多的来源于无共享的超轻量级进程模型，相当于定制了一般操作系统所提供的基本服务。微软的一个实验性操作系统项目Singularity, 其中也定义了只通过消息传递发生数据关联的超轻量级进程模型，它使用C#的一个扩展语言，额外增加的功能是消息管道上定义的规格状态机，对消息交互的时空模式进行额外的规约。这里对我们真正有价值的是隔离的单元结构。<br />
B. AOP是程序结构空间中的定位和组装技术。在Witrix中我们规范化了切点处的状态空间，并对AOP进行了偏置处理.这种结构调整大大提高了AOP的可用性，使得它成为Witrix中的核心技术手段之一。<br />
C. 面向对象的继承关系从结构观点上看是两个一维集合之间的覆盖关系。在Witrix中扩展了extends所对应的结构操作，创造了新的结构融合手段。<br />
<img src ="http://www.blogjava.net/canonical/aggbug/165664.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/canonical/" target="_blank">canonical</a> 2007-12-05 22:09 <a href="http://www.blogjava.net/canonical/archive/2007/12/05/165664.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于[面向集合的框架设计]的一些说明</title><link>http://www.blogjava.net/canonical/archive/2007/12/03/165039.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Mon, 03 Dec 2007 15:54:00 GMT</pubDate><guid>http://www.blogjava.net/canonical/archive/2007/12/03/165039.html</guid><wfw:comment>http://www.blogjava.net/canonical/comments/165039.html</wfw:comment><comments>http://www.blogjava.net/canonical/archive/2007/12/03/165039.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/canonical/comments/commentRss/165039.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/canonical/services/trackbacks/165039.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 我习惯于概念层的推演，而且所阐述的东西多数是我们创造过程中的副产品，与业内常见的观念实际上是有着很大差异的。有些人感觉我的文章读不明白是因为没有采用类似的视角，或者还没有独立思考过很多问题。如果只是从业内已经熟知的概念出发试图理解我所写的内容，显然是不可能的事情。所以我常说know something already known. <br />
<br />
如果在编制一个新的应用，存在大量代码可能是<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">myFunc(){<br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;each&nbsp;x&nbsp;in&nbsp;set<br />
&nbsp;&nbsp;&nbsp;&nbsp;doSomethingValuable(x);<br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;packedResult;<br />
}<br />
<br />
myOtherFunc(packedResult){<br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;each&nbsp;y&nbsp;in&nbsp;pakedResult<br />
&nbsp;&nbsp;&nbsp;&nbsp;doSomethingOther(y)<br />
}</span></div>
<br />
其实我们真正关心的是循环内部的某个过程，但是我们经常可以观察到它们被某些通用的或者特定的循环（集合遍历）操作所包围着。Witrix的设计方式是强调业务关注点，而把所有的汇总操作尽量抽象完成。比如现在界面上显示一些字段。从抽象的操作上说<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;each&nbsp;field&nbsp;in&nbsp;dsMeta.viewableFields<br />
&nbsp;&nbsp;&nbsp;&nbsp;show&nbsp;field.viewer</span></div>
<br />
这一过程在平台代码中实现，它是一个通用的集合操作过程。不同的具体应用只是关心具体字段的展现形式，虽然我们必然需要字段集合，但是它不是我们注意力的重心。<br />
&nbsp; 如果考虑到字段在界面上展示有一个布局问题，我们所要修改的是集合内部的结构方式：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;&nbsp;某种结构循环方式（dsMeta.字段组成的布局集合）<br />
&nbsp;&nbsp;&nbsp;&nbsp;show&nbsp;field.viewer</span></div>
<br />
抽离出集合，实际上是在最大限度上分离结构问题和内容问题。&nbsp;&nbsp;&nbsp; &nbsp;<br />
&nbsp;&nbsp; 结构是可抽象的，是具有独立意义的。这就是Witrix所提出的面向结构的设计视角。不是强调对象的所谓业务含义，不是强调某种通用语言（例如ruby）的灵活的语法结构。在这之间存在着厚重的具有物理意义的可以进行结构分析的技术层。<a href="http://canonical.javaeye.com/blog/60758 ">http://canonical.javaeye.com/blog/60758&nbsp;</a> <a href="http://canonical.javaeye.com/blog/126467">http://canonical.javaeye.com/blog/126467</a><br />
<br />
<img src ="http://www.blogjava.net/canonical/aggbug/165039.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/canonical/" target="_blank">canonical</a> 2007-12-03 23:54 <a href="http://www.blogjava.net/canonical/archive/2007/12/03/165039.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从指针到引用</title><link>http://www.blogjava.net/canonical/archive/2007/12/02/164717.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Sun, 02 Dec 2007 14:14:00 GMT</pubDate><guid>http://www.blogjava.net/canonical/archive/2007/12/02/164717.html</guid><wfw:comment>http://www.blogjava.net/canonical/comments/164717.html</wfw:comment><comments>http://www.blogjava.net/canonical/archive/2007/12/02/164717.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/canonical/comments/commentRss/164717.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/canonical/services/trackbacks/164717.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 地址(Address)是现代计算机体系架构中的核心概念，它在程序设计语言上的体现就是C语言中的指针(Pointer)。在C语言中，所有的高级技巧都和指针这个概念相关。指针只是一个存放了一个地址的变量，但是C语言中提供了一个方便的间接访问方式，p-&gt;x, 它使得拥有指针在概念上就等价于拥有了指针所指的全部内容。在这种诱导下，我们渐渐模糊了地址和地址所存储的内容之间的区别。这也是指针的指针这样的概念总是让初学者迷惑不解的重要原因。<br />
&nbsp;&nbsp;&nbsp; 指针是对地址的符号化。它所带来的第一大好处是使得我们摆脱了对绝对地址空间的依赖。如同Newton第一定律所阐述的：物理规律与所发生的惯性坐标系无关。同样，数字空间中发生的的事件与所处的绝对地址也是无关的。在符号化的方向上更进一步，如果我们专注于指针的关联语义，而放弃指针的指针这样的混杂概念，就会得到具有独立价值的引用(Reference)概念.<br />
&nbsp;&nbsp;&nbsp; 从表面上看起来，数字空间只是一个无限延展的一维地址空间，每一地址处只能存放一个有限大小的离散数值，似乎它的几何学是贫瘠的。但是因为在软件设计中，一般是不考虑寻址时间的。这意味着在拥有指针的情况下，我们可以&#8220;立刻&#8221;访问到数字空间的任意遥远的地方。这种超时空的信息传递过程使得我们可以利用&#8220;引用&#8221;概念轻松的构建一个多维的表示空间。在面向对象的技术背景下，x.y.z这样的形式表示暗示着x,y,z是同时存在的。当z发生变化的时候，通过y.z和x.y的信息传导，x对象本身也发生了某种变化。<br />
&nbsp;&nbsp;&nbsp; 随着web技术的流行，独立的状态/地址空间的存在性逐渐成为系统不可回避的假设, "同时性"的物理约束越来越难以维持. 相对论规定了物理现象的定域性, 在数字空间我们一直忽视了它.但有趣的是, 网络上的传输时延却迫使我们重新发现了"引用"形式下必然存在着的物理过程. 引用本身只是标记了某种信息关联, 并不一定意味着同时性约束. 并发编程领域的所谓的Future对象是对传统引用概念的一种有趣扩展.<br />
&nbsp;&nbsp; result = obj.callMethod(args) ==&gt;&nbsp; future = obj.callMethod(args)<br />
future对象可以被自由传递, 只有当实际访问到它的属性的时候, 才会触发时序约束.&nbsp; <br />
<img src ="http://www.blogjava.net/canonical/aggbug/164717.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/canonical/" target="_blank">canonical</a> 2007-12-02 22:14 <a href="http://www.blogjava.net/canonical/archive/2007/12/02/164717.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>面向集合的框架设计</title><link>http://www.blogjava.net/canonical/archive/2007/11/25/163048.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Sun, 25 Nov 2007 15:37:00 GMT</pubDate><guid>http://www.blogjava.net/canonical/archive/2007/11/25/163048.html</guid><wfw:comment>http://www.blogjava.net/canonical/comments/163048.html</wfw:comment><comments>http://www.blogjava.net/canonical/archive/2007/11/25/163048.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/canonical/comments/commentRss/163048.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/canonical/services/trackbacks/163048.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;
判断和循环是程序中最基本的语句结构。而在vonNeumann体系架构下，循环是对集合进行操作所需的基本步骤。一个有趣的事实是，函数式语言所宣称的
生产力的来源很大程度上在于集合操作的便捷性。在数学中我们通过张量分析，泛函分析等可以清楚地意识到集合之间的相互作用是可抽象的，是可以独立理解的，
即我们可以在不涉及具体基元结构的层面上独立的定义并执行集合运算。如何将这种概念独立性在框架层面展开是一个非常深刻的命题。<br />
&nbsp;&nbsp;&nbsp; 在基元结构上应用基础操作p(d)这一微观场景一般情况下是容易理解并实现的, 但通常程序中所定义的大量边界是基于集合变量的,
因此很多代码都是封包和解包操作, 在层层嵌套的循环结构深处我们才能发现真正具有业务价值的基元结构.
将集合操作提升到系统层，减少或简化在应用层需要显式编制的循环结构是框架设计层面需要考虑的问题. <br />
&nbsp;&nbsp;&nbsp; 一个最基本的方法是尽量定义通用的同构操作, 避免构造中间集合. 例如前后台之间通过json等通用协议交换复杂结构的对象,
避免定义特殊的中间处理过程. 一个与之相配合的重要技术手段是通过类查询语句(描述方式)直接构造特定的集合.
例如prototype.js中提供的$$('div
div.myclass').each(op)这样的处理方式显然要比在循环过程中基于特定条件过滤要方便的多.
而在AOP操作中切点的集合定义方式也是其提供的核心价值之一. 与集合操作相适应的一种代码风格是流式设计(stream),
这正是jQuery试图鼓吹的主要价值(虽然我个人认为它有些走极端). 流式设计的核心结构实际上是 x += dx,
它不需要集合是一次性构造的, 便于支持一种逐步部分修正的概念模型. <br />
&nbsp;&nbsp;&nbsp; 为了支持集合的隐式构造, 我们需要以通用的方式定义元素到集合的组装规则.
在Witrix平台的前台js框架中我们定义了由独立的html组件到复合查询条件的拼接规则,
定义了由每个html组件的数据校验函数到整个form的数据校验函数之间的组装规则,
定义了由单个html组件提交参数到整个form提交参数之间的组装规则. 在Witrix平台的标准界面上,
框架本身的编制基于js.query.buildCondition(frmQuery),
js.validate.validateForm(frmUpdate), ajax.addForm(frmUpdate)等少量集合操作进行,
在不同的应用场景下, 我们只需要关心每一个字段如何显示, 提交哪些属性, 而由系统负责将它们自动组装并在后台进行分派. 面向不同的应用,
框架代码不需要做出任何修改, 确保了系统结构的可重用性. <br />
&nbsp;&nbsp; Witrix平台的后台处理模型中定义了实体化过程, DaoWebAction基于CRUD等原子操作定义了批量提交,
数据导入导出等复合的甚至是嵌套的集合操作. 在不同的应用中, 我们通过修改bizflow文件中&lt;action
id="ViewDetail-default"&gt;, &lt;action
id="Update-default"&gt;等针对单实体的业务规则即可适应不同的业务场景, 而不需要为特定的应用重复编制集合处理过程. <br />
&nbsp;&nbsp;&nbsp; 面向集合+通用组装规则是Witrix平台设计中采用的基本设计手法之一,
它使得我们在一般应用中只需要考虑单实体,单字段等基元结构上发生的特定业务, 大大简化了系统构造过程.
但是也需要认识到从个体到集合的扩张(p(d) -&gt; P(D) )是非平凡的, 集合比个体的简单加和要更多,
为此架构中需要保留对集合边界的识别能力, 例如需要允许在数据导入完成之后执行特定的业务规则而不是仅仅针对每一数据行执行业务规则.
<img src ="http://www.blogjava.net/canonical/aggbug/163048.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/canonical/" target="_blank">canonical</a> 2007-11-25 23:37 <a href="http://www.blogjava.net/canonical/archive/2007/11/25/163048.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Witrix架构分析</title><link>http://www.blogjava.net/canonical/archive/2007/09/23/147641.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Sun, 23 Sep 2007 15:53:00 GMT</pubDate><guid>http://www.blogjava.net/canonical/archive/2007/09/23/147641.html</guid><wfw:comment>http://www.blogjava.net/canonical/comments/147641.html</wfw:comment><comments>http://www.blogjava.net/canonical/archive/2007/09/23/147641.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/canonical/comments/commentRss/147641.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/canonical/services/trackbacks/147641.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Witrix开发平台基于级列设计理论发展了一系列新的设计思想和软件分解机制。并提出了一种新的Web体系架构。<a href="http://canonical.javaeye.com/blog/33824" _fcksavedurl="http://canonical.javaeye.com/blog/33824">http://canonical.javaeye.com/blog/33824</a><br />
&nbsp; <img src="http://www.blogjava.net/images/blogjava_net/canonical/witrix.gif" _fcksavedurl="http://www.blogjava.net/images/blogjava_net/canonical/witrix.gif" alt="" height="735" width="753" /><br />
<br />
Witrix架构呈"可"字形态，其中定义了三条主要的分界线:<br />
1. 浏览器和服务器之间通过语义结构明晰的URL形成两分结构。<a href="http://canonical.javaeye.com/blog/99122" _fcksavedurl="http://canonical.javaeye.com/blog/99122">http://canonical.javaeye.com/blog/99122</a><br />
2. 系统前台至后台存在一条预制的非侵入的信道. 它维持了一种无害的可扩展结构.
具体的说,系统从前台js到后台处理,对于所有$为前缀的参数是自动传递的,没有识别出的层将自动把这些参数传递下去.系统通过这一信道实现退化过程。在
我以前的文章中曾经指出过， 每一种可退化形式都对应存在一种非侵入性的可扩展设计。<a href="http://canonical.blogdriver.com/canonical/993807.html" _fcksavedurl="http://canonical.blogdriver.com/canonical/993807.html">http://canonical.blogdriver.com/canonical/993807.html</a><br />
3. Witrix内置了对于CRUD模型的支持， 而BizFlow通过类似AOP的方法对CRUD模型进行了扩展。这使得Witrix的模型驱动部分并不是仅仅针对单表或者单实体的维护, 而是可以实现特定的业务逻辑和CRUD逻辑的混杂. <br />
<br />
&nbsp;&nbsp;&nbsp; 这三条分界线分别规范了基础状态空间，对已有知识的重用以及面向未来的可扩展性。在这种大的宏观结构下，Witrix应用了如下技术手段:<br />
1. 对象化。Witrix中的Jsplet框架以对象的名义提供了对后台的状态和行为空间进行分解的基础手段。 <a href="http://canonical.javaeye.com/blog/33873" _fcksavedurl="http://canonical.javaeye.com/blog/33873">http://canonical.javaeye.com/blog/33873</a>。Witrix
依托于Jsplet对象实现相关性的局域化, 而不需要像一般面向action的框架那样直接访问http session这一全局状态空间.
前台发送的objectName参数同时在系统的不同层面标定了WebAction响应函数, Biz配置, DataSourceMeta元数据,
Hibernate实体等一系列相关概念, 使得它们构成一个统一的整体. <br />
2.
标准化。与REST架构风格类似，DaoWebAction规范化了后台响应事件。DaoWebAction上支持的标准事件有Query,
ViewDetail,Add, Update, Remove等,
它们构成一个完整的CRUD模型。与REST不同的是，DaoWebAction提供了一个空的响应事件BizAction。它相当于是CRUD模型中的
零元操作。在BizFlow模型下，它将被扩展为一个操作子空间，从而实现对于CRUD模型的超越。而在REST模型下所有的扩展操作必须依附于一个已经
具有固定语义的Method上，例如POST. <a href="http://canonical.javaeye.com/blog/99122" _fcksavedurl="http://canonical.javaeye.com/blog/99122">http://canonical.javaeye.com/blog/99122</a><br />
3. 实体化。在Witrix中充分发掘了ORM技术的能力, 使得单一业务对象上可以聚集到某一范围内的所有相关结构信息.
<a href="http://canonical.javaeye.com/blog/111500">http://canonical.javaeye.com/blog/111500</a>.
同时在DaoWebAction中通过EntityFilter机制实现了单实体化过程. 这意味着前台应用可以一次性提交多个批量操作,
后台框架负责把它们分解为针对单个实体的一次确定性操作, 在后台实现时只需要考虑单实体的情况即可.
一个简单的例子是前台提交objectEvent=Remove&amp;id=1&amp;id=2&amp;id=3 ,
WebAction层会为每一个id对应的实体调用BizFlow中的Remove-default操作. 实体化是一个非常重要的过程,
它使我们关注的核心成为单实体, 正是因为明确了单实体作为基本的关注点, 我们才可以建立更加复杂的状态机机制, 驱动系统状态变化.<br />
4. 组件化. 前台的tpl模板和后台的WebAction共享一个thisObj指针, 结合自定义标签机制, 资源(js/css等)管理机制等构成可以重用的组件结构. <br />
5. 偏置的AOP. BizFlow通过一种类似于AOP的操作对DaoWebAction提供的CRUD模型进行扩展,
使得模型的能力得到本质性的扩张. 这种AOP操作与通常意义的AOP的区别在于: 缺省行为在默认情况下发生, 除非显式禁止. 通过这种方式,
反转了base和extension之间的主体地位. 此外BizFlow所提供的不仅仅是行为的扩展,它同时提供了对界面的描述.
在前台tpl页面中通过<ds:bizviewops>&lt;ds:BizViewOps/&gt;等无参数的标签调用来定义嵌入坐标. <a href="http://canonical.javaeye.com/blog/34941" _fcksavedurl="http://canonical.javaeye.com/blog/34941">http://canonical.javaeye.com/blog/34941</a><br />
<img src="http://www.blogjava.net/images/blogjava_net/canonical/jsplet-model.jpg" _fcksavedurl="http://www.blogjava.net/images/blogjava_net/canonical/jsplet-model.jpg" alt="" height="832" width="682" /><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp; 与传统的J2EE相比较, Witrix表现出很多变化:<br />
1. 不使用全局的session, 而是使用局域化的thisObj<br />
2. 不定义service层，其功能分解到BizFlow和Handler中，它们都不负责日常的DAO操作。独立的MDA部分负责所有的实体CRUD(Create Read Update Delete)操作。<br />
3. 不定义页面跳转规则，在前台使用拉模式直接表明跳转目标。结合前台stdPage对象在前台控制跳转目标。并可以在BizFlow中配置覆盖的规则，这样就可以针对不同的应用场景定义不同的跳转规则。<br />
4. 不是为每个模块, 每个应用场景编制一组新的页面,而是大多数模块共用少数几个标准页面.<br />
5. 不在与网络无关的service层上定义权限和事务管理。Witrix架构下通过URL明确区分了系统内部和外部,
前台访问后台时调用者的全部意图是以规范化的形式表达在url中的.
因此权限和事务管理作用在WebObject上在概念上也可以认为是约束直接作用在URL上, 这与REST风格是统一的.
当然我们也可以规范service方法的命名等, 但是显然要求一种随意性消失是有代价的,
在URL上我们已经付出了代价,为什么要在service上再付出一次. Witrix中Transaction和Auth的配置更加直观,
因为规范化了WebObject上的事件响应函数,一般我们也不需要进行特殊的配置.
Witrix这种设计更加适合于网络这一两分结构的，更加充分的利用这一架构边界所提供的隔离性. <br />
6. 不在页面中使用实体的字段名，而是大量通过元数据表达程序意图。<a href="http://canonical.javaeye.com/blog/114066" _fcksavedurl="http://canonical.javaeye.com/blog/114066">http://canonical.javaeye.com/blog/114066</a><br />
<br />
&nbsp;&nbsp;
一般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成为系统一种自动进行的背景操作时，我们不再需要
明确意识到它的存在。<br />
&nbsp;&nbsp;&nbsp; 我们需要认识到我们最终所需要的东西可能不是规整结构的, 它可能要求对于某个规整结构进行剪裁并增补附加元素.
但是这样的规整结构不应只存在于我们的想象之中，相应的剪裁过程应该是可以增量进行, 反复进行的. 在Witrix平台中， 基本的一种图景变化是:
Witrix中不再需要从头开始构造结构, 而只要指定当前业务和背景模型之间的差异部分.
在Witrix中所写的业务代码是对核心模型的扩展。这不仅仅是概念上的，而是实际体系架构上精确的体现。CRUD作为独立的模型吸收了系统中大量的变
化。整个模型内核是采用通用方式借助meta实现功能，并不涉及到特定于业务的类。对于那些我们已经掌握的知识,
Witrix提供了超越对象继承,AOP和组件重用的结构抽取手段, 使得知识可以稳步积累.<br />
&nbsp;&nbsp;&nbsp; &nbsp; 数学中存在两种基本的分解方式， 一种是加性分解 (a,b) + (c, d) =&gt; (a,b,c,d)， 另一种是乘性分解
(a,b) X (c, d) =&gt; (ac,bc,ad,bd)， 它也对应于张量(Tensor)运算. 在群论(Group
Theory)中，直积对于复杂性的化简至关重要，它的重要性要远在加和之上。实际上AOP操作类似于直积分解， 只是它的能力尚未得到充分的探索。
在Witrix中，biz的作用在感觉上很象是陪集(coset)运算：CURD *
biz。不同的biz作用到同样的CRUD模型上产生不同的操作集合，而所有biz组成的集合构成独立的整体。&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp; Witrix平台中作为内核的MDA部分首先是物理模型驱动, 而不是逻辑模型或者对象模型驱动.
我们通过在物理模型上标注的方法恢复部分对象模型的信息, 但是我们并不试图把整个软件建立为模型. 所建立的仅仅是整个程序模型的内核.
<a href="http://canonical.javaeye.com/blog/29412">http://canonical.javaeye.com/blog/29412</a> 一般业内鼓吹的所谓MDA成功的关键是要提高抽象层次。
但是陪集是更抽象吗。 正规子群更抽象吗。 它们只是系统的指标性表征，使对信息的distill, 是更容易理解的一个侧面而已,
抽象性并不是一个真正的目标。很多时候我们需要的是把系统降维到某个子空间中，形成一种可控性。 但是这个子空间并不一定是更抽象的。<br />
&nbsp;&nbsp;&nbsp; &nbsp; 群作为基本的代数系，一个本质特征是具有逆元。Witrix的MDA中明确定义了逆元结构，即界面上的元素 empty =
buttonA + (-buttonA)，这一分解公式应用到后台 OpA = Update * (-Update)&nbsp; *
OpA。假设我们已经建立了结构X, 现在需要建立一个与X略有不同的结构Y<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; X = a + b + c<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Y = a + d + c = (a + b + c) - b + d = X - b + d<br />
虽然Y的两种构造方式在数学上是等价的，
但在物理上并不等价。第一种方式对原有系统进行分解后再组装，而第二种方式没有打破原有的东西，不需要拆分。拆分总是可能存在问题的，正如你把所有电脑零
件拆装下来再装上很可能会发现多出几个零件。一般情况下第二种方式的构建成本要低. 特别是当一切都纠缠在一起的时候,
一种细粒度的逆元结构对于一种试图重用的结构是非常关键的.
可重用性的障碍不仅仅是来自于无法追加新的功能，很多时候也在于无法屏蔽原先已经提供的功能。目前所有的设计原则都未能适时识别出逆元的重要性。所有的设
计教条其实所指的方向都是加和, 如何分解出更小的组元, 如何把它们加和在一起, 如何从细部开始进行重新构建,
而不是说依赖于现有已经形成的宏观结构, 如何进行细粒度的调整. 所谓的AOP技术思考的关键点也在于如何给系统增加功能,
很少有人想到场景是为系统减少功能并把这种概念大规模正式应用的, 虽然说AOP已经在某种程度上具有了这种能力,
但是真正应用它仍然需要对AOP进行进一步的诠释. 当然，现在的软件业连基本结构的构造问题都没有完全搞清楚, 更别提所谓结构稳定性的问题了. <br />
&nbsp;&nbsp;&nbsp; &nbsp;从物理上说，Y = X - b +
d的分解方式具有特殊的意味。如果没有逆元，我们必然需要分解。但是如果发掘了背景这一概念，在逆元运算下，对背景不是分解让其成为可见的部分，而是采用
追加的，增删的方法对背景结构进行修正，则我们有可能在没有完整背景知识的情况下，独立的理解局部变化的结构。即背景是透明的，知识成为局部的。
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;
Witrix试图提供的一种图景是永远只写代码片断，而所有的代码片断组合在一起又构成一个可理解的整体。这个整体可以独立理解，不需要额外的结构元素。
Witrix架构所追求的是在不完全信息下建模，不进行整体建模。整体模型 + 不断变化的局部修正 构成
最终模型。平台技术的目标是让一切应该发生的自动发生，让一切不该发生的无法发生。这一模型的构建并不是trivial的，在概念和实现方面都要作出很多
的努力。<br />
&nbsp;&nbsp;&nbsp; &nbsp;<br />
题外：<br />
&nbsp;&nbsp;&nbsp; &nbsp;今天中午参加同学的婚礼, 席间和一个与同方有些渊源的同学谈到ezOne的现状, 大致的评语是: 垃圾, 自己人也不用. 听来也让人有些感叹. 中国原创的技术总是欺骗的代名词,&nbsp; 这一断言不应总是得到证实.</ds:bizviewops>
<img src ="http://www.blogjava.net/canonical/aggbug/147641.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/canonical/" target="_blank">canonical</a> 2007-09-23 23:53 <a href="http://www.blogjava.net/canonical/archive/2007/09/23/147641.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>软件与建筑</title><link>http://www.blogjava.net/canonical/archive/2007/09/09/143830.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Sun, 09 Sep 2007 12:00:00 GMT</pubDate><guid>http://www.blogjava.net/canonical/archive/2007/09/09/143830.html</guid><wfw:comment>http://www.blogjava.net/canonical/comments/143830.html</wfw:comment><comments>http://www.blogjava.net/canonical/archive/2007/09/09/143830.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/canonical/comments/commentRss/143830.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/canonical/services/trackbacks/143830.html</trackback:ping><description><![CDATA[&nbsp; 建筑学的隐喻在软件业中一直很流行。开发软件和建筑楼房从某种意义上说都是一种构造过程，而建筑学的成熟无疑让很多软件工程师非常羡慕。Design Pattern的始作俑者坦承受到建筑学著作的影响更是让一些人对建筑学的精深顶礼膜拜不已。不过，建筑决不只是表面上的形象/功能设计，也决不是民工就可以干的活计，在现代建筑设计背后是土木工程的蓬勃发展。正是框架结构的出现和材料工艺的进步才使得批量生产的大型现代建筑成为可能。<br />
&nbsp; 虽然建筑学有着它不为人知的复杂性的一面，但是与软件开发相比，它也有着简单贫瘠的一面。现在架构师言必称设计模式，但是估计很少有人读过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个模式，括号中的便是模式的编号。很明显，物理空间的不可重入性直接规范了建筑设计空间的有限性。<br />
&nbsp; 在软件设计中，类似VB/Delphi的可视化界面设计的操作过程与此类似：理想情况下界面开发基本就是用各种界面元素填满一个Form的过程。但是软件的一个本质复杂性在于它的基本结构单元是函数，而设计空间中同一个功能点对应的实现函数的个数和形式并不存在有限性的约束，函数的组合形式也不是线性延展的。建筑基本上依赖的是静力学，而软件无疑需要用动力学来刻画。即使是界面开发，我们所关注的也决不仅仅是静态摆放问题，而更重