<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>canonical</title>
    <description>http://canonical.blogjava.net</description>
    <link>http://canonical.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>主从分解而不是正交分解</title>
        <author>canonical</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://canonical.javaeye.com">canonical</a>&nbsp;
          链接：<a href="http://canonical.javaeye.com/blog/196826" style="color:red;">http://canonical.javaeye.com/blog/196826</a>&nbsp;
          发表时间: 2008年05月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp; 说到分解，很多人心中的意象大概只有正交分解。正交分解无疑是最重要的一种分析方法，它也是所谓&ldquo;分而治之&rdquo;思想最常见的实现策略。但是正交分解一般潜在的假定是分解后的子部分是大致均衡的，它们是相对具有独立价值的，可以彼此脱离独立发展。这是分解后实现系统解耦的重要原因。<a href="../../blog/33885">http://canonical.javaeye.com/blog/33885 </a>
但是物理学中另一种重要的分析学思想是微扰论(Perturbation). 针对一个复杂的物理现象，首先建立一个全局的规范的模型，然后考虑各种微扰条件对原有模型的影响。在小扰动情况下，模型的变化部分往往可以被线性化，被局域化，因而问题得到简化。微扰分析得到的解依赖于全局模型的解而存在，因而这是一种主从关系的分解方式。但是如果主体模型是我们已经熟知的物理现象，则我们关注的重点可以全部放在扰动解上，认为所有特定的物理规律都体现在扰动解中。如果微扰分析得到的物理元素足够丰富，则微扰模型本身可以成为独立的研究对象，在其中我们同样可以发现某种普适的结构规律。</p>
<p><br />
&nbsp; Witrix平台中系统化的应用主从分解模式，通过类似AOP的技术实现了业务模型与平台技术的自然结合。<a href="../../blog/126467">http://canonical.javaeye.com/blog/126467</a>
 最近我们的一个产品的新版本即将在全国范围内部署，如何有效的控制众多相近的二次开发版本，同时确保主版本的快速升级，是在架构层面必须解决的问题。<a href="../../blog/73265">http://canonical.javaeye.com/blog/73265</a>
 在Witrix平台中，各部署版本并不是直接修改主版本源代码得到，而是将差异化代码放在单独的目录中进行管理，由系统运行平台负责将差异化定制代码与主版本代码进行动态融合，实现部署版本的客户化。在这一过程中，系统模型本身支持逆元结构至关重要，否则某些多余的元素无法通过差异性描述去除，则将出现局部模型失效的情况。</p>
<p><br />
&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 />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 基础平台中对于代码动态融合定义了精细的融合策略，将通过编译技术检查扩展标签的接口与缺省实现的接口相兼容，由此确保代码扩展后不会破坏主版本中的已有调用代码。</p>
<p>&nbsp;&nbsp; 在基础平台的实现中，很多实现代码都是类似</p>
<pre name="code" class="xml">          &lt;df:WhenAllowFinishWf&gt;
            &lt;df:FinishWfButton /&gt;
          &lt;/df:WhenAllowFinishWf&gt;</pre>
&nbsp;
<p><br />
这样的类似废话的标签调用。但是通过这些标签的标记，我们确立了系统的逻辑结构，标定了系统中可以被安全替换的逻辑片断。</p>
          <br/>
          <span style="color:red;">
            <a href="http://canonical.javaeye.com/blog/196826#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 26 May 2008 00:36:02 +0800</pubDate>
        <link>http://canonical.javaeye.com/blog/196826</link>
        <guid>http://canonical.javaeye.com/blog/196826</guid>
      </item>
      <item>
        <title>不完全的计算</title>
        <author>canonical</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://canonical.javaeye.com">canonical</a>&nbsp;
          链接：<a href="http://canonical.javaeye.com/blog/172333" style="color:red;">http://canonical.javaeye.com/blog/172333</a>&nbsp;
          发表时间: 2008年03月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          &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/>
          <span style="color:red;">
            <a href="http://canonical.javaeye.com/blog/172333#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 16 Mar 2008 15:20:46 +0800</pubDate>
        <link>http://canonical.javaeye.com/blog/172333</link>
        <guid>http://canonical.javaeye.com/blog/172333</guid>
      </item>
      <item>
        <title>WebMVC之前世.今生</title>
        <author>canonical</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://canonical.javaeye.com">canonical</a>&nbsp;
          链接：<a href="http://canonical.javaeye.com/blog/163196" style="color:red;">http://canonical.javaeye.com/blog/163196</a>&nbsp;
          发表时间: 2008年02月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          &nbsp;
所谓WebMVC即Model2模型是目前Web开发领域的主流模型，Struts/Struts2框架是其典型实现。在概念层面上，这种程序组织模型是
怎样建立起来的?与其他Web开发模型(如面向对象模型)具有怎样的联系? 它未来可能的发展方向在哪里?
结合Witrix开发平台的具体实践，基于级列设计理论我们可以看到一条概念发展的脉络。<a href="../../blog/33824">http://canonical.javaeye.com/blog/33824</a><br />
<img src="http://www.blogjava.net/images/blogjava_net/canonical/web_app_structure.jpg" border="0" alt="" style="width: 658px; height: 992px" /><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 />
<a href="http://www.CodeHighlighter.com/" target="_blank">http://www.CodeHighlighter.com/</a><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">&quot;</span><span style="color: #000000">paramA</span><span style="color: #000000">&quot;</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">&quot;</span><span style="color: #000000">paramB</span><span style="color: #000000">&quot;</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 />
<a href="http://www.CodeHighlighter.com/" target="_blank">http://www.CodeHighlighter.com/</a><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">&quot;</span><span style="color: #000000">/show_table.jsp</span><span style="color: #000000">&quot;</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 />
<a href="http://www.CodeHighlighter.com/" target="_blank">http://www.CodeHighlighter.com/</a><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">&quot;</span><span style="color: #000000">myBiz</span><span style="color: #000000">&quot;</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">=</span><span style="color: #000000">&quot;</span><span style="color: #000000"><img src="http://www.blogjava.net/Images/dot.gif" alt="" /></span><span style="color: #000000">&quot;</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">&quot;</span><span style="color: #000000">&lt;%=&nbsp;dataList&nbsp;%&gt;</span><span style="color: #000000">&quot;</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 />
<a href="http://www.CodeHighlighter.com/" target="_blank">http://www.CodeHighlighter.com/</a><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">&quot;</span><span style="color: #000000">success</span><span style="color: #000000">&quot;</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="../../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 />
<a href="http://www.CodeHighlighter.com/" target="_blank">http://www.CodeHighlighter.com/</a><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">&quot;</span><span style="color: #000000">pager</span><span style="color: #000000">&quot;</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">&quot;</span><span style="color: #000000">pager</span><span style="color: #000000">&quot;</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="../../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="../../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=&quot;Remove-default&quot;&gt;操作。注意到AOP定位技术首先要求的就是良好的坐标定义,
实体化明确定义了实体操作边界，为实体相关切点的构造奠定了基础。<a href="../../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="../../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 />
<a href="http://www.CodeHighlighter.com/" target="_blank">http://www.CodeHighlighter.com/</a><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">=&quot;docflow&quot;</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">=&quot;my&quot;</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">=&quot;initTpl&quot;</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">=&quot;my_ops.js&quot;</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/>
          <span style="color:red;">
            <a href="http://canonical.javaeye.com/blog/163196#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 18 Feb 2008 22:23:14 +0800</pubDate>
        <link>http://canonical.javaeye.com/blog/163196</link>
        <guid>http://canonical.javaeye.com/blog/163196</guid>
      </item>
      <item>
        <title>C++配置管理</title>
        <author>canonical</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://canonical.javaeye.com">canonical</a>&nbsp;
          链接：<a href="http://canonical.javaeye.com/blog/155305" style="color:red;">http://canonical.javaeye.com/blog/155305</a>&nbsp;
          发表时间: 2008年01月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          

