<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>冒号空间 &#187; OOP</title>
	<atom:link href="http://blog.zhenghui.org/tag/oop/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.zhenghui.org</link>
	<description>自然、人类、机器</description>
	<lastBuildDate>Fri, 16 Jul 2010 18:33:48 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>冒号课堂§3.3：切面范式</title>
		<link>http://blog.zhenghui.org/2009/09/10/colon-class-3_3/</link>
		<comments>http://blog.zhenghui.org/2009/09/10/colon-class-3_3/#comments</comments>
		<pubDate>Thu, 10 Sep 2009 12:48:14 +0000</pubDate>
		<dc:creator>hui</dc:creator>
				<category><![CDATA[冒号课堂]]></category>
		<category><![CDATA[advice]]></category>
		<category><![CDATA[AOP]]></category>
		<category><![CDATA[Aspect]]></category>
		<category><![CDATA[DRY]]></category>
		<category><![CDATA[join point]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[pointcut]]></category>
		<category><![CDATA[SoC]]></category>
		<category><![CDATA[编程范式]]></category>

		<guid isPermaLink="false">http://blog.zhenghui.org/?p=385</guid>
		<description><![CDATA[<b>切面范式</b>——多角度看问题（<em>切面式编程简谈</em>）<br/>
•	从宏观角度看，太阳底下没有新鲜事——AOP无非是SoC原理和DRY原则的一种应用<br/>
•	从微观角度看，太阳每天都是新的——AOP虽自OOP的土壤中长出，却脱离藩篱自成一体<br/>
•	抽象是前提，分解是方式，模块化是结果<br/>
•	在常人眼中复杂的牛体，庖丁经过抽象，已目无全牛，及至提刀分解，自是游刃有余。待牛如土委地，模块化即成<br/>
•	两条（抽象与分解的原则）：单一化，正交化。每个模块职责明确专一，模块之间相互独立，即高内聚低耦合<br/>
•	对程序员来说，英语也是一门计算机语言，而且是必修的语言<br/>
•	OOP只能沿着继承树的纵向方向重用，而AOP则弥补了OOP的不足，可以在横向方向重用<br/>
•	如果一个程序是一个管道系统，AOP就是在管道上钻一些孔，在每个孔中注入新的代码流]]></description>
			<content:encoded><![CDATA[<h1 style="text-align: center"><span style="font-family: 宋体">冒号课堂</span></h1>
<strong><span style="font-size: 13pt; font-family: 宋体">第三课 常用范式(3)</span></strong>

<!-- below comes from generated html -->
<head><link rel="stylesheet" href="http://blog.zhenghui.org/css/colonclass.css" type="text/css"></head>

<div lang="zh-CN" class="article" title="切面范式"><div class="titlepage"><div><div><h1 class="title"><a name="id523744"></a>3.3 切面范式——多角度看问题</h1></div><div><div class="author"><h3 class="author">郑晖</h3></div></div><div><div class="abstract" title="摘要"><p class="title"><b>摘要</b></p><p>切面式编程简谈</p></div></div></div><hr /></div><div class="toc"><p><b>目录</b></p><dl><dt><span class="section"><a href="#preview">！预览</a></span></dt><dt><span class="section"><a href="#question">？提问</a></span></dt><dt><span class="section"><a href="#explaination">：讲解</a></span></dt><dt><span class="section"><a href="#note">，插语</a></span></dt><dt><span class="section"><a href="#summary">。总结</a></span></dt><dt><span class="section"><a href="#reference">“”参考</a></span></dt></dl></div><div class="epigraph"><div class="literallayout"><p>横看成岭侧成峰</p></div><div class="attribution"><span>—<span class="attribution">《苏轼•题西林壁》</span></span></div></div><div class="section" title="！预览"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="preview"></a>！预览</h2></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>
                    从宏观角度看，太阳底下没有新鲜事——AOP无非是SoC原理和DRY原则的一种应用
                </p></li><li class="listitem"><p>
                    从微观角度看，太阳每天都是新的——AOP虽自OOP的土壤中长出，却脱离藩篱自成一体
                </p></li><li class="listitem"><p>
                    抽象是前提，分解是方式，模块化是结果
                </p></li><li class="listitem"><p>
                    在常人眼中复杂的牛体，庖丁经过抽象，已目无全牛，及至提刀分解，自是游刃有余。待牛如土委地，模块化即成
                </p></li><li class="listitem"><p>
                    两条（抽象与分解的原则）：单一化，正交化。每个模块职责明确专一，模块之间相互独立，即高内聚低耦合
                </p></li><li class="listitem"><p>
                    对程序员来说，英语也是一门计算机语言，而且是必修的语言
                </p></li><li class="listitem"><p>
                    OOP只能沿着继承树的纵向方向重用，而AOP则弥补了OOP的不足，可以在横向方向重用
                </p></li><li class="listitem"><p>
                    如果一个程序是一个管道系统，AOP就是在管道上钻一些孔，在每个孔中注入新的代码流
                </p></li></ul></div></div><div class="section" title="？提问"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="question"></a>？提问</h2></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>什么是SoC和DRY？</p></li><li class="listitem"><p>如何有效地避免紊乱、松散、重复的代码？</p></li><li class="listitem"><p>抽象与分解的原则是什么？</p></li><li class="listitem"><p>什么是横切关注点？</p></li><li class="listitem"><p>接入点与切入点有何区别？</p></li><li class="listitem"><p>什么是编织？有哪些不同的编织方法？</p></li><li class="listitem"><p>实施AOP有哪些步骤？</p></li><li class="listitem"><p>为什么说AOP是OOP的一种补充？</p></li><li class="listitem"><p>为什么提倡尽可能地阅读原文的书籍和资料？</p></li></ul></div></div><div class="section" title="：讲解"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="explaination"></a>：讲解</h2></div></div></div><p>
            课间休息刚一结束，引号便重开话题：“OOP方兴未艾，AOP又开始崭露头角。AOP算是OOP的一种补充、一种分支还是一种超越？”
        </p><p>
            叹号故作捶胸顿足状：“OOP还没有完全吃透，又来了个什么AOP。”
        </p><p>
            “不同的人对新生事物采取不同的态度。”冒号王顾左右而言他，“追星族倾向于盲目追捧，唯恐落伍，他们信奉新潮的、流行的就是好的；守旧派倾向于本能抗拒，回避求新，他们认为经典的、传统的才是好的。”
        </p><p>
            引号和叹号互视一眼，不情愿地戴上了老冒派发的帽子。
        </p><p>
            冒号续道：“从宏观角度看，太阳底下没有新鲜事——AOP无非是SoC原理和DRY原则的一种应用；从微观角度看，太阳每天都是新的——AOP虽自OOP的土壤中长出，却脱离藩篱自成一体，并且嫁接到非OOP的领地，不仅在纯过程式语言、函数式语言、甚至逻辑式语言中得到发展，而且本身也具备了一定的声明式语言特征，成为一种新的软件模块化方式。”
        </p><p>
            问号举手：“什么是SoC和DRY？”
        </p><p>
            引号代答：“SoC就是Separation of Concerns，即关注点分离；DRY是Don’t Repeat Yourself，即尽量减少重复代码。”
        </p><p>
            “答案正确，加十分！”冒号戏赞道，“不良代码通常有两种病征：一是结构混乱，或聚至纠缠打结、或散至七零八落；二是代码重复，叠床架屋、臃肿不堪。治疗此类病症一个有效的方法是<span class="strong"><strong>抽象与分解</strong></span>：从问题中抽象出一些关注点，再以此为基础进行分解。分解后的子问题主题鲜明且独立完备，既不会牵一发而动全身，也不会四分五裂、支离破碎。同时具有相同特征的部分可以象代数中的公因子一样提取出来，提高了重用性，减少了重复性。”
        </p><p>
            句号醒悟道：“这不就是模块化吗？”
        </p><p>
            “准确地说，抽象是前提，分解是方式，模块化是结果。”冒号很讲究精确，“大家记得庖丁解牛的故事吧？在常人眼中复杂的牛体，庖丁经过<span class="emphasis"><em>抽象</em></span>，已目无全牛，及至提刀<span class="emphasis"><em>分解</em></span>，自是游刃有余。待牛如土委地，<span class="emphasis"><em>模块化</em></span>即成。”
        </p><p>
            句号举一反三：“前面提到的编程范式的基本思想大多不也如此？将程序分别抽象分解为过程、函数、断言、对象和进程，就依次成为过程式、函数式、逻辑式、对象式和并发式。至于泛型式——”
        </p><p>
            句号讲不下去了。
        </p><p>
            “泛型式虽未引入新类型的模块，其核心也是抽象出算法后与数据分解。”冒号为其解围，“以此类推，切面式的AOP将程序抽象分解为切面。”
        </p><p>
            问号提问：“抽象与分解的原则是什么？”
        </p><p>
            冒号作了个V字：“两条：单一化，正交化。每个模块职责明确专一，模块之间相互独立，即<span class="emphasis"><em>高内聚低耦合</em></span>（high cohesion &amp; low coupling）<a class="link" href="#note1"><sup>[1]</sup></a>。此原则相当普适，是分析复杂事物的一种基本方法，在数学和物理中应用得尤为广泛，如质因式分解、正交分解、谱分解等等。”
        </p><p>
            逗号调皮地抬杠：“为什么称为正交化呢？斜交化不行吗？”
        </p><p>
            冒号呵呵一笑：“在数学中互为正交的两个向量在彼此方向上投影为零，意味着彼此独立、互不影响，斜交可不行。”
        </p><p>
            逗号吐了吐舌头。
        </p><p>
            “诚如前述，AOP以切面为模块。”冒号返回主题，“切面Aspect常直译为‘方面’，但它描述的是<span class="term">横切关注点</span>（cross-cutting concerns），故‘切面’更准确生动，而‘方面’则失之空泛呆板。何谓横切关注点？顾名思义，乃是<span class="strong"><strong>与程序的纵向主流执行方向横向正交的关注焦点</strong></span>。不妨回顾一下，无论是过程式的函数，还是对象式的方法，都包含了完整的执行代码。但有些代码<span class="emphasis"><em>横跨</em></span>多个模块，以片断的形式散落在各处，虽具有相似的逻辑，却无法用传统的方式提炼成模块，难以实现SoC与DRY。典型的例子如：在调用某些对象的方法、读写某些对象的域、抛出某些异常等等前后，需要用到统一的业务逻辑，诸如日志输出、代码跟踪、性能监控、异常处理、安全检查、事务管理等等。为解决此类问题，AOP应运而生。它将每类横切关注点封装到单独的Aspect模块中，将程序中的一些执行点与相应的代码绑定起来。单个的执行点称为<span class="term">接入点</span>（join point），例如：调用某个对象的方法前后；符合预先指定条件的接入点集合称为<span class="term">切入点</span>（pointcut），例如：所有以set为命名开头的方法；每段绑定的代码称为一个<span class="term">建议</span>（advice）。”
        </p><p>
            问号有点疑问：“接入点与切入点有何区别？”
        </p><p>
            冒号释疑：“望文生义，接入处是点，切入处是面，面由点组成。advice<span class="emphasis"><em>定义于</em></span>切入点上，<span class="emphasis"><em>执行于</em></span>接入点处。换言之，共享一段附加代码的接入点组成了一个切入点。切入点一般用条件表达式来描述，不仅有广泛性，还有<span class="emphasis"><em>预见性</em></span>——以后新增的代码如果含有满足切入点条件的接入点，advice中的代码便自动附着其上。这是AOP的威力所在，但有时也是麻烦所在。”
        </p><p>
            引号很较真：“好像一些书上把join point译作连接点，把advice译作通知。”
        </p><p>
            “误导，完全是误导！”冒号有些痛心疾首，“何谓join point？是advice中额外代码接入之处，join显为‘参加’、‘加入’之意。如果说翻作‘连接’ 只是因缺乏动感和方向性而不够贴切的话，将advice译作‘通知’则近乎荒谬了。advice是在原有程序流程中加入的额外流程，可理解为建议采取的措施，而‘通知’强调的是一种信息，难道是程序运行到join point的信息？抑或采取某种行动的信息？简直不知所云。”
        </p><p>
            顿了一会，冒号仍意犹未尽：“英文好的技术不好，技术好的英文不好，两者都好的不屑去翻译，导致市面上的译书虽汗牛充栋，然佳作寥寥。这里奉劝各位，如果真想成为优秀的程序员，一定要尽可能地读原文的书籍、文章和文档。事实上，凡是科学和艺术方面的专业人员，要想专业水平上一层台阶，都应读该专业权威经典的<span class="emphasis"><em>原文</em></span>。要知道，语言之间的天堑原本难以弥合，译者的专业水准、语言功底和严谨程度更是参差不齐。纵使万事俱备，一年半载后的译书便如隔夜的饭菜，虽刚出炉，已然不新鲜了。”
        </p><p>
            逗号抱怨：“英文虽读得懂，但太慢、太费劲了。”
        </p><p>
            “多读，读多了就习惯了。”冒号鼓励着，“对程序员来说，<span class="emphasis"><em>英语也是一门计算机语言</em></span>，而且是必修的语言。”
        </p><p>
            课堂上有这么一个规律，越是题外的话大家讨论得越欢。下面果然开始嘈杂起来，冒号也乐得乘机歇歇嘴。
        </p><p>
            等大伙渐渐把视线重新聚焦到讲台上，冒号才继续讲课：“从软件重用的角度看，可以这么理解AOP与OOP的关系：OOP只能沿着继承树的纵向方向重用，而AOP则弥补了OOP的不足，可以在横向方向重用。这算是回答了引号开始提出的问题：AOP不是OOP的分支，也不能说是超越了OOP，而是OOP的一种补充——尽管AOP并不局限用于OOP语言。”
        </p><p>
            问号的求知欲很强：“AOP实现的机理是什么？”
        </p><p>
            冒号回答：“如果一个程序是一个管道系统，AOP就是在管道上钻一些孔，在每个孔中注入新的代码流。因此AOP实现的关键是将advice的代码嵌入到主体程序之中，术语称<span class="term">编织</span>（weaving）。这是很自然的——将问题分解之后再合成，问题才得以还原。编织可分两种：一种是静态编织，通过修改源码或字节码（bytecode）在编译期（compile-time）、后编译期（post-compile）或加载期（load-time）嵌入代码——请注意，这里涉及到刚才提到的元编程和产生式编程；另一种是动态编织，通过代理（proxy）等技术在运行期（run-time）实现嵌入。具体的工具包括一些扩展性语言如AspectJ、AspectC++、Aspect#等和一些框架如AspectWerkz、Spring、Jboss AOP等。”
        </p><p>
            叹号搔着头：“听起来怪复杂的。”
        </p><p>
            引号倒不在乎：“这些机理是AOP的实现者需要操心的，使用者只需关心AOP是否好用，性能如何等等。”
        </p><p>
            “为了让你们有更直观的印象，我们借用光学原理来类比。”冒号用幻灯片展示了一幅图——
        </p><div class="figure"><a name="id524045"></a><p class="title"><b>图3-3. 切面式编程</b></p><div class="figure-contents"><div class="mediaobject"><img src="http://blog.zhenghui.org/img/colonclass/figure3-3.jpg" alt="切面式编程"></div></div></div><br class="figure-break"><p>
            “众所周知，白光经过三棱镜的折射而分解为七色光，是谓光的色散。再经过一个倒置的三棱镜，七色光又重新会聚为白光。”冒号简述中学的物理知识，“如果把一个复杂的系统看作<span class="emphasis"><em>复合色</em></span>的白光，经过第一个三棱镜——关注分离器，系统被分解为不同的切面，如同不同的<span class="emphasis"><em>单色</em></span>的彩光。这些切面经过第二个三棱镜——编织器，再度合成为原系统。”
        </p><p>
            叹号脸上的迷惘之色渐去：“这下清楚多了。”
        </p><p>
            句号积极发言：“从中看出，AOP的实施分三步：切面分解、切面实现和切面合成。其中第一步是在设计者的头脑中进行的，第三步是通过AOP的工具实现的，真正需要程序员编码的部分在第二步，即分别实现各切面的advice。”
        </p><p>
            冒号赶紧补漏：“你好像忽略了切面的另一要素pointcut，如果程序员不指明advice挂靠的切入点，系统如何知道该何时何处调用他编写的执行代码呢？”
        </p><p>
            句号的嘴张成O状：“是哦，我怎么把这茬给忘了？”
        </p><p>
            在AOP的议题结束前，冒号不忘指出：“与OOP一样，AOP在带来便利的同时，也增加了一定的复杂度和性能损耗。它们更适用于大中型程序，用在小型程序中则不啻牛刀杀鸡。”
        </p></div><div class="section" title="，插语"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="note"></a>，插语</h2></div></div></div><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p><a name="note1"></a>
                    耦合（coupling）用来衡量模块之间的依赖程度，内聚（cohesion）用来衡量模块内在的关联强度。它们常用来作为软件质量的评判标准，耦合度宜低，内聚度宜高。
                </p></li></ol></div></div><div class="section" title="。总结"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="summary"></a>。总结</h2></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>
                    SoC是Separation of concerns的缩写，指应将关注点分离；DRY是Don’t Repeat Yourself的缩写，指应尽量减少重复代码。
                </p></li><li class="listitem"><p>
                    抽象与分解是治愈代码紊乱、松散、重复的良方。
                </p></li><li class="listitem"><p>
                    抽象与分解的原则是单一化和正交化，以保障软件系统符合“高内聚、低耦合”的要求。
                </p></li><li class="listitem"><p>
                    横切关注点指与程序的纵向主流执行方向横向正交的关注焦点。
                </p></li><li class="listitem"><p>
                    接入点是附加行为——建议（advice）的执行点，切入点（pointcut）是指定的接入点（join point）集合，这些接入点共享一段插入代码。切入点与建议组成了切面（aspect），是模块化的横切关注点。
                </p></li><li class="listitem"><p>
                    编织是将附加的切面逻辑嵌入到主体应用程序之中的过程。编织分静态编织和动态编织两种。静态编织在编译期、后编译期或加载期嵌入代码，动态编织则在运行期嵌入。
                </p></li><li class="listitem"><p>
                    AOP的实施分三步：切面分解、切面实现和切面合成。
                </p></li><li class="listitem"><p>
                    OOP只能沿继承树的纵向方向重用，AOP可以沿横向方向重用。
                </p></li><li class="listitem"><p>
                    语言之间的天然差别、译者的专业水准、语言功底和严谨程度以及时间上的滞后决定了阅读原文书籍和资料的必要性。
                </p></li></ul></div></div><div class="section" title="“”参考"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="reference"></a>“”参考</h2></div></div></div><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
                    Wikipedia．Aspect-oriented programming．<a class="link" href="http://en.wikipedia.org/wiki/Aspect-oriented_programming" target="_top">http://en.wikipedia.org/wiki/Aspect-oriented_programming</a>
                </p></li><li class="listitem"><p>
                    Ramnivas Laddad ．I want my AOP! ．<a class="link" href="http://www.javaworld.com/javaworld/jw-01-2002/jw-0118-aspect.html" target="_top">http://www.javaworld.com/javaworld/jw-01-2002/jw-0118-aspect.html</a>
                </p></li></ol></div></div></div><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fblog.zhenghui.org%2F2009%2F09%2F10%2Fcolon-class-3_3%2F&amp;linkname=%E5%86%92%E5%8F%B7%E8%AF%BE%E5%A0%82%C2%A73.3%EF%BC%9A%E5%88%87%E9%9D%A2%E8%8C%83%E5%BC%8F">分享/保存</a>]]></content:encoded>
			<wfw:commentRss>http://blog.zhenghui.org/2009/09/10/colon-class-3_3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>冒号课堂§2.3：对象范式</title>
		<link>http://blog.zhenghui.org/2009/09/06/colon-class-2_3/</link>
		<comments>http://blog.zhenghui.org/2009/09/06/colon-class-2_3/#comments</comments>
		<pubDate>Sat, 05 Sep 2009 17:26:50 +0000</pubDate>
		<dc:creator>hui</dc:creator>
				<category><![CDATA[冒号课堂]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[易用性]]></category>
		<category><![CDATA[编程范式]]></category>
		<category><![CDATA[过程式编程]]></category>
		<category><![CDATA[重用性]]></category>

		<guid isPermaLink="false">http://blog.zhenghui.org/?p=353</guid>
		<description><![CDATA[<b>对象范式</b>——民主制社会的编程法则（<em>对象式编程简谈</em>）<br/>
•	如果把整个流程看作一颗倒长的大树，过程式编程自树根向下，逐渐分支，直到每片树叶，类似数学证明中的分析法，即执果索因的逆推法；OOP则从每片树叶开始，逐渐合并，直到树根，类似数学证明中的综合法，即执因索果的正推法<br/>
•	与其说OOP更具重用性，不如说更具易用性<br/>
•	函数是被动的实体，对象是主动的实体<br/>
•	过程式程序的世界是君主制的；OO程序的世界是民主制的<br/>
•	封装使得公民拥有个体身份，继承使得公民拥有家庭身份，多态使得公民拥有社会身份]]></description>
			<content:encoded><![CDATA[<h1 style="text-align: center"><span style="font-family: 宋体">冒号课堂</span></h1>
<strong><span style="font-size: 13pt; font-family: 宋体">第二课 重要范式(3)</span></strong>

<!-- below comes from generated html -->
<head><link rel="stylesheet" href="http://blog.zhenghui.org/css/colonclass.css" type="text/css"></head>
 
<div lang="zh-CN" class="article" title="对象范式"><div class="titlepage"><div><div><h1 class="title"><a name="id622049"></a>2.3 对象范式——民主制社会的编程法则</h1></div><div><div class="author"><h3 class="author">郑晖</h3></div></div><div><div class="abstract" title="摘要"><p class="title"><b>摘要</b></p><p>对象式编程简谈</p></div></div></div><hr /></div><div class="toc"><p><b>目录</b></p><dl><dt><span class="section"><a href="#preview">！预览</a></span></dt><dt><span class="section"><a href="#question">？提问</a></span></dt><dt><span class="section"><a href="#explaination">：讲解</a></span></dt><dt><span class="section"><a href="#note">，插语</a></span></dt><dt><span class="section"><a href="#summary">。总结</a></span></dt><dt><span class="section"><a href="#reference">“”参考</a></span></dt></dl></div><div class="epigraph"><div class="literallayout"><p>民为贵，社稷次之，君为轻</p></div><div class="attribution"><span>—<span class="attribution">《孟子•尽心下》</span></span></div></div><div class="section" title="！预览"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="preview"></a>！预览</h2></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>
                    如果把整个流程看作一颗倒长的大树，过程式编程自树根向下，逐渐分支，直到每片树叶，类似数学证明中的分析法，即执果索因的逆推法；OOP则从每片树叶开始，逐渐合并，直到树根，类似数学证明中的综合法，即执因索果的正推法
                </p></li><li class="listitem"><p>
                    与其说OOP更具重用性，不如说更具易用性
                </p></li><li class="listitem"><p>
                    函数是被动的实体，对象是主动的实体
                </p></li><li class="listitem"><p>
                    过程式程序的世界是君主制的；OO程序的世界是民主制的
                </p></li><li class="listitem"><p>
                    封装使得公民拥有个体身份，继承使得公民拥有家庭身份，多态使得公民拥有社会身份
                </p></li></ul></div></div><div class="section" title="？提问"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="question"></a>？提问</h2></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>OOP是一种特殊的命令式吗？</p></li><li class="listitem"><p>OOP的基本思想是什么？</p></li><li class="listitem"><p>OOP到底好在哪里？</p></li><li class="listitem"><p>OOP将要一统天下吗？</p></li><li class="listitem"><p>过程式编程与OOP在设计理念上有什么差异？</p></li></ul></div></div><div class="section" title="：讲解"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="explaination"></a>：讲解</h2></div></div></div><p>
            短憩之后，引号迫不及待地问：“面向对象的范式应该是一种特殊的命令式吧？” 
        </p><p>
            “面向对象？”冒号咕哝着，“姑且称之为OO或对象式吧，既不标新立异，也不以讹传讹。在回答你的问题之前，请先回答我的：什么是OOP？”
        </p><p>
            引号应答如流：“<span class="term">OOP</span>（Object-Oriented programming）是一种计算机编程模式，它以对象作为问题空间的基本元素，利用对象和对象间的相互作用来设计程序。所谓对象，是实际问题中实体的抽象，具有一定的属性和功能。OOP的三个基本特征是：封装性、继承性和多态性。所谓封装性就是——”
        </p><p>
            冒号作了个暂停的手势：“OOP的的基本特征相信大家早就耳熟能详了，那么根据你刚才的定义，能否得出OOP一定是命令式的结论？”
        </p><p>
            引号歪头想了一阵，答道：“从定义上好像并不能得出，难道C++、Java、C#不是命令式的吗？”
        </p><p>
            冒号回答：“当然是，但这不妨碍Clos成为OO版的Lisp，而Prolog也有不少融入OO特征的扩充，如Visual Prolog、Logtalk等。OOP虽然是在命令式的基础上发展起来的，但其核心思想可泛化为：以数据为中心组织逻辑，将系统视为相互作用的对象集合，并利用继承与多态来增强可维护性、可扩展性和可重用性。这种思想也能应用到函数式和逻辑式中，只不过对象的方法从命令式中的过程分别换成函数式中的函数和逻辑式中的断言罢了。大致说来，命令式、函数式和逻辑式互相平行，而OOP与它们正交。”
        </p><p>
            问号提问：“OOP已经成为一种潮流，上堂课列举的十二种流行语言中只有C不是OO的，这是否意味着OOP将要一统天下？”
        </p><p>
            “严格说来，VB（VB.NET除外）和JavaScript也不是OO的，只是<span class="term">基于对象的</span>（Object Based）<a class="link" href="#note1"><sup>[1]</sup></a>。” 冒号纠正道，“至于OOP是否会一统天下，答案是否定的。首先，与能独当一面的三类最基本的范式不同，纯粹的OOP是不存在的<a class="link" href="#note2"><sup>[2]</sup></a>，必须结合其他范式；其次，世上没有包治百病的万灵丹方，OOP也不例外。用软件业的行话来说：没有银弹（No silver bullet）<a class="link" href="#note3"><sup>[3]</sup></a>。OOP最适用于大型复杂的、交互式的、尤其是与现实世界密切相关的系统，但在小型应用、数学计算、符号处理等方面并无优势。需要指出的是，语言和范式的流行，与大公司支持和商业推动是密切相关的。有人说OOP其实是MOP（Money-Oriented Programming），即以金钱为导向的。虽有过激之嫌，但有经验的股民都知道，有主力运作的股票总是涨得快一些的。当然OOP能流行，自有独到之处，谁能说说它到底好在哪里？”
        </p><p>
            逗号抢答：“OOP能提高软件的可维护性、可扩展性和可重用性。”
        </p><p>
            冒号反问：“为什么过程式编程的可维护性、可扩展性和可重用性就差呢？”
        </p><p>
            感到来者不善，逗号有点发虚：“因为OOP具有信息隐藏、继承和多态的特征。”
        </p><p>
            冒号并不买帐：“首先，将可维护性、可扩展性和可重用性与OOP划等号，是只见树木，不见森林——那是所有范式和语言的共同目标。其次，以C语言为例，信息隐藏可用关键字static来实现；继承可用<span class="term">合成</span>（composition）来代替；多态可以利用函数指针来实现。更何况这些只是手段而非目的，只要设计合理，C程序同样具有可维护性、可扩展性和可重用性，性能效率还更优越。即使在OOP日益风行的今天，C的占有率始终稳踞前列，许多大型复杂软件如操作系统、数据库等仍以C为主，这足以证明其仍堪大用。”
        </p><p>
            见逗号有些理屈词穷，冒号语气放缓：“请不要误解，我并非OOP的反对者，相反今后还要重点讨论它。但我希望大家少一点照本宣科和人云亦云，多一点独立思考，甚至不妨标新立异。”
        </p><p>
            稍作停顿，冒号继续发问：“过程式编程与OOP在设计理念上有什么区别？”
        </p><p>
             “过程式编程的理念是以过程为中心，自顶向下、逐步求精<a class="link" href="#note4"><sup>[4]</sup></a>。”引号一出口就自感有些“照本宣科”，见冒号正用鼓励的目光看着他，这才继续说下去，“OOP则正相反，以数据为中心，自底向上、逐步合并。”
        </p><p>
            冒号首肯道：“如果把整个流程看作一颗倒长的大树，过程式编程自树根向下，逐渐分支，直到每片树叶，类似数学证明中的分析法，即<span class="emphasis"><em>执果索因</em></span>的逆推法；OOP则从每片树叶开始，逐渐合并，直到树根，类似数学证明中的综合法，即<span class="emphasis"><em>执因索果</em></span>的正推法。”
        </p><p>
            句号心领神会：“倘若把树根看成主函数，离树根越近，离用户需求也越近。如果用过程式编程，由于是逆推法，树干改变容易导致树枝相应改变，因此一旦用户需求发生变化，可能会从树根波及到树枝甚至树叶，维护起来殊为不易。相反OOP从树叶开始设计，离用户需求较远，抽象程度较高，受波及的程度较小，因此更易维护和重用。”
        </p><p>
            冒号拊掌赞道：“好极了！”
        </p><p>
            问号不解：“您刚才不还说C程序同样具有可重用性吗？”
        </p><p>
            冒号微微一笑：“数学中分析法与综合法往往是结合起来使用的，过程式编程与OOP也是如此，只不过各有偏重罢了。句号的一番话虽不无道理，但也授OOP的反对者以口实：OOP鼓吹的可重用性来自‘自底向上’的设计模式，而这种模式并非OOP的专利。其实软件设计的最重要的并不是编程语言，甚至也不是编程范式，而是<span class="strong"><strong>抽象思维</strong></span>。关于这一点，我们今后还会详细阐述。”
        </p><p>
            叹号不甘寂寞，插言道：“OOP以对象为基本模块单位，而对象是现实中具体事物和抽象概念的模拟，这使得编程设计更自然更人性化。”
        </p><p>
            “深合吾意！”冒号挥动着右手，“尽管OOP最大的卖点是其高度的可重用性，相比其他范式却并不具明显优势。但它更接近人类的认知模式，编程者更容易也更乐于用这种方式编程，这是它深入人心的一个重要原因。比较一下两种用法：<code class="code">牛.吃（草）</code>与<code class="code">吃（牛，草）</code>，哪种更接近人类思维？”
        </p><p>
            有人在底下嘀咕：“如果把牛换成狗，那么一个是狗吃屎，一个是吃狗屎。”
        </p><p>
            全班捧腹。
        </p><p>
            冒号也忍不住笑了：“OOP人性化的另一表现是其接口简洁易记。看看Win32 API、Unix API等之类操作系统接口或OCI之类的数据库接口，函数的参数动辄七八个乃至上十个，函数名和数据结构成员也多冗长晦涩，既难记又易错。相比之下，相应的Java的API显然平易近人得多。”
        </p><p>
            问号刨根问底：“为什么C的API不能象Java的那么简洁呢？”
        </p><p>
            冒号释疑：“单纯这么比较其实对C并不公平，因为Java的API虽然简洁易用，但功能上与相应C的API并不等同，换句话说，Java把<span class="emphasis"><em>接口粗粒度化</em></span>了。”
        </p><p>
             “接口粗粒度化？”引号质疑道，“就是把一些函数包装起来吧？我们也可以用C将操作系统、数据库之类的API再包装一下。”
        </p><p>
            “事实上许多软件公司都曾这样做过。”冒号颔首作答，“但C函数不像Java对象，本身没有状态，只有依靠参数传递或外部变量来维持相关函数之间的联系，包装后的接口肯定不如Java简洁，但应该比Java高效。说白了，OOP就是将相关的函数用数据粘合，重新包装后再贴上对象的标签。从这种角度上看，<span class="strong"><strong>与其说OOP更具重用性，不如说更具易用性</strong></span>。”
        </p><p>
            叹号狐疑道：“OOP并不更具重用性？这可是它的金字招牌啊！”
        </p><p>
            冒号冷哼一声：“不要被金字招牌晃晕了眼，我来问你：是收音机、电视机之类的电器产品更具重用性呢，还是电阻、电容之类的电器元件更具重用性？”
        </p><p>
             “当然是电器元件啦。”叹号冲口而出。
        </p><p>
            冒号因势利导：“每个电器元件具备单一的功能，正如过程式中的函数；每个电器产品是对多个相互关联的电器元件的封装，正如OOP中的对象。同样的电器元件可用于不同的电器产品，具有高度的可重用性，而电器产品重用性低，但易用性高。<a class="link" href="#note5"><sup>[5]</sup></a>”
        </p><p>
            众人犹自将信将疑。
        </p><p>
            “对一个没有独立思考习惯的人来讲，与其说他认同一个理论，倒不如说他认同该理论倡导者的权威。而在他仰视权威的同时，也把自己的思想交托给了权威。”冒号颇具犬儒之风，“你们可以怀疑我的观点，但绝不可放弃自己的思考。请注意，这就是我在第一堂课提到的精神——<span class="strong"><strong>批判精神</strong></span>。”
        </p><p>
            冒号这时停了下来，与在座的每位逐一对视。他仿佛想通过目光把这种精神注入到每个人的身上，就像武侠小说中通过手掌将内功传输给他人一样。并不是每个人都能理解冒号的用心，但都或多或少地感受到一种异样的气氛。
        </p><p>
            “关于OOP今天就谈到这里。”冒号恢复了常态，“请不要奇怪为何如此流行的编程范式我却一带而过，那是因为你们对它相对比较熟悉，而我们这一轮只是在作热身运动，以后再作专项训练。在结束之前，我们引进一个新视点：过程式编程的模块以函数为单位，OOP的模块以对象为单位，二者的区别是：函数是被动的实体，对象是主动的实体。<span class="strong"><strong>过程式程序的世界是君主制的</strong></span>，主函数是国王，其他函数是臣民，等级分明，所有臣民在听命于上级的同时也对下级发号施令，最终为国王服务；<span class="strong"><strong>OO程序的世界是民主制的</strong></span>，所有对象都是独立而平等的公民，有权利保护自己的财产和隐私并向他人寻求服务，同时有义务为他人提供承诺的服务，公民之间通过信息交流来协作完成各种任务。更进一步地，<span class="strong"><strong>封装使得公民拥有个体身份</strong></span>，需要对自己负责；<span class="strong"><strong>继承使得公民拥有家庭身份</strong></span>，需要对家庭负责；<span class="strong"><strong>多态使得公民拥有社会身份</strong></span>，需要对社会负责。欲知个中玄机，且听我日后慢慢道来。”
        </p><p>
            众人顿觉耳目为之一新。
        </p></div><div class="section" title="，插语"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="note"></a>，插语</h2></div></div></div><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p><a name="note1"></a>
                    所谓基于对象的，有两种不同的涵义。一种指“限制版”的OOP，即具备对象概念，但不具备OOP的一些其他特征，如继承或多态等。Visual Basic（不包括Visual Basic .NET）正属于此类。另一种指基于原型的（prototype-based），或者说基于实例的（instance-based），而不像通常OOP是基于类的（class-based）。JavaScript、NewtonScript、MOO等语言即属此类。
                </p></li><li class="listitem"><p><a name="note2"></a>
                    这里所谓“纯粹的OOP”并非指一般意义上的“pure OOP”（即所谓的“一切都是对象”），而指单纯的、不含其他范式的OOP。
                </p></li><li class="listitem"><p><a name="note3"></a>
                    出自Fred Brooks的著名文章《no silver bullet》（参见文献【2】）。他认为没有一项技术或管理方法的发展能保证，在十年内让软件的生产力、可靠性或简洁性等方面提高一个数量级。常用来泛指没有一项软件技术或方法是万能的。
                </p></li><li class="listitem"><p><a name="note4"></a>
                    更准确地说，这是前文提到的结构化编程思想。
                </p></li><li class="listitem"><p><a name="note5"></a>
                    当然，也可把电器元件看作对象，只不过颗粒度比电器产品更小而已。但函数的颗粒度的确普遍比对象的小，故文中论点依然成立。
                </p></li></ol></div></div><div class="section" title="。总结"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="summary"></a>。总结</h2></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>
                    OOP大多是命令式的，但也有函数式的和逻辑式的OO语言。
                </p></li><li class="listitem"><p>
                    OOP的核心思想可以归纳为：以数据为中心组织逻辑，将系统视为相互作用的对象集合，并利用继承与多态来增强可维护性、可扩展性和可重用性。
                </p></li><li class="listitem"><p>
                    OOP既不能脱离其他范式，也绝非适用于一切应用。
                </p></li><li class="listitem"><p>
                    可维护性、可扩展性和可重用性是所有范式和语言的共同目标，并非OOP所独有。
                </p></li><li class="listitem"><p>
                    与其说OOP更具重用性，不如说更具易用性。
                </p></li><li class="listitem"><p>
                    过程式编程以过程为中心，自顶向下，逐步求精。
                </p></li><li class="listitem"><p>
                    对象式编程以数据为中心，自底向上，逐步合并。
                </p></li><li class="listitem"><p>
                    过程式程序的世界是君主制的，OO程序的世界是民主制的。
                </p></li><li class="listitem"><p>
                    封装使得对象拥有个体身份，继承使得对象拥有家庭身份，多态使得对象拥有社会身份。
                </p></li></ul></div></div><div class="section" title="“”参考"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="reference"></a>“”参考</h2></div></div></div><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
                    Wikipedia．Object-oriented programming．<a class="link" href="http://en.wikipedia.org/wiki/Object-oriented_programming" target="_top">http://en.wikipedia.org/wiki/Object-oriented_programming</a>
                </p></li><li class="listitem"><p>
                    Frederick Brooks．The Mythical Man-month．Boston：AddisonWesley，1995．179-203
                </p></li></ol></div></div></div><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fblog.zhenghui.org%2F2009%2F09%2F06%2Fcolon-class-2_3%2F&amp;linkname=%E5%86%92%E5%8F%B7%E8%AF%BE%E5%A0%82%C2%A72.3%EF%BC%9A%E5%AF%B9%E8%B1%A1%E8%8C%83%E5%BC%8F">分享/保存</a>]]></content:encoded>
			<wfw:commentRss>http://blog.zhenghui.org/2009/09/06/colon-class-2_3/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>《冒号课堂》目录</title>
		<link>http://blog.zhenghui.org/2009/08/21/contents-of-colonclass/</link>
		<comments>http://blog.zhenghui.org/2009/08/21/contents-of-colonclass/#comments</comments>
		<pubDate>Fri, 21 Aug 2009 15:34:27 +0000</pubDate>
		<dc:creator>hui</dc:creator>
				<category><![CDATA[冒号课堂]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[目录]]></category>
		<category><![CDATA[程序员]]></category>
		<category><![CDATA[编程范式]]></category>
		<category><![CDATA[软件设计]]></category>

		<guid isPermaLink="false">http://blog.zhenghui.org/?p=4</guid>
		<description><![CDATA[《冒号课堂》一书的目录]]></description>
			<content:encoded><![CDATA[<h3 style="text-align: left;"><span style="font-family: 宋体;">
</span></h3>
<ul style="margin-top: 0cm; list-style-type: none;">
	<li style="font-size: 14pt; color: #3366ff;">上篇：<strong>编程范式与编程语言</strong></li>
	<li style="font-size: 14pt; color: #3366ff;"><strong>
</strong></li>
	<li><strong>第一课 开班导言</strong></li>
	<li><a href="http://blog.zhenghui.org/2009/08/24/colon-class-1_1/">§1.1：开班发言——<em>程序员的四层境界</em></a></li>
	<li><a href="http://blog.zhenghui.org/2009/08/26/colon-class-1_2/">§1.2：首轮提问——<em>什么语言好？</em></a></li>
	<li><a href="http://blog.zhenghui.org/2009/08/27/colon-class-1_3/">§1.3：语言选择——<em>合适的就是好的</em></a></li>
	<li><a href="http://blog.zhenghui.org/2009/08/29/colon-class-1_4/">§1.4：初识范式——<em>程序王国中的世界观与方法论</em></a></li>
	<li><a href="http://blog.zhenghui.org/2009/08/31/colon-class-1_5/">§1.5：开发技术——<em>实用还是时髦？</em></a></li>
	<li><em>
</em></li>
	<li><strong>第二课 重要范式</strong></li>
	<li><a href="http://blog.zhenghui.org/2009/09/03/colon-class-2_1/">§2.1：命令范式——<em>一切行动听指挥</em></a></li>
	<li><a href="http://blog.zhenghui.org/2009/09/04/colon-class-2_2/">§2.2：声明范式——<em>目标决定行动</em></a></li>
	<li><a href="http://blog.zhenghui.org/2009/09/06/colon-class-2_3/">§2.3：对象范式——<em>民主制社会的编程法则</em></a></li>
	<li><a href="http://blog.zhenghui.org/2009/09/07/colon-class-2_4/">§2.4：并发范式——<em>合作与竞争</em></a></li>
	<li><em>
</em></li>
	<li><strong>第三课 常用范式</strong></li>
	<li><a href="http://blog.zhenghui.org/2009/09/08/colon-class-3_1/">§3.1：泛型范式——<em>抽象你的算法</em></a></li>
	<li><a href="http://blog.zhenghui.org/2009/09/09/colon-class-3_2/">§3.2：超级范式——<em>提升语言的级别</em></a></li>
	<li><a href="http://blog.zhenghui.org/2009/09/10/colon-class-3_3/">§3.3：切面范式——<em>多角度看问题</em></a></li>
	<li><a href="http://blog.zhenghui.org/2009/09/11/colon-class-3_4/">§3.4：事件驱动——<em>有事我叫你，没事别烦我</em></a></li>
	<li><em>
</em></li>
	<li><strong>第四课 重温范式</strong></li>
	<li><a href="http://blog.zhenghui.org/2009/09/13/colon-class-4_1/">§4.1：函数范式——<em>精巧的数学思维</em></a></li>
	<li><a href="http://blog.zhenghui.org/2009/09/15/colon-class-4_2/">§4.2：逻辑范式——<em>当算法失去了控制</em></a></li>
	<li><a href="http://blog.zhenghui.org/2009/09/17/colon-class-4_3/">§4.3：汇总范式——<em>一张五味俱全的大烙饼</em></a></li>
	<li><a href="http://blog.zhenghui.org/2009/09/19/colon-class-4_4/">§4.4：情景范式——<em>餐馆里的编程范式</em></a></li>
	<li><em>
</em></li>
	<li><strong>第五课 语言小谈</strong></li>
	<li><a href="http://blog.zhenghui.org/2009/09/21/colon-class-5_1/">§5.1：教学计划——<em>接下来的故事</em></a></li>
	<li><a href="http://blog.zhenghui.org/2009/09/23/colon-class-5_2/">§5.2：数据类型——<em>规则与变通</em></a></li>
	<li><a href="http://blog.zhenghui.org/2009/09/25/colon-class-5_3/">§5.3：动态语言——<em>披着彩衣飞舞的脚本语言</em></a></li>
	<li><a href="http://blog.zhenghui.org/2009/09/27/colon-class-5_4/">§5.4：语言误区——<em>语言的宗教情结</em></a></li>
	<li><em>
</em></li>
	<li><strong>第六课 语言简评</strong></li>
	<li><a href="http://blog.zhenghui.org/2009/09/29/colon-class-6_1/">§6.1：系统语言——<em>权力的双刃剑</em></a></li>
	<li><a href="http://blog.zhenghui.org/2009/10/03/colon-class-6_2/">§6.2：平台语言——<em>先搭台后唱戏</em></a></li>
	<li><a href="http://blog.zhenghui.org/2009/10/08/colon-class-6_3/">§6.3：前台语言——<em>视觉与交互的艺术</em></a></li>
	<li><a href="http://blog.zhenghui.org/2009/10/10/colon-class-6_4/">§6.4：后台脚本——<em>敏捷开发的利器</em></a></li>
	<li><em>
</em></li>
</ul>
<ul style="margin-top: 0cm; list-style-type: none;">
	<li style="font-size: 14pt; color: #3366ff;">下篇：<strong>抽象机制与对象范式</strong></li>
	<li style="font-size: 14pt; color: #3366ff;"><strong>
</strong></li>
	<li><strong>第七课 抽象封装</strong></li>
	<li>§7.1：抽象思维——<em>减法和除法的学问</em></li>
	<li>§7.2：数据抽象——<em>“做什么”重于“怎么做”</em></li>
	<li>§7.3：封装隐藏——<em>包装的讲究</em></li>
	<li><em>
</em></li>
	<li><strong>第八课 抽象接口</strong></li>
	<li>§8.1：软件应变——<em>随需而变，适者生存</em></li>
	<li>§8.2：访问控制——<em>代码的多级管理</em></li>
	<li>§8.3：接口服务——<em>讲诚信与守规矩</em></li>
	<li><em>
</em></li>
	<li><strong>第九课 继承机制</strong></li>
	<li>§9.1：继承关系——<em>继承财富，更要继承责任</em></li>
	<li>§9.2：慎用继承——<em>以谨慎之心对待权力</em></li>
	<li><em>
</em></li>
	<li><strong>第十课 多态机制</strong></li>
	<li><a href="http://blog.zhenghui.org/2009/10/20/colon-class-10_1/">§10.1：多态类型——<em>静中之动</em></a></li>
	<li><a href="http://blog.zhenghui.org/2009/10/24/colon-class-10_2/">§10.2：抽象类型——<em>实中之虚</em></a></li>
	<li><em>
</em></li>
	<li><strong>第十一课 值与引用</strong></li>
	<li>§11.1：语法类型——<em>体用之分</em></li>
	<li>§11.2：语义类型——<em>阴阳之道</em></li>
	<li><em>
</em></li>
	<li><strong>第十二课 设计原则</strong></li>
	<li>§12.1：间接原则——<em>柔胜于刚，曲胜于直</em></li>
	<li>§12.2：依赖原则——<em>有求皆苦，无欲则刚</em></li>
	<li>§12.3：内聚原则——<em>不是一家人，不进一家门</em></li>
	<li>§12.4：保变原则——<em>与魔鬼打交道的艺术</em></li>
	<li><em>
</em></li>
	<li><strong>第十三课 设计模式</strong></li>
	<li>§13.1：创建模式——<em>不要问我从哪里来</em></li>
	<li>§13.2：结构模式——<em>建筑的技巧</em></li>
	<li>§13.3：行为模式——<em>君子之交淡如水</em></li>
	<li>§13.4：闭班小结——<em>软件无形，编程有道</em></li>
</ul><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fblog.zhenghui.org%2F2009%2F08%2F21%2Fcontents-of-colonclass%2F&amp;linkname=%E3%80%8A%E5%86%92%E5%8F%B7%E8%AF%BE%E5%A0%82%E3%80%8B%E7%9B%AE%E5%BD%95">分享/保存</a>]]></content:encoded>
			<wfw:commentRss>http://blog.zhenghui.org/2009/08/21/contents-of-colonclass/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
	</channel>
</rss>