&nbsp; 自从离开学校就基本上不再使用C++了，最近却又因为项目上的原因重新走入这一迷失的世界, 感觉很是缺乏一些顺手的工具。首先就是做配置管理有点麻烦, 因为缺乏反射机制, 无法直接映射, 所以一般需要手工书写配置设置功能. <br />
&nbsp; 我们希望配置类在配置阶段能够支持动态属性名，<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%"><!--{cps..0}--><span style="color: #000000">&nbsp;&nbsp;GConfig&nbsp;cfg;<br />
&nbsp;&nbsp;cfg.set(</span><span style="color: #000000">&quot;</span><span style="color: #000000">bgColor.b</span><span style="color: #000000">&quot;</span><span style="color: #000000">,</span><span style="color: #000000">3.0</span><span style="color: #000000">);<br />
&nbsp;&nbsp;cfg.set(</span><span style="color: #000000">&quot;</span><span style="color: #000000">lightEnabled</span><span style="color: #000000">&quot;</span><span style="color: #000000">,</span><span style="color: #0000ff">false</span><span style="color: #000000">);<br />
<br />
&nbsp;&nbsp;t_float&nbsp;b&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;cfg.get(</span><span style="color: #000000">&quot;</span><span style="color: #000000">bgColor.b</span><span style="color: #000000">&quot;</span><span style="color: #000000">);<br />
&nbsp;&nbsp;bool&nbsp;l&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;cfg.get(</span><span style="color: #000000">&quot;</span><span style="color: #000000">lightEnabled</span><span style="color: #000000">&quot;</span><span style="color: #000000">);</span></div>
<br />
&nbsp;&nbsp;&nbsp; 但是内部使用时支持直接的属性访问，便于编译器检查， 也提高运算速度。<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%"><!--{cps..1}--><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t_float&nbsp;b&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;cfg.bgColor.b;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;l&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;cfg.lightEnabled;</span></div>
<br />
<br />
所幸C++的类型系统能够偷偷的去干很多见不得人的勾当，因此便有了下面这个简易机制。<br />
<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%"><!--{cps..2}--><span style="color: #000000">#define&nbsp;S_P(x)&nbsp;</span><span style="color: #0000ff">do</span><span style="color: #000000">{</span><span style="color: #0000ff">if</span><span style="color: #000000">(strcmp(name,#x)&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">) { x&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;value;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">; } }&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(</span><span style="color: #000000">0</span><span style="color: #000000">)<br />
#define&nbsp;G_P(x)&nbsp;</span><span style="color: #0000ff">do</span><span style="color: #000000">{</span><span style="color: #0000ff">if</span><span style="color: #000000">(strcmp(name,#x)&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">) { value&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;x;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">; } }&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(</span><span style="color: #000000">0</span><span style="color: #000000">)<br />
<br />
</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;_GConfig{<br />
</span><span style="color: #0000ff">public</span><span style="color: #000000">:<br />
&nbsp;&nbsp;bool&nbsp;lightEnabled;<br />
<br />
&nbsp;&nbsp;t_float&nbsp;minX;<br />
&nbsp;&nbsp;t_float&nbsp;maxX;<br />
&nbsp;&nbsp;t_float&nbsp;minY;<br />
&nbsp;&nbsp;t_float&nbsp;maxY;<br />
<br />
&nbsp;&nbsp;_GConfig(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;initialize&nbsp;all&nbsp;primitive&nbsp;members</span><span style="color: #008000"><br />
</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;memset(</span><span style="color: #0000ff">this</span><span style="color: #000000">,</span><span style="color: #000000">0</span><span style="color: #000000">,sizeof(_GConfig));<br />
&nbsp;&nbsp;}<br />
};<br />
<br />
</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;GConfig:&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;_GConfig{<br />
</span><span style="color: #0000ff">public</span><span style="color: #000000">:<br />
&nbsp;&nbsp;GColor&nbsp;bgColor;<br />
<br />
&nbsp;&nbsp;GConfig(){<br />
&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;_variant_t&nbsp;get(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;name){<br />
&nbsp;&nbsp;&nbsp;&nbsp;_variant_t&nbsp;value;<br />
&nbsp;&nbsp;&nbsp;&nbsp;get(name,value);<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;value;<br />
&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;get(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;name,_variant_t</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;value){<br />
&nbsp;&nbsp;&nbsp;&nbsp;G_P(lightEnabled);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;G_P(minX);<br />
&nbsp;&nbsp;&nbsp;&nbsp;G_P(maxX);<br />
&nbsp;&nbsp;&nbsp;&nbsp;G_P(minY);<br />
&nbsp;&nbsp;&nbsp;&nbsp;G_P(maxY);<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;G_P(bgColor.r);<br />
&nbsp;&nbsp;&nbsp;&nbsp;G_P(bgColor.g);<br />
&nbsp;&nbsp;&nbsp;&nbsp;G_P(bgColor.b);<br />
&nbsp;&nbsp;&nbsp;&nbsp;G_P(bgColor.a);<br />
&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;set(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;name,&nbsp;_variant_t&nbsp;value){<br />
&nbsp;&nbsp;&nbsp;&nbsp;S_P(lightEnabled);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;S_P(minX);<br />
&nbsp;&nbsp;&nbsp;&nbsp;S_P(maxX);<br />
&nbsp;&nbsp;&nbsp;&nbsp;S_P(minY);<br />
&nbsp;&nbsp;&nbsp;&nbsp;S_P(maxY);<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;S_P(bgColor.r);<br />
&nbsp;&nbsp;&nbsp;&nbsp;S_P(bgColor.g);<br />
&nbsp;&nbsp;&nbsp;&nbsp;S_P(bgColor.b);<br />
&nbsp;&nbsp;&nbsp;&nbsp;S_P(bgColor.a);<br />
&nbsp;&nbsp;}<br />
};<br />
</span></div>
<br />
_variant_t是VC++在&lt;comdef.h&gt;中提供的对变体数据类型的封装。使用S_P和G_P这样的宏可以由编译器检查变量名的正确性。<br />
 
          <br/>
          <span style="color:red;">
            <a href="http://canonical.javaeye.com/blog/155305#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 12 Jan 2008 20:59:20 +0800</pubDate>
        <link>http://canonical.javaeye.com/blog/155305</link>
        <guid>http://canonical.javaeye.com/blog/155305</guid>
      </item>
      <item>
        <title>关系模型与ORM</title>
        <author>canonical</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://canonical.javaeye.com">canonical</a>&nbsp;
          链接：<a href="http://canonical.javaeye.com/blog/153515" style="color:red;">http://canonical.javaeye.com/blog/153515</a>&nbsp;
          发表时间: 2008年01月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          关系数据库模型在理论上主要解决的是消除数据冗余的问题。关系模型的数学基础是所谓的集合论，而集合的基本含义正是一组具有某种原子性的互不相同的元素。面向对象技术是对相关性进行局域化的一种手段（相关的数据和操作聚集到同一对象名义下），在这一局域化过程中，相同的元素被识别出来，成为独立的对象。从某种意义上说，关系模型与对象模型是殊途同归的过程，是从不同侧面对同一事物的反映。关系模型中，我们关注的重点是元素组成的集合，允许的连接关系定义在集合之上。而在对象模型中，我们关注的首先是横向关联的实体，实体之间具有稳定的联系。在概念层面上，从对象模型映射到一种关系存储模型只是一个分组问题。为了断开实体之间的直接联系，关系模型创造了一个id字段，而对象模型并不是需要显式id的。在关系模型中，关联并不是通过某种存在的结构来表达的（一个实体持有另一个实体的指针，拥有直接联系），而是将直接关联问题弱化为某种计算过程，我们必须检查id的值（不是某种直接的存在性），通过某种运算过程才能重新发现数据之间的关联。<br />    <br />    通过id（伴随一个匹配计算过程）来进行间接关联对于保证模型的一致性是非常关键的。在ORM中恢复了对象的强关联其实会造成很多潜在的复杂性。例如为了维护对象层面结构的一致性，在更新父子关系的时候，我们需要同时调用 child.setParent(parent); parent.getChildren().remove(child); 当关联结构更加复杂的时候，这里所需要的维护工作是随之增加的。不过，在ORM中，对象的形态是暂时性的。在ORM的一次session的操作过程中，对于对象状态的修改可以是不一致的。例如我们可以只调用child.setParent(parent); 而不需要同时  parent.getChilren().remove(child); 只要我们在此次session操作中，不需要同时用到parent.getChildren(). 这种关联的暂时性对于很多ORM应用来说是必不可少的。<br />    <br />    对象模型中可以直接表达的结构关系比关系模型要丰富一些，例如继承关系，many-to-many, one-to-list等。但是所有这些都不是真正本质性的差异。抛弃概念诠释，基类与众多派生类之间的关系基本上可以等价于一组one-to-one关系。而当关联对象本身的重要性凸现出来的时候，当我们无法把它约化为对象上的一些附属特性的时候（例如数组的下标），我们必然要建立相应的关联对象，而这正对应于关系模型中的中间关联表。中间关联表上增加额外的字段是一个自然的扩展过程，而对象模型上做这样的扩充往往表现为形态上的重大的不兼容的变化，例如从getManyToManyEntity() -> getToManyRelation(), 这实际上意味着这里的对象形式是偶然的，简化的。 <br />    <br />    在原始的关系数据库模型中，所有的表之间的地位是平等的，所有字段之间的地位是平等的（主键和外键在参与数据关联时和其他字段的处理方式一致）。这种概念上的均一性和普遍性往往被认为是理论的优美之处。但是现实世界是复杂的，发展的方向就是逐步识别出不同之处，并找出自然的表达形式将这些不同表达出来。均匀的关系模型是对称性最高的，最简化的模型。在面对物理约束时，它隐含的假设是集合之间很少发生相互作用，单表（表单到数据表之间的映射）和主从表是最广泛的情况。试着想象一下关系模型，在思维中一般我们只能看到两个数据表，当考虑到多个表的时候，因为这些表之间没有明确的可区分性，因此它们的意象是模糊的。只有明确意识到主键，外键，主表，从表，字典表，事实表，纬度表这些不同的概念的时候，当对称性出现破缺的时候，我们思维中的模型才能够丰富化起来。<br />    <br />    关系模型理论应用到数据库具体应用中时，并不需要死守关系范式教条，它们只是描述了某种极端化的对唯一性的追求。面对具体应用的时候，理论本身也在不断丰富化。我并不把现实应用中必然需要增加冗余字段看作是关系理论失效的结果。从关系完全分解，到关系完全不分解之间，我们可以建立大量的模型。建立冗余字段的时候，我们存在着大量可能的选择，到底哪一种选择是最优的，理论方面仍然可以给我们以具体的指导。理论在各种不同纯化程度的关系模型中都可以给我们以直观的建议。数据仓库理论中建立的snowflake模式和star模式，强调了针对主题域的允许部分冗余的关系分解。这里实际上是强调了表之间的不同性。不再是所有的表都处于同一地位。Fact Table和Dimension Table之间的区别被识别出来，并被明确处理。在我看来，这是原始关系模型的一种自然发展，它也是关系模型理论的一部分。理论不应该是单一的，而是提供一个模型级列，在不同的复杂性层次上，我们可以根据理论的指导选择具体的实现模型。<br />    <br />    关于ORM <a href="http://canonical.javaeye.com/blog/111500" target="_blank">http://canonical.javaeye.com/blog/111500</a><br />    关系模型中的所谓关系是在使用时刻才定义的，所有建立关系的方式在某种程度上都是等价的，也是外在的。而在ORM中主键与外键之间的关联被独立出来，成为模型内置的部分。这在很多时候简化了数据查询的结构构造过程。<br />    在ORM中主键因为缓存的存在而显出与其他字段的区别。ORM的使用使得数据存储的分解策略得到扩充。并不是所有的表的更新频度都是一致的，而且表中的数据量大小也不同。字典表一般较小，而且很少更新，可以安全的复制。在整个数据存储框架中，ORM作为独立的技术元素参与数据存储过程，通过主键提供缓存服务，产生了新的数据分布模型，提供了新的性能优化契机。
          <br/>
          <span style="color:red;">
            <a href="http://canonical.javaeye.com/blog/153515#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 06 Jan 2008 19:20:29 +0800</pubDate>
        <link>http://canonical.javaeye.com/blog/153515</link>
        <guid>http://canonical.javaeye.com/blog/153515</guid>
      </item>
      <item>
        <title>关于学习</title>
        <author>canonical</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://canonical.javaeye.com">canonical</a>&nbsp;
          链接：<a href="http://canonical.javaeye.com/blog/150359" style="color:red;">http://canonical.javaeye.com/blog/150359</a>&nbsp;
          发表时间: 2007年12月24日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          我平时Kill Time的主要方式是阅读各类学术书籍。但是学习本身只是了解前人的发现，间或锻炼一下自己的思维能力，对自己的工作和生活并没有什么直接的助益。学习本身无论如何深入，多半也只是采用前人的话语复现前人思考的历程。在我们通过独立的思考获得直观的体验之前，在我们将所学到的知识应用到书本之外的场景之前，我们所学习的知识只是考试的工具，只是可供欣赏的对象，却不能成为我们思考中活跃的因素，无法参与我们思维的进程。别人只能给你思想的引子，并不能给你真正的思想。只有自己找到了所学知识的超出书本的非显然的应用，只有独立建立了不同概念之间未曾阐明的联系，我们才能真正获得对于真理的体悟。无论我们自己的发现是如何的微不足道，无论它是否只是重复发现了劣质的轮子，它唯一的意义只在于它是我们独立思考的结果，是我们自己的创造。即使它是卑微的，是重复的，它对我们的理解的作用仍然是任何外在的教诲都无法比拟的。<br /><br />    现代社会中创造所需的成本已经被空前降低了。想想百年前的天才们，他们缺少信息来源，只能一页页翻查文献，反复誊写文稿来保存知识，大量的时间被花费在了与思考完全无关的事情上。同时，他们所处的时代存在着更多的不确知性，他们的思考所能够凭依的事实更少，做出错误判断的可能性与今天相比也更大。即使 Bill Gates这样的挣钱能手在1981年也能放出"640k ought to be enough for anybody"的厥词，显示出我们在预测未来的时候是何等的乏力。当我们今天站在人类文明的巅峰，拥有前人无法想象的工具，并不断制造着从未经历过的实践的时候，我们理应拥有超越历史上任何天才的，更加宽广的眼界。<br /><br />    现代社会中的创造看似简单了，但从另一个方面看，却又是大大的复杂化了。前人的成就成为了难以逾越的丰碑，而为了进入科学殿堂，我们需要的准备工作也变得异常的繁复。这里有科学内在的规律，但也有人为制造的障碍，而这其中最主要的是数学障碍。只要想一想，针对软件工程，经济运行，企业管理，每个参与其中的实践者都可以提出一些自己的意见，但是如果涉及到数学，为什么大多数人只有三缄其口了？现代抽象数学取得了辉煌的成就，但是它也可能毁掉了更多学生创造的激情。宏伟精深的大厦让人敬畏，却无法激发我们任何直观的共鸣。甚至Arnold这样的数学大师也坦承读不懂当代数学家们的著述：因为他们从不说“彼嘉洗了手”，而只是写道：存在一个t1&lt;0，使得t1在自然的映射t1->彼嘉(t1)之下的像属于脏手组成的集合，并且还存在一个t2， t1&lt;t2&lt;=0，使得t2在上面提到的映射之下的像属于前一句中定义的集合的补集。当Bourbaki学派致力于在课本上消灭所有图示的时候，理性达到了非理性的彼岸。<br /><br />    有时我在想为什么现在的程序员似乎对于程序的理解能力降低了。排除教学水平的降低和个人努力的不足之外，是否是因为现在需要学习的内容过多，以至于丧失了自我思考的勇气？在C的时代，每个程序员对于程序的理解都是直接的，原始的，对程序结构的把握都是充满自信的。当新的概念不断涌现的时候，人们总是说， Object不过是..., Component不过是..., AOP不过是..., ORM不过是..., IoC不过是.... 这体现了人们试图把新的概念融入自己原有知识体系的一种努力。虽然仔细考究起来，这里的理解很多时候都是似是而非的，未必掌握了新技术真正创新的思想方向，但是这里的思考总是独立进行的，总是对我们的理解和工作有所助益的。而新一代的程序员生活在Object, Pattern等概念已经无需饶舌来证明自己的时代，他们是否在思想中独自评估过所有概念的意义，是否建立了概念和实现之间直观的联系，是否在统一的思维世界中为所有的概念找到了合适的坐标？这一切，我不得而知。<br />    <br />推荐：Arnold 论数学教育 <a href="http://www.ieee.org.cn/dispbbs.asp?boardID=64&ID=25892" target="_blank">http://www.ieee.org.cn/dispbbs.asp?boardID=64&ID=25892</a>
          <br/>
          <span style="color:red;">
            <a href="http://canonical.javaeye.com/blog/150359#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 24 Dec 2007 01:11:47 +0800</pubDate>
        <link>http://canonical.javaeye.com/blog/150359</link>
        <guid>http://canonical.javaeye.com/blog/150359</guid>
      </item>
      <item>
        <title>代码之外的结构</title>
        <author>canonical</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://canonical.javaeye.com">canonical</a>&nbsp;
          链接：<a href="http://canonical.javaeye.com/blog/148609" style="color:red;">http://canonical.javaeye.com/blog/148609</a>&nbsp;
          发表时间: 2007年12月15日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          我在各种场合一直都在强调结构问题是独立的，在程序语言之外存在着独立的，可研究的，富有成效的结构问题。<a href="http://canonical.javaeye.com/blog/147424 " target="_blank">http://canonical.javaeye.com/blog/147424 </a>在这个方向上更进一步，我们注意到所有的代码并不是天然出现的，而是由人所编制的，因此代码世界内部并不构成封闭的，自足的某个世界。代码中的结构问题并不是由代码本身完全解决的，即在代码之外仍然存在着技术上可研究的结构问题。<br /><br />    我们在编制代码的同时也在编制着大量的说明文档。这些文档描述了代码片断之间的相互关系，描述了代码未来的扩展方向，描述了代码之间的可能的交互方式，同时也描述了针对现有代码实现的很多具体约束。例如我们在文档中约定某个量要在10和20之间，但在代码中却不一定显式进行了判断。针对代码结构的很多具体约束条件和相关性描述可能只在文档中体现，只在程序员的头脑中存在，而并不一定忠实的在代码结构中得到表达。<br /><br />    我在设计领域基本持有一种物理实在论，即某种技术相关的约束应该在技术世界中通过技术手段得到表达。只是这里的技术手段却不一定指在应用中加上特定的代码实现，虽然我们在代码实现中更直接的表达设计要求无疑是需要提倡的。为了在程序中有效的维护结构相关性，我们并不一定需要抽象出所有可能重用的代码，并不一定需要确保某一概念在程序中只有精确的唯一的表达。程序中难以直接精确表达的弱关联，仍然可以通过开发/设计工具等技术手段得到有效的维护。我们需要保证的是代码世界中知识的自恰性，而自恰性并不等于唯一性。<a href="http://canonical.javaeye.com/blog/33788" target="_blank">http://canonical.javaeye.com/blog/33788</a><br /><br />    在Witrix中我们采用一种物理模型驱动的开发方式，<a href="http://canonical.javaeye.com/blog/29412" target="_blank">http://canonical.javaeye.com/blog/29412</a> 由pdm模型出发，自动生成hibernate的hbm文件，java实体类，元数据meta文件，前台Action注册文件等。生成的配置文件通过 syncWithModel标记与模型保持着稳定的关联。所有配置文件都支持手工修改，开发工具识别syncWithModel标记，当pdm模型发生变化的时候，工具自动将变化信息同步到各个配置文件中。注意到这里并不是采用一个统一的元数据模型的方式，各个配置文件所表达的信息在一定程度上是重复的，也可能是不一致的。例如后台数据库允许保存100个字节，但是前台meta中我们可能配置只允许录入20个字节。根据不同应用场景的需要，我们可以在各个层面对每个配置文件进行独立的调节. 当然,在一般情况下并不存在这种需要。整个开发过程中，信息表达的自恰性并不是在应用程序代码中得到定义的,而是因为开发工具的存在而在技术上得到保证的。放松模型之间的唯一匹配要求，我们可以得到更加丰富，更加灵活的软件结构。实际上我认为RoR(RubyOnRails)采用直接映射的 ActiveRecord的方式虽然有效保证了系统变动中知识的一致性，但是如果不允许在各个层面上都能够自然的定义某种偏离，它在复杂应用中的价值就要打上大大的折扣。
          <br/>
          <span style="color:red;">
            <a href="http://canonical.javaeye.com/blog/148609#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 15 Dec 2007 19:49:45 +0800</pubDate>
        <link>http://canonical.javaeye.com/blog/148609</link>
        <guid>http://canonical.javaeye.com/blog/148609</guid>
      </item>
      <item>
        <title>结构的独立性</title>
        <author>canonical</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://canonical.javaeye.com">canonical</a>&nbsp;
          链接：<a href="http://canonical.javaeye.com/blog/147424" style="color:red;">http://canonical.javaeye.com/blog/147424</a>&nbsp;
          发表时间: 2007年12月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          设计考虑的是最终需要什么，最终我们要提供的调用接口是什么，我们所直接需要的某个有价值的，直接存在的，直接可以接触的结构是什么，而不是它所依据的原理是什么，不是它的具体构造过程或者构造方法是什么。比如说我们在程序中完全不需要内置Map这一结构，因为它可以通过列表等结构组合构建出来，但是很显然，Map这一概念的直接存在对我们来说是方便的，是经济的，是有效的。我们在思考的时候并不需要考虑它是采用List实现还是采用Set实现，或者任何它本身的构造结构。这一概念在我们的思想中成为某种原子化的东西。<br /><br />    那么，我们到底需要构建哪些概念，才能够最方便的基于这些概念应对万千应用系统的开发呢。 这是我们需要在结构空间作出探索的。 这里的思维方向不是把系统推向某种纯粹化，某种极致的简单化，而是让它更加物理化，揭示出更多的层次，更加关切在物理约束情况下如何实现灵活性的最大化。一种概念在物理上如果被证明能够在很多场景下成为不变的基元，则它便是有价值的，是可以进行物理诠释的。<br /><br />   很多人习惯于接受语言存在的现实，接受设计后的结果，但是作为程序语言设计者，他们又是如何工作的？他们是否真的是从纯粹的数学关系推演得到所有的语法特征，还是他们预先已经在心中设定了应该出现的语法特征，然后去寻找它的数学表达，只是借此清除思维中潜在存在的矛盾性呢？<br /><br />    语言中存在的所有特征是经过全局考虑的，是清除了所有概念的矛盾冲突的。但是在现实中，我们偶然构造的结构却可能是局限于当下的信息构造的，因此它们相会的时候，可能会出现不协调，可能会出现结构障碍。例如同样是关闭操作，有些人命名为close, 另一些人命名为destroy. 可能一个具有额外参数，另外一个没有。这里可能需要一种adaptor接口的封装，也可能使用ruby那种method-missing的动态判断。对于更加错综复杂的结构问题，其解决方案就不是那么显然的了，但这并不意味着我们无办法可想。究竟设计何种结构边界才能最小化结构融合时所要付出的代价呢？结构被识别并表征出来以后，是否允许它在一定范围内有所变形？在变形中我们需要保持的拓扑不变量是什么？结构动态调整的时候，我们是否需要定义调整的物理代价，是否能够定义某种动力学？<br />    <br />   我所阐述的只是在计算机理论中从数学视角向物理视角的转换，它不是必然给你某种超越当下的能力，而是提供一种不同的眼光看待所有的一切。视角变换后，我们发现了一些新的命题，而在原先的视角下在我们的话语体系中原本是无法表达这些命题的。串行程序假设了只有1颗CPU, 而函数式语言假设了可以有无限多个CPU, 你不觉得1至无穷之间缺点什么吗。我们可以创造一些东西把1至无穷之间的空白补齐，概念空间是连续的。
          <br/>
          <span style="color:red;">
            <a href="http://canonical.javaeye.com/blog/147424#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 11 Dec 2007 00:00:35 +0800</pubDate>
        <link>http://canonical.javaeye.com/blog/147424</link>
        <guid>http://canonical.javaeye.com/blog/147424</guid>
      </item>
      <item>
        <title>关于抽象性的一些澄清</title>
        <author>canonical</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://canonical.javaeye.com">canonical</a>&nbsp;
          链接：<a href="http://canonical.javaeye.com/blog/147121" style="color:red;">http://canonical.javaeye.com/blog/147121</a>&nbsp;
          发表时间: 2007年12月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          没有人否认抽象的意义，但是抽象是否就是抽象到无穷大，这是个可以明确定义的问题，也是数学领域正在解决的问题。在我们的思考中没有明确定义何处是边界，没有明确的限制，这便是导向无穷的一种思维方式，它和现实中是否真的允许消耗无限多的资源，创建无限多的对象无关。当我们认为自己明白了终极的意义，明白了一种推向无穷的抽象，这并不是理解了世界的全部，我们仍然要明白如何解决一些更加小范围，但是却又普遍发生的事情。<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语言来开发商业应用，难道你罢工吗？如果你不使用函数式语言，你所做的工作就不是程序工作了？你所解决的难道不是程序结构问题了吗？现在就是有一个结构问题要解决, 它是和语言无关的. 语言提供了就可以直接用, 语言没有提供我们可以写代码构造. 难道除了语言直接体现的结构之外, 程序本身就无法构造任何具有通用价值的结构了吗？<br /><br />   我在说到函数式语言的时候，基本的态度只是说不要太沉迷于一种特殊的抽象方式，应该多看看别的视角。在不同的情况下存在着做事情的不同的最优方式。思维中不要只允许永远，而容不下现在。<br />  <br />   非此即彼，天下唯我,是我们思维中经常陷入的一个误区。现在计算机领域所谓的理论主要是基于数学视角的，没有考虑物理世界因为我们观察的有限性，因为资源的有限性所造成的种种约束，此外数学中目前也没有考虑到物理世界真实的各种复杂性的存在。在我们想到一种计算机理论的时候，图像过于简单化，这种简单化被认为是优美的全部。其实我们应该思维更加开放一些。
          <br/>
          <span style="color:red;">
            <a href="http://canonical.javaeye.com/blog/147121#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 09 Dec 2007 22:27:28 +0800</pubDate>
        <link>http://canonical.javaeye.com/blog/147121</link>
        <guid>http://canonical.javaeye.com/blog/147121</guid>
      </item>
      <item>
        <title>关于语言有效性的一些澄清</title>
        <author>canonical</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://canonical.javaeye.com">canonical</a>&nbsp;
          链接：<a href="http://canonical.javaeye.com/blog/147075" style="color:red;">http://canonical.javaeye.com/blog/147075</a>&nbsp;
          发表时间: 2007年12月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          数学上的有效性与物理中的有效性是不同的，例如对于密码学问题，如果通过穷举法破解密码成功时，经过这些密码加密的数据已经过了有效期限，此时我们在数学上定义穷举法不是一种有效的破解方法。但是物理层面上我们说只要一种方法比另一种方法能够更快的解决问题，我们就说第一种方法比第二种方法有效，而无论密码被破解的时候该密码是否已经过了有效期限。<br /><br />    我所表述的论题并不是说特定的领域结构无法在某个特定的通用语言中有效实现。我想很多人对我的话语都有些误解。<br /><div class="quote_title">引用</div><div class="quote_div"><br />如果我们认为一种通用语言是比较稳定的,则它一般选择只内置一些通用的不带有领域特定含义的概念. 而缺乏领域知识,或者说因为通用语言故意的摒弃领域依赖, 它在处理领域相关的问题的时候并不是有效的.这种有效性不是数学含义上的,而是可以进行物理度量的. </div><br />   现在ErLang对通信领域具有良好的支持，你可以说它对于通信领域的结构是有效的。但是显然在ErLang中编写界面就不如面向对象语言得心应手。在ErLang中实现界面结构的时候，它对于界面结构的表述就不是那么符合我们直观的，对我们的实现过程来说就不是那么经济的。因此在界面结构的实现上，目前我们可以说ErLang相对于面向对象语言而言就是不那么有效的。也许你会说ErLang做XX发展之后怎见得就更差。但是如果允许引入未来这一具有无限可能性的因子，我们基本上无法针对现实的情况作出判断。例如我们目前并无法证明广义相对论相对于牛顿力学是更加精确的，如果允许在太阳星系中增加越来越多的隐蔽的摄动星体的话。按照库恩的科学革命论，每一个科学时代都具有着自己的科学范式，它总是具有着充分的自我辩护能力。范式的更新意味着格式塔的崩溃。回顾历史，哥白尼刚提出日心说的时候，并不是在计算精度，计算简洁性上真的远胜托勒密的地心说，只是日心说的哲学隐喻撼动了人心。<br /><br />  我说<div class="quote_title">引用</div><div class="quote_div">实际上现在的通用语言也是无法有效承载Domain Specific Structure的</div>这并不是意指在通用语言中无法针对特定应用作出特定扩展来支持特定的结构，而是说Domain Specific Structure是任意多的，作为通用语言它不应该把越来越多的结构内置在语言中(这不是很多人对ruby的希冀吗)，这么做对它来说首先是不经济的。同时某些特殊的结构在一定的场景下是有用的，但是把它抽象出来扩展到通用领域的时候，会出现有效性的丧失。例如现在我的系统中只需要10个相互依赖的线程，如果我们定死了10这个数字，显然我们可以发展一种这个领域特有的高效的一些算法结构。而抽象到通用语言中的时候，显然我们只能假设线程数是任意大，或者是充分大的，而无法充分利用10这一领域信息，因此在这个意义上我说通用语言不是有效的。<br /><br />   传统上数学使用的一种逼近范式是：当n趋于无穷大的时候，偏差趋于无穷小。现在物理学对数学的一种常见要求却是：当n限定在有限数量范围的时候（例如10以内），我们如何才能尽量减少偏差。这要求对小样本数学进行深入的研究，它所具有的物理内涵也是不同的。<br /><br />   在物理的视角下，我们所关心的不是世界在终极的意义上能否分解为函数的复合，不是要导向一种宗教式的顶礼膜拜，而是强调要尊重自己所直接感受到的，充分利用我们因为在这个世界上存在而获得的直观意象，发掘自己的直觉，这样我们才能在无限复杂的世界上借助有限的信息做出选择。
          <br/>
          <span style="color:red;">
            <a href="http://canonical.javaeye.com/blog/147075#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 09 Dec 2007 17:16:49 +0800</pubDate>
        <link>http://canonical.javaeye.com/blog/147075</link>
        <guid>http://canonical.javaeye.com/blog/147075</guid>
      </item>
      <item>
        <title>关于通用语言能力的一些澄清</title>
        <author>canonical</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://canonical.javaeye.com">canonical</a>&nbsp;
          链接：<a href="http://canonical.javaeye.com/blog/147068" style="color:red;">http://canonical.javaeye.com/blog/147068</a>&nbsp;
          发表时间: 2007年12月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          我在前面的文章中列举了大量物理学相关的例子来试图说明采用物理视角的必要性,但是可能因为物理事实大家不熟悉,结果直接被无视了. 在本文中我想有必要举一个软件领域的例子。只是在实际思考的过程中,我主要还是基于物理概念进行推理.<br />    <br />    首先我所谓“现在的通用语言”，它并不意指“现在至未来所有通用语言之合集”，而是指“目前正在被使用的某一种通用语言”，这种差别便体现了我所强调的不同的价值观和不同的视角。不是一种覆盖一切的全称判断，而是在特定物理约束下的物理实体。<br />    <br />    现在无论我们设计什么大型系统，一般总是要优先考虑微内核设计。但是很显然，如果我们的编程控制能力极强（强大到不现实的地步），我们可以把所有的代码实现为一个大的整体。一个整体的好处是勿用质疑的，否则Linux Torvalds就不会有信心和Tanenbaum PK。但即使是Linux, 随着系统越来越庞大，在内核中也补充了很多模块管理策略。我并不把这种情况看作是一种现在技术能力不到位所造成的结果，而是把它看作是在现实的物理约束下所促成的一种必然的选择。<br />    <br />    按照类似的逻辑，我认为在通用语言层面不应该导入越来越多的特征，实际上也不可能把所有可能的结构方式都内置在语言中（这种不可能不是数学意义上的不可能）。这会破坏一种语言的纯洁性，使得它极难维护和发展。为了扩大通用语言的有效应用范围，一种显然的方式是在语言中定义一些支持结构再次抽象的机制，通过可插拔的方式实现与domain相关的知识的融合。ruby这样的语言提供了大量的元编程机制, Witrix平台中tpl模板语言也发展了一系列编译期结构构造技术, 但是显然它们都不能说是结构抽象技术的终极形态. 目前我对所有通用语言所提供的结构抽象和结构组装能力都是不满意的,因此在Witrix中发展了一些领域特定的结构融合手段.例如根据"继承"关系的结构诠释(继承可以看作是两个一维集合之间的覆盖关系), 我们扩展了extends的结构操作方式, 定义了广义的extends算子. 这些特定的结构关系目前在领域特定的BizFlow语言中体现, 它们在通用语言中是难以想象的, 而把它们放置在通用的语言中也是不合适的(这种复杂的结构融合操作如果不能结合领域知识进行直观的理解, 必将导向一种思维的混乱). 这就是我所谓"现在的通用语言无法有效承载Domain Specific Structure"的含义. 这种说法其实类似于"集合论是无法包容所有数学结构的". 我们在集合论中只研究最普遍的关系,而特定的结构在特定的学科中研究. <br />    <br />    关于ErLang的例子, 我的原意是用来说明结构问题是独立的,它是和具体语言无关的.即基于消息传递发生数据关联的超轻量级进程模型这一结构不是和ErLang语言绑定的. 为此我特意加了一段说明:"这里不是要证明某种语言中无法描述这些结构，而是说结构是客观存在的，它并不是要在基础语言层面得到充分解决的". 即使在语言层面我们并不解决这个结构问题, 它仍然客观存在着,我们仍然可以用其他的技术手段去定义,去解决. 解决了这个结构问题就必然会带给我们价值,而无论我们使用何种实现语言.<br /><br />    "什么原因，什么样的约束条件,导致了现在的通用语言是无法有效承载消息传递发生数据关联的超轻量级进程模型". 这一命题并不是我原文中论点的合理推论.我并不是要说某一种特定的领域结构无法在一种特定的通用语言中得到支持.而是说如果我们认为一种通用语言是比较稳定的,则它一般选择只内置一些通用的不带有领域特定含义的概念. 而缺乏领域知识,或者说因为通用语言故意的摒弃领域依赖, 它在处理领域相关的问题的时候并不是有效的.这种有效性不是数学含义上的,而是可以进行物理度量的. 现在也有很多人认为ErLang并不是真正的通用语言,它是针对通信领域进行了特定结构调整的, 是内置了领域特定结构的. 而目前在ErLang上建立GUI的努力也并不算是成功. <br />    <br />    在前文中我举了一个例子试图说明:"在限定的物理约束下，我们的选择范围会大大缩小". "比如说我现在有无穷多种方式从北京跑到上海，但是如果限定只允许用1升汽油，那么我们的选择就近乎于0". 这里并不是要说明加上物理约束之后,我们便没有任何选择了.而是说物理约束对无穷多的可能方式起了限定选择的作用, 它最终造成我们在具体的物理场景下可能只有非常有限的选择. 例如现在允许用100升汽油, 有多少种运输方式可以满足我们的要求? 如果允许1000升呢? 但是如果不考虑所有物理约束, 我们是否能够证明说: 飞机和拖拉机的运输能力是完全一致的, 因为它们都能从北京开到上海. <br /><br />    我的观点是结构问题是独立存在的,它具有自身的价值, 研究它也需要建立特定的价值观. 一个结构可以体现为语言上的某种语法特征, 也可以通过框架等实现, 或者表现为某种设计模式,某种编程技巧. 我们在思考结构问题的时候并不是从特定语言的机制出发的, 当语言不直接支持的时候我们可以发展特定的实现技术支持它. 在未来的日子里某个结构可能被证明具有普适的价值,它会被吸收到某个通用语言中成为所有程序的支撑结构, 但是更多的结构永远都不会进入通用语言, 而是居留在某个特定的领域. 通用语言的发展并不是完全基于抽象的数学分析而进行的, 它可以从更加丰富的物理世界中吸取营养. 当一种结构进入通用语言的时候, 它所带来的绝对不只是一组数量关系,而是同时带来一系列经过实践检验的物理诠释. <br /><br />    我所谓的领域并不是指业务领域, 而是结构领域, 一个可以定义特定结构的物理场景. 一个特定的结构仍然可以支撑着任意多的具体应用. 例如CRUD操作可以作为数据管理模型. BizFlow作为界面和单实体的交互模型.<br /><br />    函数式语言为我们提供了一种具体的技术工具, 但是在现实的开发中, 为了有效的处理结构问题, 显然我们需要多种视角的组合, 而不是把所有可想见的图景都纯化为函数. 我们对世界的体验是多样化的. 这就是我所谓"世界比函数的集合要复杂"的含义.
          <br/>
          <span style="color:red;">
            <a href="http://canonical.javaeye.com/blog/147068#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 09 Dec 2007 16:41:30 +0800</pubDate>
        <link>http://canonical.javaeye.com/blog/147068</link>
        <guid>http://canonical.javaeye.com/blog/147068</guid>
      </item>
      <item>
        <title>关于语言与结构的一些说明</title>
        <author>canonical</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://canonical.javaeye.com">canonical</a>&nbsp;
          链接：<a href="http://canonical.javaeye.com/blog/147067" style="color:red;">http://canonical.javaeye.com/blog/147067</a>&nbsp;
          发表时间: 2007年12月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          每当我在文字中对函数式语言有些不敬之意时,便好像动了某些人的奶酪,以至我的言辞总在被曲解后遭到排斥。我想这就是因为视角差异过大所造成的. 但是谦虚谨慎是传统的美德, 不能容纳他人的观点只会妨碍自己在某些方向的探索。<br /><br />   首先请不要轻易怀疑我的知识水平。当然如果总无法聚集起足够的注意力来理解别人话语中的细节，我也无话可说。<br /><br />   容纳他人的观点就意味着不要总在自己的话语体系中试图找到反例. 一个人总是受限于他的知识范围，因此他也经常在自己的知识范围内篡改曲解别人的意见。我从未说过 "一个具体的问题是现有的通用语言无法描述的". 我说的是"现实开发中所需要处理的结构问题并不是在语言层面得到充分<strong>解决</strong>的", "<strong>现在</strong>的通用语言也是无法<strong>有效</strong>承载Domain Specific Structure的". 请注意我对定语和动词的选择。其实我已经举了大量的例子来进行说明，但可能因为大多数人不是物理背景,对相关的内容不熟悉，所以直接无视了。这也很对，符合物理学的精神。<br /><br />   可能大多数人都知道函数式语言和命令式语言都是和图灵机等价的，因此它具有某种终极能力，怀疑它无异于怀疑我们世界存在的基础。但是请注意，这种等价性是数学性的。它潜在的要求是无限的能量和时间消耗。如果在限定的物理约束下，我们会发现我们的选择范围会大大缩小。所以我说"函数式语言和命令式语言的计算能力相同，但是在具体的情形下它们的描述能力是不同的". 比如说我现在有无穷多种方式从北京跑到上海，但是如果限定只允许用1升汽油，那么我们的选择就近乎于0。飞机和汽车的运输能力是相同的吗。物理学的一个基本精神在于一种物理性的约束是始终存在的。而事实上，我们在实际工作中也总是在各种有限的物理条件下工作。<br /><br />   也许有些人认为这种区分是无关紧要的，我们只关心某种终极的东西。但是物理学中有着太多的例证，说明在有限约束下，整个系统呈现出完全不同的性质。在通信领域我们都知道Shannon定理，它的物理诠释是在有噪声的信道上可以<strong>有效</strong>的进行<strong>准确</strong>的信息传递。但是这一诠释只能在有限的数学精度（远大于我们实际需求的精度）上成立, 在绝对准确的数学意义上，这是不可能的事情。<br /><br />   你觉得现在的通用语言做起领域相关的东西来很方便吗，这就是我所谓无法有效承载的含义。在这里我也没有否认"未来的牛语言可以轻松搞定目前难题"的可能性。<br /><br />   因为所有的软件设计最终都要落实到某种代码实现上，所以怎么会有什么神秘的软件结构是现有的语言无法描述的呢。但是ErLang中那种高并发，支持错误恢复的程序结构是在其他语言中能够轻松实现的吗。很多人不是在潜意识中认为ErLang的成功是函数式语言排他性的成功吗，不是认为命令式语言无论如何实现不了ErLang的程序结构的吗。很显然，在命令式语言中是无法直接实现ErLang中的程序结构的，否则它就变成了函数式语言，但是所有发生在ErLang世界中的事实都一样可以发生在命令式语言的世界中。ErLang语言的编译器可以是使用命令式语言实现的，在终极的意义上，语言之间能有什么区别呢？<br /><br />   我说"实际上现在的通用语言也是无法有效承载Domain Specific Structure的", 这还有另一层含义。通用语言设计总是要考虑到内置结构的某种通用性，设计时能够凭依的信息较少，因此不可能直接制造某种复杂的领域相关的结构。而目前已知的通用语言中提供的结构抽象的手段也不够强大（实际上我认为任何语言都不会强大到内置所有结构，也无法提供所有的结构抽象手段）， 相当于是把领域结构问题推给程序员解决。这就如同C语言把内存管理推给程序员解决一样。现在ruby比较流行不就是因为它能够动态处理很多结构问题吗，但是它现在所作的一切就是足够的了吗。难道二十年之后再来看这个语言，不能够发现它存在着巨大的改进空间吗。我们目前在Witrix中通过tpl模板语言，bizflow extends等机制，结合整体框架设计实现了一些与ruby不同的结构构造方法。这些手段都极大的增强了我们面对领域问题时的信心，也确保了我们的领域知识是技术层面上可积累的。但是即使这样，我对程序发展的现状就是满意的吗？难道不存在更加丰富的结构知识等待我们去发现吗？一般人总是习惯接受已经存在的现实，在有限的职业生涯中把它们当作不变的真理，却没有耐心的去思考如何去改变。<br /><br />  我认为很多结构问题不是需要在语言层面得到解决的，而是应该在独立的结构层（平台，框架）进行解决。这意味着没有必要在语言层面直接内置某种特定的结构，内置某种特定的结构抽象手段。这基本类似于说不要把集合论扩大到包含所有的数学关系，请在别的学科分支中进行研究。需要注意的是，我所谓的领域知识不是特定的业务知识，而是从业务知识中可以分析得到的某种更加通用的普适的结构知识，甚至是可以使用数学进行精确描述的。<br /><br />  现代软件发展的时间还很短，与数学和物理学这样深刻的学科相比，它无疑是相对幼稚的，是待成长的，是更加的不完美的。在程序构建的基本问题上并没有抽象出什么可以实际操作的精确规律。这是所谓Pattern在软件业流行的部分原因：我们希望用这种半形式化的方式捕获某种思考的结果。但是软件真的除了基于抽象数学的全局的全称性的证明之外，不能够在局部进行某种更加复杂，更加严谨的分析吗。<br /><br />   我们说结构问题是独立的，这也意味着它和具体的实现语言具有某种意义上的分离性。通过一种语言书写的结构可以在另一种语言中得到表达。我们可以建立语言中立的技术结构。一种所谓的结构在概念上具有某种确定的形态，我们可以脱离具体的语言来理解它。例如我说"面向对象的继承关系从结构观点上看是两个一维集合之间的覆盖关系". 在java中我们可以直接使用语言提供的继承机制，而在C语言中我们就需要建立某种结构体，手动维持所有的指针关联。而在Witrix平台中，我们从继承的结构诠释出发，定义了更加复杂的extends算子，这就需要利用java语言编制特定的parser来实现了。但是显然，在思考的时候我们所有的思维指向是结构本身，而不是任何通用语言的语法。<br /><br />   在物理学中，通过摄动分析我们可以清楚地意识到：同样一个物理现象对应的数学模型可以是众多的，但是在特定的参数区我们会选择某种特定的数学表述，并确定其中的待定参数。<br /><br />   delta函数是物理学家狄拉克引入的，在Schwatz引入分布概念建立广义函数论之前，物理学家们已经使用这一函数工作了很多年。后来Abraham Robinsen利用数理逻辑方法，建立了非标准分析，通过模型论的方法精确定义了无穷小的概念，从更加直接的角度论证了delta的合理性。但是在物理学家看来，这些数学又有什么区别呢？物理学只是按照物理的诠释进行工作，具体的数学只是它可选的工具而已。<br /><br />   物理的真理并不是蕴含在数学中的，它需要我们独立的探索，从与数学不同的观点进行思考，检验，最终我们才能做出真正的发现。广义相对论可以采用Riemman几何进行描述，但是它的物理诠释却是Einstein提出的. 没有人说Riemann或者Hilbert发现了广义相对论。另外一方面，因为Einstein的工作触发了对于微分几何的更加深入的研究，靠着物理直觉的导引，我们将这一数学分支推进到了难以想象的深度。"数学是无法涵盖物理学的". 这不是说最终物理学无法采用数学语言进行描述，而是说在这一发展过程中，所有思想的推动来源于物理学的经验，来源于我们在这个物质世界上所进行的反复验证。不是在一个封闭的小屋中，整天摆弄各种数学符号，我们就能够发明所有的物理公式所对应的数学。实际上，现在学术界普遍承认，没有物理学的推进，很多数学的进展是不可能发生的。<br /><br />   物理系每天都在演算着Feynman路径积分, 但是所有人都知道这是没有什么严格的数学依据的.目前并无法定义路径积分的收敛性,但是所有人对此避而不谈. 只要形式演算合法,物理预测符合实验, 合理性的证明只是数学家们的事情. 在量子场论中所采用的重整化(Renormalization)方法不过是回避无穷大问题的一种形式手段.我们仍然无法在数学层面对所有的演算都给予合理化解释. 在更多的物理分支中工作，你就会发现物理学家的胆子不是一般的大。也许在未来我们能够发现这些物理过程背后数学机制的精确定义, 但也许最终我们也无法找到合适的定义方式. 但这对物理学家来说, 并不是很大的打击.因为指引我们的是物理直觉，是独立于数学的物质世界的意象。<br /><br />   我所想讨论的不是某种终极意义上的可能性，不是绝对概念之间的冲突，而是在物理现实的约束下，我们如何才能有效工作的问题。我已经反复表述了自己的观点: "结构是可抽象的，是具有独立意义的。这就是Witrix所提出的面向结构的设计视角。不是强调对象的所谓业务含义，不是强调某种通用语言（例如ruby）的灵活的语法结构。在这之间存在着厚重的具有物理意义的可以进行结构分析的技术层". 也许有人觉得我说的这是废话, 但是当系统化的执行一种思想的时候,就会揭示出未预料到的可能性. 整个Witrix平台简单的说起来就是"面向结构的级列分析", 但是如何找到合适的技术形式来体现这一思想,却绝对不是一件平凡的事情. "在Witrix中我们实现的代码重用程度和程序整体结构控制能力是超越了目前所有已知的公开技术的。这不是什么哲学，而是我们在残酷的商业竞争中得以生存的资本".http://canonical.javaeye.com/blog/126467 <br /><br />   在我看来，计算机领域充斥着纯数学的深沉遐想和从工程实践而来的轻佻常识，还没有注意到物理学所能带来的不同的同样深刻的视角。我常说，好好学习物理是必要的，因为这个世界远比你想象的要复杂的多。
          <br/>
          <span style="color:red;">
            <a href="http://canonical.javaeye.com/blog/147067#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 09 Dec 2007 16:40:36 +0800</pubDate>
        <link>http://canonical.javaeye.com/blog/147067</link>
        <guid>http://canonical.javaeye.com/blog/147067</guid>
      </item>
      <item>
        <title>关于函数式语言的一些说明</title>
        <author>canonical</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://canonical.javaeye.com">canonical</a>&nbsp;
          链接：<a href="http://canonical.javaeye.com/blog/147065" style="color:red;">http://canonical.javaeye.com/blog/147065</a>&nbsp;
          发表时间: 2007年12月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          我的观点并不是什么具体的程序结构问题不能用函数式语言处理.我所要表述的是这和函数式语言中能否加入结构解决任意复杂问题无关。为什么所有的问题不能在集合论中解决，为什么要有独立的数学学科。物理学所有的定律都使用数学表述，是否意味着物理学的真理蕴含在数学之中。<br />    我说实际上现在的通用语言也是无法有效承载Domain Specific Structure的。其实与以下说法是类似的<br />数学是无法涵盖物理学的，现在的已知的数学工具是无法有效承载尚未得到充分探索的领域的物理的<br /><br />    我说我所关心的不是语言层面的问题。这类似于说不要把所有物理问题都推到数学层面去解决。<br /><br />    我们应该研究独立的结构，应该建立单独的价值观和方法论。不要谈及一个技术进展的时候就说某某语言好，不是一说到DSL的优点就要去抱ruby的大腿。此外，我的观点也不是去做业务分析，不是去如何更好的实现业务到基础技术结构的映射。<br /><br />不是强调对象的所谓业务含义，不是强调某种通用语言（例如ruby）的灵活的语法结构。在这之间存在着厚重的具有物理意义的可以进行结构分析的技术层<br /><br />我想说这个结构层面现在并未得到充分的关注，我们对于结构的问题并不是非常清楚，对程序结构的稳定性更是少有经验。我们在Witrix中做了大量的工作，试图做到如下的图景：<br /><br />永远只写代码片断，而所有的代码片断组合在一起又构成一个可理解的整体<br /><br />对背景不是分解让其成为可见的部分，而是采用追加的，增删的方法对背景结构进行修正，则我们有可能在没有完整背景知识的情况下，独立的理解局部变化的结构。即背景是透明的，知识成为局部的。<br /><br />http://canonical.javaeye.com/blog/126467<br />在Witrix中我们实现的代码重用程度和程序整体结构控制能力是超越了目前所有已知的公开技术的。这不是什么哲学，而是我们在残酷的商业竞争中得以生存的资本。<br /><br />号外：<br />  不要把具体的技术和一种技术思想混为一谈。一种实现总是包容了太多的思想。思想错了，实现对了。实现死了，思想活着。
          <br/>
          <span style="color:red;">
            <a href="http://canonical.javaeye.com/blog/147065#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 09 Dec 2007 16:39:19 +0800</pubDate>
        <link>http://canonical.javaeye.com/blog/147065</link>
        <guid>http://canonical.javaeye.com/blog/147065</guid>
      </item>
      <item>
        <title>关于函数式语言的只言片语</title>
        <author>canonical</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://canonical.javaeye.com">canonical</a>&nbsp;
          链接：<a href="http://canonical.javaeye.com/blog/147064" style="color:red;">http://canonical.javaeye.com/blog/147064</a>&nbsp;
          发表时间: 2007年12月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          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)的东西在计算机理论研究中频频出现。范畴论是从同调代数发展而来的一种较新的代数语言，但它显然也不是可以解决任何问题的灵丹妙药。多一种表达方式当然在某种程度上可以增进我们的理解。但是范畴本身只是研究一种基础结构，它本身并没有承载所有的物理事实，基于它不可能对所有的规律一网打尽。不是明白了范畴，就懂了程序。范畴论是一种基础性的语言，有些人致力于基于范畴论来构建数学的其他分支，取代集合论的地位。将计算的本质重新归结于范畴论是无意义的，它不过是对事实的另一种陈述方式。说“函数式语言是基于范畴”是无意义的，因为这和说“所有现代数学都基于集合论”一样。无法发现新的相互作用关系，所有的概念都只是同义反复。不是一拿起数学，就找到了组织。<br /><br />3. 我对函数式语言并没有什么反对意见。它是非常重要也非常优美的一种技术思想。但是现在一些函数式语言的狂热支持者似乎对函数世界充满了乌托邦式的幻想，一种大一统的世界观让人迷醉，但是它却解决不了现实的问题。所以我说无法认同函数式编程的世界观。作为一种具体的技术工具，问题不在于函数式语言是否体现了计算的本质，而在于它是否向我们提供了称手的兵器。现在我要计算两个小球相互碰撞的问题，我可以操起广义相对论，量子力学啥的开始大干一场，也可以用个牛顿力学小试牛刀，甚至可以只用反射关系摆个等式。但是在绝大多数情况下我们都会说这里面的物理是弹性反射而不是相对论。在理论分析中我们经常使用平面波假设，但只要实际关心的对象不在波包的边缘，没有人会认为平面波不是真实的物理机制。理论物理不是理想物理。在具体的参数设定下，我们只会使用特定的物理学。<br /><br />   对世界的认识并不是非此即彼的。并不是说函数式语言好它就永远都好，要把所有对立面都灭掉。也不是说函数式不好，命令式就必然的好，就必然的能够解决问题。函数式语言的世界观过分单纯而排他，这是我反对的，我同样无法认同面向对象的本体论论调。就像CISC和RISC架构之争一样，最终我们在现实的物理约束下，运行的最好的芯片是两者思想的结合。这是我们面对物理世界的基本态度。<br />   <br />4. 函数式语言中时间是个有趣的概念。命令式语言中因为赋值语句的存在，使得我们可以观测到状态的变化，因此必然要定义时间。而函数式语言是无状态的，可以是无时间概念（对Lazy Caculation的依赖是否体现了深层次上对时间概念的需求？）。有些人认为函数可以看作是相空间中的迁移函数，是与相对论协调的，因而反映了时间的本质等等。相对论主要是解决了物理规律的协变性的问题，在此过程中它使人们认识到了时空之间奇异的对称性。但是广义相对论的表述中时间也是可逆的。真正定义了时间之箭的是热力学第二定律。根据Landauer's principle: 擦除(erase)1比特信息，耗散到环境中的能量至少是k*T*ln2, 或者说熵增至少是k*ln2. 这意味着只要我们对眼前的黑板不停的写了擦，擦了写，就必然无法回到过去。物理世界是复杂的。<br /><br />5. 如果将状态看作是可以附着在某个对象上的标记，显然状态的存在性便于我们识认概念的唯一性。对象还是那个对象，只是状态标记发生了变化。而如果系统中没有状态，则必然产生了一个新的概念。这在很多情况下是不必要的负担。状态的存在使得系统在局部结构上允许出现非常复杂的变化，函数式编程的拥趸们对此多有诟病。但是从另一个方面上说，状态使得我们可以基于局部信息处理很多问题而不需要把它扩大化为一个全局匹配问题。<br /><br />6. 函数构成函数似乎是很完备统一的世界。 但是在物理世界中发生的一切却复杂的多。虽然世界可以还原为原子，但是原子构成分子，分子构成宏观物质时，系统的基本性状发生了本质性的变化，并不再是统一的形式。每一个层面上都会产生独立的结构规律。<br /><br />7. 函数式语言和命令式语言的计算能力相同（可以相差一个任意长度的多项式时间），但是在具体的情形下它们的描述能力是不同的。我所关心的不是语言层面的问题，因为语言本身的能力并不足以解决现实开发中的所有问题。即现实开发中所需要处理的结构问题并不是在语言层面得到充分解决的，这是我们需要做工作的地方。<br /><br />   关于现实中的结构问题，我无意去定义什么万能的描述能力。你可以用微分几何，积分几何，广义变分等等手段去证明圆盘是某种意义下的周长最短的东西，但是这一切对你发明轮子并无本质上的助益。不过可以说说现实中的结构。这里不是要证明某种语言中无法描述这些结构，而是说结构是客观存在的，它并不是要在基础语言层面得到充分解决的。实际上现在的通用语言也是无法有效承载Domain Specific Structure的。<br /><br />A. ErLang大概是目前世界上应用最为深入的函数式语言了。它确实发挥了函数式语言无显式状态变量的优势。但是它对程序构建本质上的帮助更多的来源于无共享的超轻量级进程模型，相当于定制了一般操作系统所提供的基本服务。微软的一个实验性操作系统项目Singularity, 其中也定义了只通过消息传递发生数据关联的超轻量级进程模型，它使用C#的一个扩展语言，额外增加的功能是消息管道上定义的规格状态机，对消息交互的时空模式进行额外的规约。这里对我们真正有价值的是隔离的单元结构。<br /><br />B. AOP是程序结构空间中的定位和组装技术。在Witrix中我们规范化了切点处的状态空间，并对AOP进行了偏置处理.这种结构调整大大提高了AOP的可用性，使得它成为Witrix中的核心技术手段之一。<br /><br />C. 面向对象的继承关系从结构观点上看是两个一维集合之间的覆盖关系。在Witrix中扩展了extends所对应的结构操作，创造了新的结构融合手段。
          <br/>
          <span style="color:red;">
            <a href="http://canonical.javaeye.com/blog/147064#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 09 Dec 2007 16:38:05 +0800</pubDate>
        <link>http://canonical.javaeye.com/blog/147064</link>
        <guid>http://canonical.javaeye.com/blog/147064</guid>
      </item>
      <item>
        <title>关于[面向集合的框架设计]的一些说明</title>
        <author>canonical</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://canonical.javaeye.com">canonical</a>&nbsp;
          链接：<a href="http://canonical.javaeye.com/blog/147063" style="color:red;">http://canonical.javaeye.com/blog/147063</a>&nbsp;
          发表时间: 2007年12月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          我习惯于概念层的推演，而且所阐述的东西多数是我们创造过程中的副产品，与业内常见的观念实际上是有着很大差异的。感觉不明白是因为你没有采用类似的视角，或者还没有独立思考过很多问题。如果你只是从业内已经熟知的概念出发试图理解我所写的内容，显然是不可能的事情。所以我常说know something already known. <br /><br />如果你在编制一个新的应用，存在大量代码可能是<br /><pre name="code" class="java">myFunc(){
  for each x in set
    doSomethingValuable(x);
  return packedResult;
}

myOtherFunc(packedResult){
  for each y in pakedResult
    doSomethingOther(y)
}</pre><br />其实我们真正关心的是循环内部的某个过程，但是我们经常可以观察到它们被某些通用的或者特定的循环（集合遍历）操作所包围着。Witrix的设计方式是强调业务关注点，而把所有的汇总操作尽量抽象完成。比如现在界面上显示一些字段。从抽象的操作上说<br /><pre name="code" class="java">  for each field in dsMeta.viewableFields
    show field.viewer</pre><br />这一过程在平台代码中实现，它是一个通用的集合操作过程。不同的具体应用只是关心具体字段的展现形式，虽然我们必然需要字段集合，但是它不是我们注意力的重心。<br />  如果考虑到字段在界面上展示有一个布局问题，我们所要修改的是集合内部的结构方式：<br /><pre name="code" class="java">  某种结构循环方式（dsMeta.字段组成的布局集合）
    show field.viewer</pre><br />抽离出集合，实际上是在最大限度上分离结构问题和内容问题。     <br />   结构是可抽象的，是具有独立意义的。这就是Witrix所提出的面向结构的设计视角。不是强调对象的所谓业务含义，不是强调某种通用语言（例如ruby）的灵活的语法结构。在这之间存在着厚重的具有物理意义的可以进行结构分析的技术层。<a href="http://canonical.javaeye.com/blog/60758 " target="_blank">http://canonical.javaeye.com/blog/60758 </a> <a href="http://canonical.javaeye.com/blog/126467" target="_blank">http://canonical.javaeye.com/blog/126467</a><br /><br />stream style就是向流中不断追加内容，o.put(y).put(z).put(t)这种方式，看一下jQuery的代码就知道了。<br /><br />SAX的事件驱动方式结合模式匹配能力确实可以直接在局部应用转换逻辑，但是缺乏状态空间的配合，它面对复杂问题时是乏力的。
          <br/>
          <span style="color:red;">
            <a href="http://canonical.javaeye.com/blog/147063#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 09 Dec 2007 16:36:10 +0800</pubDate>
        <link>http://canonical.javaeye.com/blog/147063</link>
        <guid>http://canonical.javaeye.com/blog/147063</guid>
      </item>
      <item>
        <title>哲学与情感</title>
        <author>canonical</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://canonical.javaeye.com">canonical</a>&nbsp;
          链接：<a href="http://canonical.javaeye.com/blog/147053" style="color:red;">http://canonical.javaeye.com/blog/147053</a>&nbsp;
          发表时间: 2007年12月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          因为在认识上物质和意识的两分，传统上哲学便分为唯物和唯心两大流派。唯物主义因为非哲学的缘故在国内占据主导地位。但在哲学上却从未平息过思想的纷争。胡塞尔的现象学试图重新回归形而上学，摒弃物质和意识的二元论，将它们统一到现象这个一元概念之中。我个人的思想基本是唯物主义的（毕竟少年时受过太多官方的教育），但是对我们目前所掌握的所有知识却持有温和的怀疑。<br />   <br />   当一个非哲学家说到“客观规律是客观存在的”的时候，这是以他者的态度，从上帝的第三只眼看世界。但是我们此时此刻却存在于此一世界，因而不可避免的要卷入这滚滚红尘当中。为什么我们在应用分析和综合方法之后，能够通过螺旋式上升的路径逼近终极的真理？这就如同说一个迭代总会收敛，而且必然收敛在正确的结果之上。我们所认识到的一切为什么不能是为了应用方便而不自觉采用的机会主义的产物？所有可能的哲学都是我们在此生有限的存在中所无法证实或证伪的。当我开始质疑为什么我们不能是离(我们在有限时空范围内认为的)本质愈近，离真实愈远的时候，这不过是用一种无意义置换了另一种无意义，但是一个人的