<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet href='http://feed.feedsky.com/styles/temp01.xsl' type='text/xsl' ?><!--这是一个由Feedsy提供技术支持的Feed，为了提高读者阅读的体验，以及满足用户美化自己Feed的需要，我们设计了多种精美的Feed模板，提供给大家选择，所有最终呈现出来的样式，皆由用户自愿选择使用，未经许可，任何团体和个人，请不要擅自修改样式或者盗用，这是对于用户选择权的尊重。--><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:fs="http://www.feedsky.com/namespace/feed" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"><channel><atom:link href="http://feed.feedsky.com/ideagracedocs" type="application/rss+xml" rel="self"></atom:link><fs:self_link href="http://feed.feedsky.com/ideagracedocs" type="application/rss+xml"></fs:self_link><lastBuildDate>Tue, 13 Jan 2009 13:38:18 GMT</lastBuildDate><title>IdeaGrace - JAVA开发 - Web开发 RSS</title><description>IdeaGrace - JAVA开发 - Web开发</description><link>http://www.ideagrace.com/</link><language>en</language><copyright>IdeaGrace - JAVA开发 - Web开发</copyright><image><title>IdeaGrace - JAVA开发 - Web开发</title><url>http://www.ideagrace.com/attachments/</url><link>http://www.ideagrace.com/</link><description>IdeaGrace - JAVA开发 - Web开发</description></image><item><title>JSF配置文件faces-config.xml参数详解</title><link>http://www.ideagrace.com/html/doc/2009/01/13/08722.html</link><content:encoded>&lt;p align=&quot;left&quot;&gt;&amp;nbsp; &amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;lt;!DOCTYPE faces-config PUBLIC&lt;br /&gt;
&amp;nbsp;&amp;quot;-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN&amp;quot;&lt;br /&gt;
&amp;nbsp;&amp;quot;http://java.sun.com/dtd/web-facesconfig_1_0.dtd&amp;quot;&amp;gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;lt;faces-config&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;navigation-rule&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;from-view-id&amp;gt;/pages/index.jsp&amp;lt;/from-view-id&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;navigation-case&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;from-outcome&amp;gt;success&amp;lt;/from-outcome&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;to-view-id&amp;gt;/pages/welcome.jsp&amp;lt;/to-view-id&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/navigation-case&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;navigation-case&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;from-outcome&amp;gt;failure&amp;lt;/from-outcome&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;to-view-id&amp;gt;/pages/index.jsp&amp;lt;/to-view-id&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/navigation-case&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/navigation-rule&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;managed-bean&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;managed-bean-name&amp;gt;user&amp;lt;/managed-bean-name&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;managed-bean-class&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; onlyfun.caterpillar.UserBean&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/managed-bean-class&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;managed-bean-scope&amp;gt;session&amp;lt;/managed-bean-scope&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/managed-bean&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;lt;/faces-config&amp;gt;&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;一对&amp;lt;navigation-case&amp;gt;是一组导航规则,在该标签里面定义表单来源和跳转的目标 . 对于JSF，每一个视图（View）都有一个独特的识别（identifier），称之为View ID，在JSF中的View ID是从Web应用程序的环境相对路径开始计算，设定时都是以/作为开头，如果您请求时的路径是/pages/index.faces，则JSF会将扩展 名改为/pages/index.jsp，以此作为view-id。在&amp;lt;navigation-rule&amp;gt;中的&amp;lt;from-view- id&amp;gt;是个选择性的定义，它规定了来源页面的条件，&amp;lt;navigation-case&amp;gt;中定义各种导览条件，&amp;lt;from- outcome&amp;gt;定义当窗体结果符合的条件时，各自改导向哪一个目的页面，目的页面是在&amp;lt;to-view-id&amp;gt;中定义&lt;/p&gt;
&lt;p&gt;还可以在&amp;lt;navigation-case&amp;gt;中加入&amp;lt;from-action&amp;gt;，进一步规范窗体结果必须根据哪一个动作方法（action method），当中是使用 JSF Expression Language 来设定，例如：&lt;/p&gt;
&lt;p&gt;....&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;navigation-rule&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;from-view-id&amp;gt;/pages/index.jsp&amp;lt;/from-view-id&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;navigation-case&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;from-action&amp;gt;#{user.verify}&amp;lt;/from-action&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;from-outcome&amp;gt;success&amp;lt;/from-outcome&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;to-view-id&amp;gt;/pages/welcome.jsp&amp;lt;/to-view-id&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/navigation-case&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ....&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/navigation-rule&amp;gt;&lt;br /&gt;
&amp;nbsp;....&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;在导航时，预设都是使用forward的方式，您可以在&amp;lt;navigation-case&amp;gt;中加入一个&amp;lt;redirect/&amp;gt;，让JSF发出让浏览器重新导向（redirect）的header，让浏览器主动要求新网页，例如：&lt;/p&gt;
&lt;p&gt;....&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;navigation-rule&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;from-view-id&amp;gt;/pages/index.jsp&amp;lt;/from-view-id&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;navigation-case&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;from-outcome&amp;gt;success&amp;lt;/from-outcome&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;to-view-id&amp;gt;/pages/welcome.jsp&amp;lt;/to-view-id&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;redirect/&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/navigation-case&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ....&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/navigation-rule&amp;gt;&lt;br /&gt;
&amp;nbsp;....&lt;/p&gt;
&lt;p&gt;您的来源网页可能是某个特定模块，例如在/admin/下的页面，您可以在&amp;lt;from-view-id&amp;gt;中使用wildcards，也就是使用 * 字符，例如：&lt;/p&gt;
&lt;p&gt;....&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;navigation-rule&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;from-view-id&amp;gt;/admin/*&amp;lt;/from-view-id&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;navigation-case&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;from-action&amp;gt;#{user.verify}&amp;lt;/from-action&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;from-outcome&amp;gt;success&amp;lt;/from-outcome&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;to-view-id&amp;gt;/pages/welcome.jsp&amp;lt;/to-view-id&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/navigation-case&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ....&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/navigation-rule&amp;gt;&lt;br /&gt;
&amp;nbsp;....在上面的设定中，只要来源网页是从/admin来的，都可以开始测试接下来的&amp;lt;navigation-case&amp;gt;。&lt;/p&gt;
&lt;p&gt;&amp;lt;from-view-id&amp;gt;如果没有设定，表示来源网页不作限制，您也可以使用 * 显式的在定义档中表明，例如：&lt;/p&gt;
&lt;p&gt;....&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;navigation-rule&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;from-view-id&amp;gt;/*&amp;lt;/from-view-id&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;navigation-case&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ....&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/navigation-rule&amp;gt;&lt;br /&gt;
&amp;nbsp;....或者&lt;/p&gt;
&lt;p&gt;....&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;navigation-rule&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;from-view-id&amp;gt;*&amp;lt;/from-view-id&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;navigation-case&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ....&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/navigation-rule&amp;gt;&lt;br /&gt;
&amp;nbsp;....&lt;/p&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/ideagracedocs/361097317/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/ideagracedocs/361097317/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><pubDate>Tue, 13 Jan 2009 21:38:18 +0800</pubDate><guid isPermaLink="false">http://www.ideagrace.com/html/doc/2009/01/13/08722.html</guid><fs:srclink>http://www.ideagrace.com/html/doc/2009/01/13/08722.html</fs:srclink><fs:srcfeed>http://www.ideagrace.com/rss.php</fs:srcfeed><fs:itemid>feedsky/ideagracedocs/~6170083/361097317/4278026</fs:itemid></item><item><title>Spring 2.X 中AOP的使用浅析</title><link>http://www.ideagrace.com/html/doc/2008/09/19/08721.html</link><content:encoded>Spring 2.X 中AOP的使用浅析

　　和 Spring1.X相比，Spring2.X使用AspectJ的语法来声明AOP，这使得它更“标准”，更灵活了。还是那句话，如果你不了解 AspectJ并且打算使用Spring2.X的AspectJ式AOP，那就学学AspectJ吧，这方面的书还是很多了。
Spring2.X下的切面有两种实现方式，一种是以Java文件定义切面（其只是普通的Java类），然后在配置文件中声明定义的切面；另一种是在Java类中引入和AOP相关的元数据（注释）。
　　先介绍第一种配置方式。需要指出的是，Spring2.X的beans名称空间和Spring1.X有所不同，它采用了Schema而不是DTD（也可采用DTD方式，具体的请参考文档）。还是引入毫无意义的日志切面，定义的切面类LogingAspect 如下：

public class LogingAspect {
public void logMethod(JoinPoint jp){
System.err.println(jp.getTarget().getClass());
System.err.println(jp.getSignature().getName());
}
}

　　同时在配置文件中如下配置：

＜ bean id = &quot; logAspectTarget &quot; class = &quot; hibernatesample.service.util.LogingAspect &quot; ＞
＜/ bean ＞
＜ aop:config ＞
＜ aop:aspect id = &quot; logAspect &quot; ref = &quot; logAspectTarget &quot; ＞
＜ aop:pointcut id = &quot; businessService &quot; expression = &quot; execution(* hibernatesample.service.*.*(..)) &quot; /＞
＜ aop:after pointcut - ref = &quot; businessService &quot; method = &quot; logMethod &quot; /＞
＜/ aop:aspect ＞
＜/ aop:config ＞

　　对于上面的切面，切入点businessService是在配置文件中声明的，其表达式采用了 AspectJ的语法，LogingAspect 类中logMethod(JoinPoint jp)方法根据配置文件信息可知其是after通知，方法的JoinPoint参数不是必须的，它是来自于AspectJ的实用类，这里用它不过输出一些和连接点有关的信息。当然，在Spring2.X中，切入点和通知能更灵活的使用，我们可以如AspectJ一样传递参数给通知。如果需要在 Service中引入事务功能，需要如下配置事务通知：

＜ tx:advice id = &quot; txAdvice &quot; transaction - manager = &quot; transactionManager &quot; ＞
＜ tx:attributes ＞
＜ tx:method name = &quot; get* &quot; read - only = &quot; true &quot; /＞
＜ tx:method name = &quot; find* &quot; read - only = &quot; true &quot; /＞
＜ tx:method name = &quot; * &quot; /＞
＜/ tx:attributes ＞
＜/ tx:advice ＞
＜ aop:config ＞
＜ aop:pointcut id = &quot; demoServiceMethods &quot; expression = &quot; execution(* hibernatesample.service.*.*(..)) &quot; /＞
＜ aop:advisor advice - ref = &quot; txAdvice &quot; pointcut - ref = &quot; demoServiceMethods &quot; /＞
＜ aop:aspect id = &quot; logAspect &quot; ref = &quot; logAspectTarget &quot; ＞
＜ aop:pointcut id = &quot; businessService &quot; expression = &quot; execution(* hibernatesample.service.*.*(..)) &quot; /＞
＜ aop:after pointcut - ref = &quot; businessService &quot; method = &quot; logMethod &quot; /＞
＜/ aop:aspect ＞
＜/ aop:config ＞

　　完成上面的工作相当于完成了 Spring1.X 的 自动代理。 我们接下来需要定义的任何 Service Bean 都可以很纯粹很纯粹了：

＜ bean id =&quot;accountService&quot; class =&quot;hibernatesample.service.impl.AccountServiceImpl&quot; ＞
＜ property name =&quot;accountDAO&quot; ref =&quot;accountDAO&quot; ＞＜/ property ＞
＜/ bean ＞

　　第二种实现 AOP 的方式和第一种相比，只是在 LogingAspect 中加入了注释，而省去了配置文件中和 LogingAspect 相关的配置。重新编写的 LogingAspect 如下：

@Aspect
public class LogingAspect {
@Pointcut( &quot; execution(* hibernatesample.service.*.*(..)) &quot; )
public void businessService(){}
@After( &quot; businessService() &quot; )
public void logMethod(JoinPoint jp){
System.err.println(jp.getTarget().getClass());
System.err.println(jp.getSignature().getName());
}
}

　　而简化后的配置文件可以去除上面的如下和 logAspect 相关的配置信息：

＜ aop:aspect id =&quot;logAspect&quot; ref =&quot;logAspectTarget&quot; ＞
＜ aop:pointcut id =&quot;businessService&quot; expression =&quot;execution(* hibernatesample.service.*.*(..))&quot; /＞
＜ aop:after pointcut-ref =&quot;businessService&quot; method =&quot;logMethod&quot; /＞
＜/ aop:aspect ＞
＜ bean id =&quot;logAspectTarget&quot; class =&quot;hibernatesample.service.util.LogingAspect&quot; ＞＜/ bean ＞

　　还没有完，为了使 Spring 应用 LogingAspect 的注释，需要在配置文件中添上
＜aop:aspectj-autoproxy/＞
　　如果觉得事务的配置没有使用注释更简洁（我倒不会有这样的想法，毕竟在配置文件中声明的事务只是那么固定的几段，除非作用于类上的事务逻辑上很复杂），也可以使用Spring提供的事务注释作用于类文件上，这可是更细粒度的事务声明了。
　　坦率的说，由于时间有限，该文写的比较粗糙。对于Spring AOP有兴趣并有疑问的朋友，可以参考Spring的文档，它的文档做的还是不错的。&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/ideagracedocs/361097318/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/ideagracedocs/361097318/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><pubDate>Fri, 19 Sep 2008 19:11:37 +0800</pubDate><guid isPermaLink="false">http://www.ideagrace.com/html/doc/2008/09/19/08721.html</guid><fs:srclink>http://www.ideagrace.com/html/doc/2008/09/19/08721.html</fs:srclink><fs:srcfeed>http://www.ideagrace.com/rss.php</fs:srcfeed><fs:itemid>feedsky/ideagracedocs/~6170083/361097318/4278026</fs:itemid></item><item><title>白话设计模式――Abstract Factory</title><link>http://www.ideagrace.com/html/doc/2008/06/06/08720.html</link><content:encoded>&lt;p style=&quot;text-indent: 21pt;&quot; class=&quot;MsoNormal&quot;&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: 宋体;&quot;&gt;Abstract Factory&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;，把英文直接翻译过来的话就是&amp;ldquo;抽象工厂&amp;rdquo;，既然是工厂，那就肯定是生产产品的地方。不过，它不是生产同一类的产品，而是生产同一系列的产品。举个例子，广州本田现在生产&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: 宋体;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;种汽车，&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: 宋体;&quot;&gt;Odyssey&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;、&lt;span lang=&quot;EN-US&quot;&gt;Accord&lt;/span&gt;、&lt;span lang=&quot;EN-US&quot;&gt;Fit&lt;/span&gt;，而广本的工厂里面并不是拥有&lt;span lang=&quot;EN-US&quot;&gt;3&lt;/span&gt;条不同的生产线以生产不同的汽车。这就非常相似于我们正在讨论的抽象工厂模式，广本在生产不同的汽车时，需要在各个生产环节进行修改，换机器自然是不合适的，因为这&lt;span lang=&quot;EN-US&quot;&gt;3&lt;/span&gt;种汽车每天都要生产，分时段而已。如果某一个环节的更换工作出了问题都会有大麻烦，比如&lt;span lang=&quot;EN-US&quot;&gt;Fit&lt;/span&gt;的车顶肯定装不到&lt;span lang=&quot;EN-US&quot;&gt;Odyssey&lt;/span&gt;上。 我们在软件设计的时候也是这样，如果需要某一系列配套的类来进行工作，当这个系列中有一个类用错了，后果都是不好的。再回到广本的例子上，当广本准备生产 另外一种汽车时，只需要拥有相应的配套模具（还有其他的一些配件和一些数控设备的控制程序）就可以了，没有必要搞一大堆的生产线。&lt;span lang=&quot;EN-US&quot;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot;text-indent: 21pt;&quot; class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;再来一个生活中的例子，&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;西服&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;西裤&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;皮鞋&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;白衬衫&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;领带&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;头发梳得顺顺的，出入高级会所或者重要场合的时候，男人一般都这样穿；休闲装&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;运动鞋&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;随意的发型，生活中就这样穿，舒服；睡衣&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;拖鞋&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;鸡窝头，早上就这样。每一种都是合适的造型，如果你搞成如下这样的造型就不合适了，西服&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;西裤&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;回力鞋&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;超级大背包&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;鸡窝头，广州火车站很多同志都是这样打扮的。&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot;text-indent: 21pt;&quot; class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;抽象工厂模式是一种创建型的模式。上面的比喻说明了抽象工厂就是生产同一个系列产品的东西，因为这一系列的产品是关联的，如果混用就可能出问题，所以就统一的在抽象工厂中进行创建。当要增加一个新的产品系列时，就多写一个工厂子类并添加相应的产品子类就可以了。&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot;text-indent: 21pt;&quot; class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;我们来看一个类图。 &lt;br /&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;v:shapetype coordsize=&quot;21600,21600&quot; o:spt=&quot;75&quot; o:preferrelative=&quot;t&quot; path=&quot;m@4@5l@4@11@9@11@9@5xe&quot; filled=&quot;f&quot; stroked=&quot;f&quot; id=&quot;_x0000_t75&quot;&gt;&lt;v:stroke joinstyle=&quot;miter&quot;&gt;&lt;/v:stroke&gt;&lt;v:formulas&gt;&lt;v:f eqn=&quot;if lineDrawn pixelLineWidth 0&quot;&gt;&lt;/v:f&gt;&lt;v:f eqn=&quot;sum @0 1 0&quot;&gt;&lt;/v:f&gt;&lt;v:f eqn=&quot;sum 0 0 @1&quot;&gt;&lt;/v:f&gt;&lt;v:f eqn=&quot;prod @2 1 2&quot;&gt;&lt;/v:f&gt;&lt;v:f eqn=&quot;prod @3 21600 pixelWidth&quot;&gt;&lt;/v:f&gt;&lt;v:f eqn=&quot;prod @3 21600 pixelHeight&quot;&gt;&lt;/v:f&gt;&lt;v:f eqn=&quot;sum @0 0 1&quot;&gt;&lt;/v:f&gt;&lt;v:f eqn=&quot;prod @6 1 2&quot;&gt;&lt;/v:f&gt;&lt;v:f eqn=&quot;prod @7 21600 pixelWidth&quot;&gt;&lt;/v:f&gt;&lt;v:f eqn=&quot;sum @8 21600 0&quot;&gt;&lt;/v:f&gt;&lt;v:f eqn=&quot;prod @7 21600 pixelHeight&quot;&gt;&lt;/v:f&gt;&lt;v:f eqn=&quot;sum @10 21600 0&quot;&gt;&lt;/v:f&gt;&lt;/v:formulas&gt;&lt;v:path o:extrusionok=&quot;f&quot; gradientshapeok=&quot;t&quot; o:connecttype=&quot;rect&quot;&gt;&lt;/v:path&gt;&lt;o:lock v:ext=&quot;edit&quot; aspectratio=&quot;t&quot;&gt;&lt;/o:lock&gt;&lt;/v:shapetype&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-indent: 21pt;&quot; class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;&amp;nbsp;&lt;img border=&quot;0&quot; src=&quot;http://www.cnblogs.com/images/cnblogs_com/reeezak/DesignPattern/af.jpg&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; 图中，我们可以看到，客户需要得到某系列的产品的时候，直接用相应的工厂子类来创建产品就可以了。比如，当需要生产&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;Fit&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;时，就用&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;FitFactory&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;，等到换班之后，要生产&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;Odyssey&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;了，直接使用&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;OdysseyFactory&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;替换&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;FitFactory&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;就行了，至于怎么替换就随便了，&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;GoF&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;也给了我们一些建议，我将在后面总结创建型模式的时候讲。&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot;text-indent: 21pt;&quot; class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;把上面的类图转换成代码，应该是这个样子。 &lt;br /&gt;
&lt;br /&gt;
关于车门的类：&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);&quot;&gt;&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/None.gif&quot; alt=&quot;&quot; /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;abstract&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;AbstractDoor&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_37_40_Open_Text.style.display='none'; Codehighlighter1_37_40_Closed_Image.style.display='inline'; Codehighlighter1_37_40_Closed_Text.style.display='inline';&quot; id=&quot;Codehighlighter1_37_40_Open_Image&quot; alt=&quot;&quot; /&gt;&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_37_40_Closed_Text.style.display='none'; Codehighlighter1_37_40_Open_Image.style.display='inline'; Codehighlighter1_37_40_Open_Text.style.display='inline';&quot; style=&quot;display: none;&quot; id=&quot;Codehighlighter1_37_40_Closed_Image&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);&quot; id=&quot;Codehighlighter1_37_40_Closed_Text&quot;&gt;&lt;img src=&quot;http://www.cnblogs.com/Images/dot.gif&quot; alt=&quot;&quot; /&gt;&lt;/span&gt;&lt;span id=&quot;Codehighlighter1_37_40_Open_Text&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;{&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/None.gif&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/None.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;FitDoor&amp;nbsp;:&amp;nbsp;AbstractDoor&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_81_84_Open_Text.style.display='none'; Codehighlighter1_81_84_Closed_Image.style.display='inline'; Codehighlighter1_81_84_Closed_Text.style.display='inline';&quot; id=&quot;Codehighlighter1_81_84_Open_Image&quot; alt=&quot;&quot; /&gt;&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_81_84_Closed_Text.style.display='none'; Codehighlighter1_81_84_Open_Image.style.display='inline'; Codehighlighter1_81_84_Open_Text.style.display='inline';&quot; style=&quot;display: none;&quot; id=&quot;Codehighlighter1_81_84_Closed_Image&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);&quot; id=&quot;Codehighlighter1_81_84_Closed_Text&quot;&gt;&lt;img src=&quot;http://www.cnblogs.com/Images/dot.gif&quot; alt=&quot;&quot; /&gt;&lt;/span&gt;&lt;span id=&quot;Codehighlighter1_81_84_Open_Text&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;{&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/None.gif&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/None.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;OdysseyDoor&amp;nbsp;:&amp;nbsp;AbstractDoor&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_129_132_Open_Text.style.display='none'; Codehighlighter1_129_132_Closed_Image.style.display='inline'; Codehighlighter1_129_132_Closed_Text.style.display='inline';&quot; id=&quot;Codehighlighter1_129_132_Open_Image&quot; alt=&quot;&quot; /&gt;&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_129_132_Closed_Text.style.display='none'; Codehighlighter1_129_132_Open_Image.style.display='inline'; Codehighlighter1_129_132_Open_Text.style.display='inline';&quot; style=&quot;display: none;&quot; id=&quot;Codehighlighter1_129_132_Closed_Image&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);&quot; id=&quot;Codehighlighter1_129_132_Closed_Text&quot;&gt;&lt;img src=&quot;http://www.cnblogs.com/Images/dot.gif&quot; alt=&quot;&quot; /&gt;&lt;/span&gt;&lt;span id=&quot;Codehighlighter1_129_132_Open_Text&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;{&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p style=&quot;text-indent: 21pt;&quot; class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;&lt;br /&gt;
关于底盘的类：&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);&quot;&gt;&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/None.gif&quot; alt=&quot;&quot; /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;abstract&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;AbstractChassis&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_40_43_Open_Text.style.display='none'; Codehighlighter1_40_43_Closed_Image.style.display='inline'; Codehighlighter1_40_43_Closed_Text.style.display='inline';&quot; id=&quot;Codehighlighter1_40_43_Open_Image&quot; alt=&quot;&quot; /&gt;&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_40_43_Closed_Text.style.display='none'; Codehighlighter1_40_43_Open_Image.style.display='inline'; Codehighlighter1_40_43_Open_Text.style.display='inline';&quot; style=&quot;display: none;&quot; id=&quot;Codehighlighter1_40_43_Closed_Image&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);&quot; id=&quot;Codehighlighter1_40_43_Closed_Text&quot;&gt;&lt;img src=&quot;http://www.cnblogs.com/Images/dot.gif&quot; alt=&quot;&quot; /&gt;&lt;/span&gt;&lt;span id=&quot;Codehighlighter1_40_43_Open_Text&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;{&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/None.gif&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/None.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;FitChassis&amp;nbsp;:&amp;nbsp;AbstractChassis&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_90_93_Open_Text.style.display='none'; Codehighlighter1_90_93_Closed_Image.style.display='inline'; Codehighlighter1_90_93_Closed_Text.style.display='inline';&quot; id=&quot;Codehighlighter1_90_93_Open_Image&quot; alt=&quot;&quot; /&gt;&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_90_93_Closed_Text.style.display='none'; Codehighlighter1_90_93_Open_Image.style.display='inline'; Codehighlighter1_90_93_Open_Text.style.display='inline';&quot; style=&quot;display: none;&quot; id=&quot;Codehighlighter1_90_93_Closed_Image&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);&quot; id=&quot;Codehighlighter1_90_93_Closed_Text&quot;&gt;&lt;img src=&quot;http://www.cnblogs.com/Images/dot.gif&quot; alt=&quot;&quot; /&gt;&lt;/span&gt;&lt;span id=&quot;Codehighlighter1_90_93_Open_Text&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;{&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/None.gif&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/None.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;OdysseyChassis&amp;nbsp;:&amp;nbsp;AbstractChassis&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_144_147_Open_Text.style.display='none'; Codehighlighter1_144_147_Closed_Image.style.display='inline'; Codehighlighter1_144_147_Closed_Text.style.display='inline';&quot; id=&quot;Codehighlighter1_144_147_Open_Image&quot; alt=&quot;&quot; /&gt;&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_144_147_Closed_Text.style.display='none'; Codehighlighter1_144_147_Open_Image.style.display='inline'; Codehighlighter1_144_147_Open_Text.style.display='inline';&quot; style=&quot;display: none;&quot; id=&quot;Codehighlighter1_144_147_Closed_Image&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);&quot; id=&quot;Codehighlighter1_144_147_Closed_Text&quot;&gt;&lt;img src=&quot;http://www.cnblogs.com/Images/dot.gif&quot; alt=&quot;&quot; /&gt;&lt;/span&gt;&lt;span id=&quot;Codehighlighter1_144_147_Open_Text&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;{&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p style=&quot;text-indent: 21pt;&quot; class=&quot;MsoNormal&quot;&gt;&lt;br /&gt;
关于工厂的类：&lt;/p&gt;
&lt;div style=&quot;border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);&quot;&gt;&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/None.gif&quot; alt=&quot;&quot; /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;abstract&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;HondaFactory &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_37_136_Open_Text.style.display='none'; Codehighlighter1_37_136_Closed_Image.style.display='inline'; Codehighlighter1_37_136_Closed_Text.style.display='inline';&quot; style=&quot;display: inline;&quot; id=&quot;Codehighlighter1_37_136_Open_Image&quot; alt=&quot;&quot; /&gt;&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_37_136_Closed_Text.style.display='none'; Codehighlighter1_37_136_Open_Image.style.display='inline'; Codehighlighter1_37_136_Open_Text.style.display='inline';&quot; style=&quot;display: none;&quot; id=&quot;Codehighlighter1_37_136_Closed_Image&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);&quot; id=&quot;Codehighlighter1_37_136_Closed_Text&quot;&gt;&lt;img width=&quot;15&quot; height=&quot;20&quot; src=&quot;http://www.cnblogs.com/Images/dot.gif&quot; alt=&quot;&quot; /&gt;&lt;/span&gt;&lt;span style=&quot;display: inline;&quot; id=&quot;Codehighlighter1_37_136_Open_Text&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;{ &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;abstract&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;AbstractDoor&amp;nbsp;CreateDoor(); &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;abstract&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;AbstractChassis&amp;nbsp;CreateChassis(); &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/None.gif&quot; alt=&quot;&quot; /&gt; &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/None.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;FitFactory &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_165_313_Open_Text.style.display='none'; Codehighlighter1_165_313_Closed_Image.style.display='inline'; Codehighlighter1_165_313_Closed_Text.style.display='inline';&quot; id=&quot;Codehighlighter1_165_313_Open_Image&quot; alt=&quot;&quot; /&gt;&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_165_313_Closed_Text.style.display='none'; Codehighlighter1_165_313_Open_Image.style.display='inline'; Codehighlighter1_165_313_Open_Text.style.display='inline';&quot; style=&quot;display: none;&quot; id=&quot;Codehighlighter1_165_313_Closed_Image&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);&quot; id=&quot;Codehighlighter1_165_313_Closed_Text&quot;&gt;&lt;img width=&quot;15&quot; height=&quot;20&quot; src=&quot;http://www.cnblogs.com/Images/dot.gif&quot; alt=&quot;&quot; /&gt;&lt;/span&gt;&lt;span id=&quot;Codehighlighter1_165_313_Open_Text&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;{ &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;AbstractDoor&amp;nbsp;CreateDoor() &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_204_233_Open_Text.style.display='none'; Codehighlighter1_204_233_Closed_Image.style.display='inline'; Codehighlighter1_204_233_Closed_Text.style.display='inline';&quot; id=&quot;Codehighlighter1_204_233_Open_Image&quot; alt=&quot;&quot; /&gt;&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_204_233_Closed_Text.style.display='none'; Codehighlighter1_204_233_Open_Image.style.display='inline'; Codehighlighter1_204_233_Open_Text.style.display='inline';&quot; style=&quot;display: none;&quot; id=&quot;Codehighlighter1_204_233_Closed_Image&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);&quot; id=&quot;Codehighlighter1_204_233_Closed_Text&quot;&gt;&lt;img width=&quot;15&quot; height=&quot;20&quot; src=&quot;http://www.cnblogs.com/Images/dot.gif&quot; alt=&quot;&quot; /&gt;&lt;/span&gt;&lt;span id=&quot;Codehighlighter1_204_233_Open_Text&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;{ &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;FitDoor(); &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;AbstractChassis&amp;nbsp;CreateChassis() &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_278_310_Open_Text.style.display='none'; Codehighlighter1_278_310_Closed_Image.style.display='inline'; Codehighlighter1_278_310_Closed_Text.style.display='inline';&quot; id=&quot;Codehighlighter1_278_310_Open_Image&quot; alt=&quot;&quot; /&gt;&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_278_310_Closed_Text.style.display='none'; Codehighlighter1_278_310_Open_Image.style.display='inline'; Codehighlighter1_278_310_Open_Text.style.display='inline';&quot; style=&quot;display: none;&quot; id=&quot;Codehighlighter1_278_310_Closed_Image&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);&quot; id=&quot;Codehighlighter1_278_310_Closed_Text&quot;&gt;&lt;img width=&quot;15&quot; height=&quot;20&quot; src=&quot;http://www.cnblogs.com/Images/dot.gif&quot; alt=&quot;&quot; /&gt;&lt;/span&gt;&lt;span id=&quot;Codehighlighter1_278_310_Open_Text&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;{ &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;FitChassis(); &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/None.gif&quot; alt=&quot;&quot; /&gt; &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/None.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;OdysseyFactory &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_346_502_Open_Text.style.display='none'; Codehighlighter1_346_502_Closed_Image.style.display='inline'; Codehighlighter1_346_502_Closed_Text.style.display='inline';&quot; id=&quot;Codehighlighter1_346_502_Open_Image&quot; alt=&quot;&quot; /&gt;&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_346_502_Closed_Text.style.display='none'; Codehighlighter1_346_502_Open_Image.style.display='inline'; Codehighlighter1_346_502_Open_Text.style.display='inline';&quot; style=&quot;display: none;&quot; id=&quot;Codehighlighter1_346_502_Closed_Image&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);&quot; id=&quot;Codehighlighter1_346_502_Closed_Text&quot;&gt;&lt;img width=&quot;15&quot; height=&quot;20&quot; src=&quot;http://www.cnblogs.com/Images/dot.gif&quot; alt=&quot;&quot; /&gt;&lt;/span&gt;&lt;span id=&quot;Codehighlighter1_346_502_Open_Text&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;{ &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;AbstractDoor&amp;nbsp;CreateDoor() &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_385_418_Open_Text.style.display='none'; Codehighlighter1_385_418_Closed_Image.style.display='inline'; Codehighlighter1_385_418_Closed_Text.style.display='inline';&quot; id=&quot;Codehighlighter1_385_418_Open_Image&quot; alt=&quot;&quot; /&gt;&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_385_418_Closed_Text.style.display='none'; Codehighlighter1_385_418_Open_Image.style.display='inline'; Codehighlighter1_385_418_Open_Text.style.display='inline';&quot; style=&quot;display: none;&quot; id=&quot;Codehighlighter1_385_418_Closed_Image&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);&quot; id=&quot;Codehighlighter1_385_418_Closed_Text&quot;&gt;&lt;img width=&quot;15&quot; height=&quot;20&quot; src=&quot;http://www.cnblogs.com/Images/dot.gif&quot; alt=&quot;&quot; /&gt;&lt;/span&gt;&lt;span id=&quot;Codehighlighter1_385_418_Open_Text&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;{ &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;OdysseyDoor(); &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;AbstractChassis&amp;nbsp;CreateChassis() &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_463_499_Open_Text.style.display='none'; Codehighlighter1_463_499_Closed_Image.style.display='inline'; Codehighlighter1_463_499_Closed_Text.style.display='inline';&quot; id=&quot;Codehighlighter1_463_499_Open_Image&quot; alt=&quot;&quot; /&gt;&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_463_499_Closed_Text.style.display='none'; Codehighlighter1_463_499_Open_Image.style.display='inline'; Codehighlighter1_463_499_Open_Text.style.display='inline';&quot; style=&quot;display: none;&quot; id=&quot;Codehighlighter1_463_499_Closed_Image&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);&quot; id=&quot;Codehighlighter1_463_499_Closed_Text&quot;&gt;&lt;img width=&quot;15&quot; height=&quot;20&quot; src=&quot;http://www.cnblogs.com/Images/dot.gif&quot; alt=&quot;&quot; /&gt;&lt;/span&gt;&lt;span id=&quot;Codehighlighter1_463_499_Open_Text&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;{ &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;OdysseyChassis(); &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; &lt;br /&gt;
&lt;img width=&quot;11&quot; height=&quot;16&quot; align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;
&lt;p style=&quot;text-indent: 21pt;&quot; class=&quot;MsoNormal&quot;&gt;&amp;nbsp;&lt;br /&gt;
客户的调用：&lt;/p&gt;
&lt;div style=&quot;border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);&quot;&gt;&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/None.gif&quot; alt=&quot;&quot; /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;Client&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_22_561_Open_Text.style.display='none'; Codehighlighter1_22_561_Closed_Image.style.display='inline'; Codehighlighter1_22_561_Closed_Text.style.display='inline';&quot; id=&quot;Codehighlighter1_22_561_Open_Image&quot; alt=&quot;&quot; /&gt;&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_22_561_Closed_Text.style.display='none'; Codehighlighter1_22_561_Open_Image.style.display='inline'; Codehighlighter1_22_561_Open_Text.style.display='inline';&quot; style=&quot;display: none;&quot; id=&quot;Codehighlighter1_22_561_Closed_Image&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);&quot; id=&quot;Codehighlighter1_22_561_Closed_Text&quot;&gt;&lt;img src=&quot;http://www.cnblogs.com/Images/dot.gif&quot; alt=&quot;&quot; /&gt;&lt;/span&gt;&lt;span id=&quot;Codehighlighter1_22_561_Open_Text&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;{&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;private&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;AbstractDoor&amp;nbsp;_door;&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;private&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;AbstractChassis&amp;nbsp;_chassis;&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;private&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;HondaFactory&amp;nbsp;_factory;&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;void&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;GetACar(&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;seriesName)&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_167_326_Open_Text.style.display='none'; Codehighlighter1_167_326_Closed_Image.style.display='inline'; Codehighlighter1_167_326_Closed_Text.style.display='inline';&quot; id=&quot;Codehighlighter1_167_326_Open_Image&quot; alt=&quot;&quot; /&gt;&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_167_326_Closed_Text.style.display='none'; Codehighlighter1_167_326_Open_Image.style.display='inline'; Codehighlighter1_167_326_Open_Text.style.display='inline';&quot; style=&quot;display: none;&quot; id=&quot;Codehighlighter1_167_326_Closed_Image&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);&quot; id=&quot;Codehighlighter1_167_326_Closed_Text&quot;&gt;&lt;img src=&quot;http://www.cnblogs.com/Images/dot.gif&quot; alt=&quot;&quot; /&gt;&lt;/span&gt;&lt;span id=&quot;Codehighlighter1_167_326_Open_Text&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;{&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;.PrepareFactory(seriesName);&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;._door&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;._factory.CreateDoor();&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;._chassis&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;._factory.CreateChassis();&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 128, 0);&quot;&gt;//&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 128, 0);&quot;&gt;&amp;nbsp;TODO:&amp;nbsp;Make&amp;nbsp;a&amp;nbsp;car!&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 128, 0);&quot;&gt;&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif&quot; alt=&quot;&quot; /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;private&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;void&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;PrepareFactory(&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;seriesName)&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_380_558_Open_Text.style.display='none'; Codehighlighter1_380_558_Closed_Image.style.display='inline'; Codehighlighter1_380_558_Closed_Text.style.display='inline';&quot; id=&quot;Codehighlighter1_380_558_Open_Image&quot; alt=&quot;&quot; /&gt;&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_380_558_Closed_Text.style.display='none'; Codehighlighter1_380_558_Open_Image.style.display='inline'; Codehighlighter1_380_558_Open_Text.style.display='inline';&quot; style=&quot;display: none;&quot; id=&quot;Codehighlighter1_380_558_Closed_Image&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);&quot; id=&quot;Codehighlighter1_380_558_Closed_Text&quot;&gt;&lt;img src=&quot;http://www.cnblogs.com/Images/dot.gif&quot; alt=&quot;&quot; /&gt;&lt;/span&gt;&lt;span id=&quot;Codehighlighter1_380_558_Open_Text&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;{&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;switch&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;(seriesName)&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_407_554_Open_Text.style.display='none'; Codehighlighter1_407_554_Closed_Image.style.display='inline'; Codehighlighter1_407_554_Closed_Text.style.display='inline';&quot; id=&quot;Codehighlighter1_407_554_Open_Image&quot; alt=&quot;&quot; /&gt;&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif&quot; onclick=&quot;this.style.display='none'; Codehighlighter1_407_554_Closed_Text.style.display='none'; Codehighlighter1_407_554_Open_Image.style.display='inline'; Codehighlighter1_407_554_Open_Text.style.display='inline';&quot; style=&quot;display: none;&quot; id=&quot;Codehighlighter1_407_554_Closed_Image&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);&quot; id=&quot;Codehighlighter1_407_554_Closed_Text&quot;&gt;&lt;img src=&quot;http://www.cnblogs.com/Images/dot.gif&quot; alt=&quot;&quot; /&gt;&lt;/span&gt;&lt;span id=&quot;Codehighlighter1_407_554_Open_Text&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;{&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Fit&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;:&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;._factory&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;FitFactory();&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;break&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;;&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Odyssey&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;:&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;._factory&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;OdysseyFactory();&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;break&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;;&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;
&lt;img align=&quot;top&quot; src=&quot;http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif&quot; alt=&quot;&quot; /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p style=&quot;text-indent: 21pt;&quot; class=&quot;MsoNormal&quot;&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; 抽象工厂的优点很明显了，就是在需要用到一系列相关类的地方，它可以使我们不出错的创建出一系列的类实例，而我们在需要添加新的产品系列的时候，完全不需 要考虑其他系列的问题，仅需要将相关的抽象类（工厂已经产品）具体化就可以了。缺点也在这个地方，当工厂需要生产多一种产品（不是系列）的时候，改动将波 及所有类，比如，广本打算在每一辆汽车上装一个翅膀，那就需要在工厂中添加一个冲压机（以及各种车型的翅膀模具），还要在焊接科里添加这么一道工序，涂装 科以及总装科里面也一样要进行相应的调整。 &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-indent: 21pt;&quot; class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;工厂子类不一定需要实现父类的所有方法，但要使子类有用的话，我们必须使它的所有方法宣布具体化。这里，就引出几种做法：&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;、工厂父类可以就是一个接口，以确保其子类一定是具体的；&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;、我们可以继承抽象的父类，但不完全具体化，这样可以继续细分工厂子类；&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;、抽象的父类中含有具体的方法，这些方法也可以不加&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;virtual&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;修饰符。最后的这种方法可能是比较灵活一点的。&lt;/span&gt; &lt;/p&gt;
&lt;span style=&quot;font-family: 宋体;&quot;&gt;抽象工厂主要是用在需要一系列相关联的类协同工作的地方，而且这些系列的数量可能会变多，每一个系列完成的工作都不一样，但是调用接口却是一样的。另外，抽象工厂不适合这样一种情况，即每个系列内部的元素数量不能够确定，也就是说，当初设计的时候，系列中有&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;个配件，后面又涨成&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;个，之后又涨到&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;7&lt;/span&gt;&lt;span style=&quot;font-family: 宋体;&quot;&gt;个，这样的话，要改动的地方将多到让人受不了。&lt;/span&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/ideagracedocs/361097319/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/ideagracedocs/361097319/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><pubDate>Fri, 06 Jun 2008 19:36:42 +0800</pubDate><guid isPermaLink="false">http://www.ideagrace.com/html/doc/2008/06/06/08720.html</guid><fs:srclink>http://www.ideagrace.com/html/doc/2008/06/06/08720.html</fs:srclink><fs:srcfeed>http://www.ideagrace.com/rss.php</fs:srcfeed><fs:itemid>feedsky/ideagracedocs/~6170083/361097319/4278026</fs:itemid></item><item><title>在JavaScript中使用面向对象</title><link>http://www.ideagrace.com/html/doc/2008/05/30/08719.html</link><content:encoded>作者：Truly
日期：2007.7.24

前言

    OO(面向对象)概念的提出是软件开发工程发展的一次革命，多年来我们借助它使得很多大型应用程序得以顺利实现。如果您还没有掌握并使用OO进行程序设计和开发，那么您无疑还停留在软件开发的石器时代。大多数编程语言，尤其是近年问世的一些语言，都很好的支持了面向对象，您可能对此了如执掌，但是一些语言在OO方面却无法与其它高级语言相比，在这些语言上进行面向对象程序设计和开发会有些困难，例如本文要讨论的JavaScript。JavaScript是一门古老的语言，但是随着近期Web2.0 技术的热捧，这门语言又重新焕发出青春的光辉，借助于JavaScript客户端技术，我们的Web体验变得丰富而又精彩，为了设计和开发更加完善、复杂的客户端应用，我们必须掌握JavaScript上的OO方法，这正是本文要讨论的。 前几天阅读了MSDN的《使用面向对象的技术创建高级 Web 应用程序》一文，觉得还有些东西有必要继续探讨补充一下，就有了本文。

目录

开始
对象的声明
成员的声明
全局变量和局部变量
命名空间


开始

JavaScript是一门相当灵活的语言，语法也相当宽松，并且入门门槛很低，您可以不费什么力气就编写出一大堆可以运行的代码，但是根据我在实际工作中的经验，多数人还是对之核心技术知之甚少。同样一个功能，简简单单几行代码，就可看出一个人的技术功底。正如天龙八部中的萧峰使用的一招“太祖长拳”，这是一种武术中的入门的招法，虽然它看上去很简单，但是在高手的使用下，却是威力无穷。其实越是简单的东西，要把它变得完美就越是困难。所以作为能工巧匠的您怎能错过这篇文章？切听我一一道来。


对象的声明

在JavaScript我们可以使用下面几种代码进行对象声明：
var MyObject = {};

function MyObject()
{
    blablabla
}

var MyObject = function() { blablabla };

对于后两种方法，我们还可以增加参数，这样就类似于一个带参数的构造器了，例如：

function MyObject(msg)
{
    alert(msg);
}
var o = new MyObject('Hello world!');

var MyObject = function(msg)
{
    alert(msg + ' again');
};
var o = new MyObject('Hello world!');

甚至我们可以使用字符串来声明函数，这使得我们的程序更加灵活：
var MyObject = new Function(&quot;msg&quot;, &quot;alert(msg);&quot;); // Function可以有多个入口参数，最后一个参数作为方法体。

var o = new MyObject('Hello world!');

成员的声明

在JavaScript中，要声明一个对象的成员也非常简单，但是跟其它的高级程序仍然略有不同，请看下面的示例：
var MyObject = {
      FirstName:&quot;Mary&quot;, 
      LastName:&quot;Cook&quot;,
      Age:18, 
      ShowFullName : function(){
     alert(this.FirstName + ' ' + this.LastName);
       }
  }
  
MyObject.ShowFullName();

或者使用字符串来声明：
var MyObject = {
      &quot;FirstName&quot;:&quot;Mary&quot;, 
      &quot;LastName&quot;:&quot;Cook&quot;,
      &quot;Age&quot;:18, 
      &quot;ShowFullName&quot; : function(){
     alert(this.FirstName + ' ' + this.LastName);
       }
  }
  
MyObject.ShowFullName();

用字符串的声明方式有诸多好处，这也是JavaScript中表示对象的一种特殊方式，像近年JSON概念的提出，将这种特殊方式提示到了一个新的高度，更多JSON的介绍请参加我以前的大作《深入浅出JSON》。

而在实际的程序设计中，这种方式在JavaScript的面向对象程序设计中我们通常用来映射数据类型，定义类似高级语言中的结构，集合，实体等，还常常用作定义静态帮助器类，无需构造而可以直接访问成员方法。例如上面代码中的MyObject.ShowFullName();

前面我们介绍了成员的定义，在JavaScript中另一个面向对象特点是我们可以像高级编程语言一样使用.和[]引用成员，如：
var DateTime = { Now : new Date(), &quot;Show&quot; : function() { alert(new Date());} };

alert(DateTime.Now);
// 等价于：
alert(DateTime[&quot;Now&quot;]);

DateTime.Show()
// 等价于：
DateTime[&quot;Show&quot;]();

提到方法调用，这里有一些知识需要知道，在JavaScript中，所有的对象的基类是Object，基类通过prototype定义了很多成员和方法，例如toString, toLocaleString, valueOf等
这里我以toString()来做一介绍，请看下面示例：
var obj = { &quot;toString&quot; : function() { return &quot;This is an object.&quot;; } };
alert(obj);

我们注意到当alert的时候，toString()方法被调用了，事实上，当javascript需要将一个对象转换成字符串时就隐式调用这个对象的toString()方法，例如alert或者document.write或者字符串需要进行+运算等等。参加下面示例代码：
Date.prototype.toString = function(){ alert('This is called');}
var dt= new Date(new Date());

Date.prototype.toString = function(){ alert('This is called');}
var dt= new Date() + 1;

通过这个例子我们验证了这一点，即使一个对象作为入口参数也可能会调用其toString方法。除了这一点外，该示例同时演示了如何覆盖基类中定义的方法。


全局变量和局部变量

在JavaScript中，在全局上下文中声明的变量作为全局变量，而在对象或方法内部声明的对象则作为本地变量。请参见下面的代码：
var global = 1;
function mm()
{
    var global = 2; // 声明本地变量
    alert(this.global); // 等价于alert(global);
}
mm();
alert(this.global); // 等价于alert(global);

上面例子我们可以看出本地变量和全局变量即使同名也不会出现冲突。
另外 Javascript有一个特性就是变量不用声明就可以使用，在第一次使用一个未声明的变量时，系统会自动声明该变量，并将其作为全局变量。但是在构建大型应用程序的时候，这一点是非常具有破坏性的，如果该变量名在多个脚本块中出现，引起变量名冲突，导致严重的程序错误。因此，我们应该尽量避免使用全局变量，并且保持先声明后使用的良好习惯。

在JavaScript中this关键字是比较重要的一个特点，它会随调用对象而发生改变，始终与当前对象的上下文保持一致，这里一个例子让我们演示this并且同时继续深入研究toString,首先我们使用构造器方式创建一个对象，代码如下：
function obj(params){
toString = function() { return 'This is an object.'; }
} 

alert(new obj());

你会发现当运行这段代码的时候，浏览器将会抛出一个错误。
下面我们再看另外两段代码：
function obj(params){
aMethod = function() { return 'This is global method.'; }
} 
alert(new obj()); // 正常执行


function obj(params){
this.toString = function() { return 'This is local method.'; }
} 

alert(new obj()); // 正常执行

第一个函数声明虽没有使用this关键字，这时如果初始化对象那么将声明一个全局方法aMethod。第二个函数声明则为对象定义了一个自己的toString()方法。

当分析这两个函数的时候，你会注意到JavaScript的另一个特性，解释执行，所以
function obj(params){
aMethod = function() { return 'This is global method.'; }
} 
alert(aMethod()); // 此语句会报错

function obj(params){
aMethod = function() { return 'This is global method.'; }
}
new obj();  // 实例化的时候，声明了全局的aMethod()方法
alert(aMethod()); // 正常执行

通过上面的例子我们知道通过this非常重要，如果使用不当，可能造成全局函数的改变。有一点需要记住，绝不要调用包含“this”（却没有所属对象）的函数。否则，将违反全局命名空间，因为在该调用中，“this”将引用全局对象，而这必然会给您的应用程序带来灾难。
如下面的例子，当对象没有定义this指定的函数（isNaN）时，那么可能覆盖全局的同名函数, 看一些代码示例：

正确使用this的例子：
alert(isNaN(1)); // 全局函数isNaN
function obj(params){
    this.toString = function() { return 'This is an object.'; }
    this.isNaN = function() { 
        return &quot;not anymore!&quot;;
    };
}
var o = new obj(); // 正确的使用方式，调用构造函数
alert(o.isNaN(1)); // 此时obj定义中的this指向o这个实例而不是全局上下文
alert(isNaN(1)); // 全局函数未发生改变

错误的例子：
alert(isNaN(1)); // 全局函数isNaN
function obj(params){
    isNaN = function() { 
        return &quot;not anymore!&quot;;
    };
}
obj(); // 错误的使用方式，this指向全局上下文，全局函数isNaN被覆盖
alert(isNaN(1)); // 全局函数发生改变

同时我们还注意到有一些全局函数则无法覆盖，例如toString()

下面我们看JavaScript的一个很好用的方法: call

关于call的解释：
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。

可以这样来理解：
我们定义了一个函数abc：
function abc()
{
    alert(this.member1);
}
var obj = { member1:&quot;Hello world!&quot;, show:abc};
var obj2 = { member1:&quot;Hello world again!&quot;, show:abc};

obj.show();
//也可以使用
abc.call(obj);
abc.call(obj2);

修改后的另一个版本：
member1 = 'test';
function abc()
{
    alert(this.member1);
}
var obj = { member1:&quot;Hello world&quot;, show:abc};
var obj2 = { member1:&quot;Hello world again&quot;, show:abc};

obj.show();
//也可以使用
abc.call(obj);
abc.call(obj2);

abc(); // 此时abc中的this指向了当前上下文

每个函数都有call方法，上面的过程中我们看到用另一个对象代替调用显示方法，并注意到this在对象上下文中的改变。

通过上面基础知识的研究，让我们再向前跨出一步，使用call的特性来实现类继承，参见下面示例：
// 统一类构造器
function MyClassInitor()
{
    this.base();
    if(!this.mm)
     alert('未定义成员函数: mm()');
    
    return this;
}
// 定义一个基类
function baseClass()
{
    if(!this.tt) // 判断该成员是否被继承类覆盖
 this.tt = '基类成员';
}
// 从基类继承
var obj = { member1:&quot;Hello world&quot;, base:baseClass, gg:function(){ alert('I am an GG');}};
var obj2 = { member1:&quot;Hello world again&quot;, base:baseClass,mm:function(name){alert('I am MM '+name + '.');}, tt:&quot;覆盖基类的tt成员&quot;};

var o = MyClassInitor.call(obj);
var o2 = MyClassInitor.call(obj2);
alert(o.tt);
alert(o2.tt);
o2.mm('Mary');

虽然跟高级编程语言的语法有点不同，但是你必须了解JavaScript的语法特点。通过这个例子，我们什么分析了this和call的配合，但是实际进行类继承设计时往往不会采用此方法进行实现，后面我们介绍Prototype时再做详细介绍。

命名空间

前面我们了解完类、对象的声明，下面看一下Javascript中命名空间的处理，大家知道，在高级编程语言中我们非常熟练的使用命名空间来避免变量或方法名的冲突，那么同样我们也可以在JavaScript中使用命名空间来为我们的类和方法进行界定。在JavaScript中命名空间的声明与其它高级语言略有不同，下面是一个命名空间声明的示例：
var System = {};
var System.Web = {};

通过这两行代码我们就有了System和System.Web两个命名空间，回想一下前面我们介绍的知识，你很快可以发现，这是两个对象声明语句。在JavaScript中，我们正是使用对象来表示命名空间的。但是你必须清楚一点，由于 JavaScript的特性，在实际应用中，我们不能这么简单的来处理命名空间，因为声明语句可能同时出现在多个地方或者多个js文件中，我们知道，在 JavaScript中，最后声明的变量会覆盖前面同名的变量，因此通常我们要加一些判断代码来防止重复声明，例如：
if(typeof System == 'undefined') var System = {};

这样即使这段代码在程序中重复出现多次我们也可以保证System对象只声明一次。关于这一点，大家如果深入研究过AjaxPro和其它很多大型JavaScript框架，会发现当配合后端应用程序的时候，它是多么的有用。例如AjaxPro 的类型注册，关于AjaxPro可参见我另一篇文章《AjaxPro框架剖析》&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/ideagracedocs/361097320/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/ideagracedocs/361097320/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><pubDate>Fri, 30 May 2008 22:10:52 +0800</pubDate><guid isPermaLink="false">http://www.ideagrace.com/html/doc/2008/05/30/08719.html</guid><fs:srclink>http://www.ideagrace.com/html/doc/2008/05/30/08719.html</fs:srclink><fs:srcfeed>http://www.ideagrace.com/rss.php</fs:srcfeed><fs:itemid>feedsky/ideagracedocs/~6170083/361097320/4278026</fs:itemid></item><item><title>深入浅出JSON</title><link>http://www.ideagrace.com/html/doc/2008/05/30/08718.html</link><content:encoded>JSON定义

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式，易于阅读和编写，同时也易于机器解析和生成。它基于ECMA262语言规范（1999-12第三版）中JavaScript 编程语言的一个子集。 JSON采用与编程语言无关的文本格式，但是也使用了类C语言（包括C， C++， C#， Java， JavaScript， Perl， Python等）的习惯，这些特性使JSON成为理想的数据交换格式。

JSON的结构基于下面两点

    * 1. &quot;名称/值&quot;对的集合 不同语言中，它被理解为对象(object)，记录(record)，结构(struct)，字典(dictionary)，哈希表(hash table)，键列表(keyed list)等
    * 2. 值的有序列表 多数语言中被理解为数组(array)

JSON使用：

JSON以一种特定的字符串形式来表示 JavaScript 对象。如果将具有这样一种形式的字符串赋给任意一个 JavaScript 变量，那么该变量会变成一个对象引用，而这个对象就是字符串所构建出来的，好像有点拗口，我们还是用实例来说明。

 这里假设我们需要创建一个User对象，并具有以下属性
# 用户ID
# 用户名
# 用户Email

您可以使用以下JSON形式来表示User对象：

{&quot;UserID&quot;:11, &quot;Name&quot;:&quot;Truly&quot;, &quot;Email&quot;:&quot;zhuleipro◎hotmail.com&quot;};

然后如果把这一字符串赋予一个JavaScript变量，那么就可以直接使用对象的任一属性了。

完整代码:



实际使用时可能更复杂一点，比如我们为Name定义更详细的结构，使它具有FirstName和LastName：

{&quot;UserID&quot;:11, &quot;Name&quot;:{&quot;FirstName&quot;:&quot;Truly&quot;,&quot;LastName&quot;:&quot;Zhu&quot;}, &quot;Email&quot;:&quot;zhuleipro◎hotmail.com&quot;}

完整代码:



现在我们增加一个新的需求，我们某个页面需要一个用户列表，而不仅仅是一个单一的用户信息，那么这里就需要创建一个用户列表数组。
下面代码演示了使用JSON形式定义这个用户列表：

[
{&quot;UserID&quot;:11, &quot;Name&quot;:{&quot;FirstName&quot;:&quot;Truly&quot;,&quot;LastName&quot;:&quot;Zhu&quot;}, &quot;Email&quot;:&quot;zhuleipro◎hotmail.com&quot;},
{&quot;UserID&quot;:12, &quot;Name&quot;:{&quot;FirstName&quot;:&quot;Jeffrey&quot;,&quot;LastName&quot;:&quot;Richter&quot;}, &quot;Email&quot;:&quot;xxx◎xxx.com&quot;},
{&quot;UserID&quot;:13, &quot;Name&quot;:{&quot;FirstName&quot;:&quot;Scott&quot;,&quot;LastName&quot;:&quot;Gu&quot;}, &quot;Email&quot;:&quot;xxx2◎xxx2.com&quot;}
]


完整代码:



事实上除了使用&quot;.&quot;引用属性外，我们还可以使用下面语句：

alert(UserList[0][&quot;Name&quot;][&quot;FirstName&quot;]); 或者 alert(UserList[0].Name[&quot;FirstName&quot;]); 


现在读者应该对JSON的使用有点认识了，归纳为以下几点：
# 对象是属性、值对的集合。一个对象的开始于“{”，结束于“}”。每一个属性名和值间用“:”提示，属性间用“,”分隔。
# 数组是有顺序的值的集合。一个数组开始于&quot;[&quot;，结束于&quot;]&quot;，值之间用&quot;,&quot;分隔。
# 值可以是引号里的字符串、数字、true、false、null，也可以是对象或数组。这些结构都能嵌套。
# 字符串和数字的定义和C或Java基本一致。

小节：

本文通过一个实例演示，初步了解了JSON 的强大用途。可以归结如下：
# JSON 提供了一种优秀的面向对象的方法，以便将元数据缓存到客户机上。
# JSON 帮助分离了验证数据和逻辑。
# JSON 帮助为 Web 应用程序提供了 Ajax 的本质。

参考资料：
http://www.json.org/&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/ideagracedocs/361097321/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/ideagracedocs/361097321/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><pubDate>Fri, 30 May 2008 22:07:35 +0800</pubDate><guid isPermaLink="false">http://www.ideagrace.com/html/doc/2008/05/30/08718.html</guid><fs:srclink>http://www.ideagrace.com/html/doc/2008/05/30/08718.html</fs:srclink><fs:srcfeed>http://www.ideagrace.com/rss.php</fs:srcfeed><fs:itemid>feedsky/ideagracedocs/~6170083/361097321/4278026</fs:itemid></item><item><title>在Javascript中Eval函数的使用</title><link>http://www.ideagrace.com/html/doc/2008/05/29/08717.html</link><content:encoded>【eval()函数】

JavaScript有许多小窍门来使编程更加容易。
其中之一就是eval()函数，这个函数可以把一个字符串当作一个JavaScript表达式一样去执行它。
举个小例子：

var the_unevaled_answer = &quot;2 + 3&quot;;
var the_evaled_answer = eval(&quot;2 + 3&quot;);
alert(&quot;the un-evaled answer is &quot; + the_unevaled_answer + &quot; and the evaled answer is &quot; + the_evaled_answer);

如果你运行这段eval程序, 你将会看到在JavaScript里字符串&quot;2 + 3&quot;实际上被执行了。
所以当你把the_evaled_answer的值设成 eval(&quot;2 + 3&quot;)时, JavaScript将会明白并把2和3的和返回给the_evaled_answer。 
这个看起来似乎有点傻，其实可以做出很有趣的事。比如使用eval你可以根据用户的输入直接创建函数。
这可以使程序根据时间或用户输入的不同而使程序本身发生变化，通过举一反三，你可以获得惊人的效果。
在实际中，eval很少被用到，但也许你见过有人使用eval来获取难以索引的对象。 

文档对象模型（DOM)的问题之一是:有时你要获取你要求的对象简直就是痛苦。
例如，这里有一个函数询问用户要变换哪个图象:变换哪个图象你可以用下面这个函数：

function swapOne()
{
 var the_image = prompt(&quot;change parrot or cheese&quot;,&quot;&quot;);
 var the_image_object;

 if (the_image == &quot;parrot&quot;)
 {
  the_image_object = window.document.parrot;
 } 
 else 
 {
  the_image_object = window.document.cheese;
 }

 the_image_object.src = &quot;ant.gif&quot;;
}

连同这些image标记:

[img src=&quot;http://www.ideagrace.com//stuff3a/parrot.gif&quot; name=&quot;parrot&quot;]
[img src=&quot;http://www.ideagrace.com//stuff3a/cheese.gif&quot; name=&quot;cheese&quot;]

请注意象这样的几行语句：
      
the_image_object = window.document.parrot;

它把一个图象对象敷给了一个变量。虽然看起来有点儿奇怪，它在语法上却毫无问题。
但当你有100个而不是两个图象时怎么办？你只好写上一大堆的 if-then-else语句，要是能象这样就好了： 


function swapTwo()
{
 var the_image = prompt(&quot;change parrot or cheese&quot;,&quot;&quot;);
 window.document.the_image.src = &quot;ant.gif&quot;;
}

不幸的是, JavaScript将会寻找名字叫 the_image而不是你所希望的&quot;cheese&quot;或者&quot;parrot&quot;的图象，
于是你得到了错误信息：”没听说过一个名为the_image的对象”。 

还好，eval能够帮你得到你想要的对象。

function simpleSwap()
{
 var the_image = prompt(&quot;change parrot or cheese&quot;,&quot;&quot;);
 var the_image_name = &quot;window.document.&quot; + the_image;
 var the_image_object = eval(the_image_name);
 the_image_object.src = &quot;ant.gif&quot;;
}


如果用户在提示框里填入&quot;parrot&quot;，在第二行里创建了一个字符串即window.document.parrot. 然后包含了eval的第三
行意思是： &quot;给我对象window.document.parrot&quot; - 也就是你要的那个图象对象。一旦你获取了这个图象对象，你可以把
它的src属性设为ant.gif. 有点害怕？用不着。其实这相当有用，人们也经常使用它。

我们常常在Javascript中间到Eval这个函数，
有些人觉得这个函数很奇怪，可以把一些字符串变的功能很强大
在我们需要将普通的字符串转变成具体的对象的时候，就会用到这个函数

eval 函数对作为数字表达式的一个字符串进行求值，其语法为：

eval(expr)

此处 expr 是一个被求值的字符串参数。如果该字符串是一个表达式，eval 求该表达式的值；如果该参数代表一个或多个  JavaScript 语句，那么 eval 执行这些语句。eval 函数可以用来把一个日期从一种格式（总是字符串）转换为数值表达式或数字。

==============================
Eval 函数
功能：先解释Javascript代码，然后在执行它
用法：Eval(codeString)
codeString是包含有Javascript语句的字符串，在eval之后使用Javascript引擎编译。

注释：

例子：eval(id + &quot;_icon.src=&quot;http://www.ideagrace.com//imgs/collapse_up.gif'&quot;);
id是之前设定的参数，而在双引号中的字符串则是需要编译的

引用:
--------------------------------------------------------------------------------
function tophide(id)    //id indicates menu
{
    if (top.topframeset.rows == &quot;31,*&quot;)
    {
        top.topframeset.rows = &quot;86,*&quot;;
        eval(id + &quot;_icon.src=&quot;http://www.ideagrace.com//imgs/collapse_up.gif'&quot;);
        eval(id + &quot;_icon.alt='Collapse The Head'&quot;);
        head.style.display = &quot;block&quot;
        }
    else
    {
        top.topframeset.rows = &quot;31,*&quot;;
        eval(id + &quot;_icon.src=&quot;http://www.ideagrace.com//imgs/collapse_down.gif'&quot;);
        eval(id + &quot;_icon.alt='Expand The Head'&quot;);
        head.style.display = &quot;none&quot;
    } 
}&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/ideagracedocs/361097322/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/ideagracedocs/361097322/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><pubDate>Thu, 29 May 2008 19:19:31 +0800</pubDate><guid isPermaLink="false">http://www.ideagrace.com/html/doc/2008/05/29/08717.html</guid><fs:srclink>http://www.ideagrace.com/html/doc/2008/05/29/08717.html</fs:srclink><fs:srcfeed>http://www.ideagrace.com/rss.php</fs:srcfeed><fs:itemid>feedsky/ideagracedocs/~6170083/361097322/4278026</fs:itemid></item><item><title>深入认识javascript中的eval函数</title><link>http://www.ideagrace.com/html/doc/2008/05/29/08716.html</link><content:encoded>深入认识javascript中的eval函数
    分类：技术专区时间：2007-5-21 15:04:58作者：supNate
     
         发现为本文起一个合适的标题还不是那么容易，呵呵，所以在此先说明下本文的两个目的：
（1）介绍javascript中的eval函数的用法
（2）如何在函数内执行全局代码
    &amp;#9658;先来说eval的用法，内容比较简单，熟悉的可以跳过。
    eval函数接收一个参数s，如果s不是字符串，则直接返回s。否则执行s语句。如果s语句执行结果是一个值，则返回此值，否则返回undefined。
    需要特别注意的是对象声明语法“{}”并不能返回一个值，需要用括号括起来才会返回值，简单示例如下：
    var code1='&quot;a&quot; + 2';    //表达式
    var code2='{a:2}';      //语句
    alert(eval(code1));     //-&gt;'a2'
    alert(eval(code2));     //-&gt;undefined
    alert(eval('(' + code2 + ')'));    //-&gt;[object Object]
            可以看到，对于对象声明语句来说，仅仅是执行，并不能返回值。为了返回常用的“{}”这样的对象声明语句，必须用括号括住，以将其转换为表达式，才能返回其值。这也是使用JSON来进行Ajax开发的基本原理之一。在例子中可以清楚的看到，第二个alert语句输出的是undefined，而第三个加了括号后输出的是语句表示的对象。
                &amp;#9658;现在来说本文的重点，如何在函数内执行全局代码。为了说明这个问题，先看一个例子：
    var s='global';    //定义一个全局变量
    function demo1(){
        eval('var s=&quot;local&quot;');
    }
    demo1();
    alert(s);    //-&gt;global
             很好理解，上面的demo1函数等价于：function demo1(){var s='local';}，其中定义了一个局部变量s。
            所以最后的输出是global并不是什么奇怪的事情，毕竟大家都能很清楚的区分局部变量和全局变量。
            仔细体会一下，可以发现eval函数的特点，它总是在调用它的上下文变量空间（也称为：包，closure）内执行，无论是变量定义还是函数定义都是如此，所以如下的代码会产生函数未定义的错误：
    var s='function test(){return 1;}';     //一个函数定义语句
    function demo2(){
        eval(s);
    }
    demo2();
    alert(test());    //-&gt;error:test is not defined
            这是因为test函数在局部空间定义，demo2函数内可以访问到，外面就访问不到了。

             而在实际的Ajax开发中，有时我们需要从服务器动态获取代码来执行，以减轻一次载入代码过多的问题，或者是一些代码是通过Javascript自身生成的，希望用eval函数来使其执行。
    但这样的动态获取代码的工作一般在函数内完成，比如：
    function loadCode(){
        var code=getCode();
        eval(code);
    }
           可见eval不可能在全局空间内执行，这就给开发带来了不少问题，也看到过很多人为此郁闷。
            不过现在偶终于找到了解决办法，嘿嘿，可以同时兼容IE和Firefox，方法如下：
    var X2={}    //my namespace:)
    X2.Eval=function(code){
     if(!!(window.attachEvent &amp;&amp; !window.opera)){
      //ie
      execScript(code); 
     }else{
      //not ie
      window.eval(code);
     }
    }
            现在如果要想在函数内定义全局代码，就可以通过调用X2.Eval(code)方法，一个例子如下：
    var s='global';
    function demo3(){
     X2.Eval('var s=&quot;local&quot;');
    }
    demo3();
    alert(s); //-&gt;'local'
            可见，在demo3函数内重新定义了全局变量s=&quot;local&quot;。
            需要注意的是X2.Eval并不返回值，如果要进行表达式的求值，还是用系统的eval函数。X2.Eval设计为仅做全局代码定义用。
            其实看到这里，或许有人感觉问题也太容易解决了点，呵呵，但发现这个办法倒是需要些运气和技巧的：
    （1）对于IE浏览器，默认已经提供了这样的函数：execScript，用于在全局空间执行代码，只是知道的人还不多。
    （2）对于Firefox浏览器，直接调用eval函数，则在调用者的空间执行；如果调用       window.eval则在全局空间执行。这个知道的人估计就更少了。毕竟alert(eval==window.eval)返回true！
             Firefox的eval函数的特点的确是很令人奇怪的，但从javascript规范中倒也能找到其来源：
    If value of the eval property is used in any way other than a direct call (that is, other than by the explicit use of its
    name as an Identifier which is the MemberExpression in a CallExpression), or if the eval property is assigned to,
    an EvalError exception may be thrown.
          意思大概就是说eval函数的执行是和调用者相关的，但并没有说其执行上下文的问题。所以IE和Firefox孰是孰非也就很难说了，大家知道解决办法就好。
 
 
原文地址：http://www.x2blog.cn/supnate/#sid.1735/page.1/&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/ideagracedocs/361097323/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/ideagracedocs/361097323/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><pubDate>Thu, 29 May 2008 19:16:36 +0800</pubDate><guid isPermaLink="false">http://www.ideagrace.com/html/doc/2008/05/29/08716.html</guid><fs:srclink>http://www.ideagrace.com/html/doc/2008/05/29/08716.html</fs:srclink><fs:srcfeed>http://www.ideagrace.com/rss.php</fs:srcfeed><fs:itemid>feedsky/ideagracedocs/~6170083/361097323/4278026</fs:itemid></item><item><title>JavaScript 面向对象编程, 第一部分: 继承</title><link>http://www.ideagrace.com/html/doc/2008/05/29/08715.html</link><content:encoded>　　我们将向你展示 JavaScript 如何实现面向对象的语言中的: 继承. 同时, 这些例子将向你展示如何实现类的封装. 在此, 我们不会讨论多态实现.

　　虽然 JavaScript 是脚本语言, 但它所支持的面向对象编程也是非常强大的. 虽然它没有类和实例, 但它有对象, 原型和隐式的继承. 我们将会解释如何模拟继承及其超类与子类之间关系的形式. 原型是理解继承概念的关键, 我们将会教你如何建立原型, 如何检测一个对象是否是另外一个对象的原型, 及其 JavaScript 的模型与 Java 面向对象编程之间的区别. 我们同样会向你展示如何检测对象所包含的各种属性的方法. 在另外一篇文章里, 我还会详细地讲解有关 &quot;原型链 (prototype chain)&quot; 的知识.

　　本文大量地参考了 Webreference.com 中 &quot;Object-Oriented Programming with JavaScript, Part I: Inheritance&quot; 的内容, 许多内容我进行了详细的测试和再探讨, 以保证内容不会有太大的失误.
原文地址: http://www.webreference.com/js/column79/

　　面向对象语言的特点

　　面向对象设计是基于以下 3 个主要原理的: 封装, 继承和多态. 说某种程序语言是支持 OO (面向对象) 设计的, 只有在它的语法中支持以上 3 个概念才可以这么说. 这种语言应该为你提供某些方法, 以使你能很轻松地定义和使用这些范例. 封装涉及到了将某个对象变成一个 &quot;黑盒子&quot;的概念. 当你使用某个对象时, 你不用知道它内部是如何工作的, 你也不必理解对象是如何工作的. 这个对象只需将它绝对有用的信息以接口方式提供出来. 此对象应该给你提供友好的接口, 来让你可以使用其有限的属性集和方法集. 封装还有一层意思, 那就是说某个对象包含了它需要的每一样东西, 这包括数据和对于它的操作. 封装的概念非常的强大, 因为它允许将一个大的软件项目有效地分配给每个开发人员, 对于团队中的每个人, 他们只需要关注自己所实现的对象, 而不需要太多地关注于别人的实现. 开发项目中的开销使得开发团队中成员与接口的数量按指数级别增长. 封装是自 &quot;软件危机&quot; 以来最受欢迎的 OO 设计理念.

　　软件的复用是 OO 设计思想中另外一个重要的特点. 在软件体系中实现此思想的主要方法就是继承. 类就是定义对象的功能. 超类是某个新类, 或者说是子类被建立的来源类. 一个子类从它的超类中继承了所的方法和属性. 实际上, 所有的子类都是被自动地生成的, 因此节省了大量的工作. 你不需要一个一个地定义这些子类. 当然, 你可以重载那些继承下来的方法和属性. 事实上, 谁也没有指出哪个子类要建立得和其超类一模一样, 除非你没有重载任何的属性和方法.

　　多态可能是这个 3 个概念中最复杂的一个了. 其本质上是说, 每个对象都可以处理各种不同的数据类型. 你不必为处理不同的数据类型而建立不同的类. 其典型的例子就是画图的类, 你不必为实现画圆, 画矩形, 画椭圆而编写不同的类. 你可以建立一个足够聪明的类来调用特定的方法来操作特定的形状.

　　通过函数实现继承

　　虽然 JavaScript 不支持显示继承操作符, 但你可以通过其实方式实现隐式继承. 对于实现类的继承, 有 2 种比较常用的方式. 第一种将某个类定义成子类的方法是, 通过在负责定义子类函数的内部调用超类的构造函数. 看下面的示例:

// 超类构造函数
function superClass() {
  this.bye = superBye;
  this.hello = superHello;
}

// 子类构造函数
function subClass() {
  this.inheritFrom = superClass;
  this.inheritFrom();
  this.bye = subBye;
}

function superHello() {
  return &quot;Hello from superClass&quot;;
}
 
function superBye() {
  return &quot;Bye from superClass&quot;;
}

function subBye() {
  return &quot;Bye from subClass&quot;;
}

// 测试构造特性的函数
function printSub() {
  var newClass = new subClass();
  alert(newClass.bye());
  alert(newClass.hello());
}

　　当你运行上面的 printSub 函数时, 它会依次执行 subBuy 和 superHello 函数. 我们可以看到, bye 和 hello 方法最先在 superClass 中被定义了. 然而, 在 subClass 中, bye 方法又被重载了, subClass 构造函数头两行的功能只是做了一个简单的原始的继承操作, 但它是通过显示执行 inheritFrom 方法来完成的继承操作. 继承的过程先是将 superClass 的对象原型赋给 subClass 下的 inheritFrom 方法, 然后在执行完 superClass 的构造函数后, superClass 的属性就被自动地加到了 subClass 的属性列表中.这主要是由于在 subClass 中通过 this 来调用的 inheritFrom (也就是 superClass) 构造函数造成的, 通过此种方式调用 superClass 构造函数时, JavaScript 解释器会把 superClass 中的 this 与 subClass 中的 this 理解成位于同一个作用域下的 this 关键字, 所以就产生了继承的效果.

　　另外, 需要说明的是, 对于任何一个实例化的对象, 你任意地为它添加属性或方法, 如下所示:

  var newClass = new subClass();
  newClass.addprop = &quot;added property to instance object&quot;;

　　很明显, 通过此种方式添加的属性和方法只对当前实例化对象有效, 不会影响所有的同类型对象实例. 无疑, 它是你创造的一个独一无二的对象实例.

　　通过原型实现继承

　　第二种, 也是更强大的方法是通过建立一个超类对象, 然后将其赋值给子类对象的 prototype 属性, 以此方式来建立子类的继承. 假设我们的超类是 superClass, 子类是 subClass. 其 prototype 的赋值格式如下:

subClass.prototype = new superClass;

对于原型继承的实现方式, 让我们刚前面的代码改写一下, 示例如下:

// 超类构造函数
function superClass() {
  this.bye = superBye;
  this.hello = superHello;
}

// 子类构造函数
function subClass() {
  this.bye = subBye;
}
subClass.prototype = new superClass;

function superHello() {
  return &quot;Hello from superClass&quot;;
}
 
function superBye() {
  return &quot;Bye from superClass&quot;;
}

function subBye() {
  return &quot;Bye from subClass&quot;;
}

// 测试构造特性的函数
function printSub() {
  var newClass = new subClass();
  alert(newClass.bye());
  alert(newClass.hello());
}

　　我们可以看到, 除了将前面第一种继承方式中 subClass 中的前 2 行内容, 换成函数外的 prototype 赋值语句之外, 没有其它任何的变化, 但代码的执行效果和前面是一样的.

　　为已经建立的对象添加属性

　　通过原型实现的继承比通过函数实现的继承更好, 因为它支持动态继承. 你可以在构造函数已经完成之后, 再通过 prototype 属性定义超类的其它方法和属性, 并且其下的子类对象会自动地获得新的方法和属性. 下面是示例, 你可以看到它的效果.

function superClass() {
  this.bye = superBye;
  this.hello = superHello;
}

function subClass() {
  this.bye = subBye;
}
subClass.prototype = new superClass;

function superHello() {
  return &quot;Hello from superClass&quot;;
}
 
function superBye() {
  return &quot;Bye from superClass&quot;;
}

function subBye() {
  return &quot;Bye from subClass&quot;;
}

var newClass = new subClass();

/*****************************/
// 动态添加的 blessyou 属性
superClass.prototype.blessyou = superBlessyou;

function superBlessyou() {
  return &quot;Bless You from SuperClass&quot;;
}
/*****************************/

function printSub() {
  alert(newClass.bye());
  alert(newClass.hello());
  alert(newClass.blessyou());
}

　　这就是我们经常看到的为内部对象, 如 String, Math 等再添加其它属性和方法的技巧. 对于任何的内部对象和自定义对象, 你都也可以通过 prototype 来重载其下的属性和方法. 那么在调用执行时, 它将调用你所定义的方法和属性. 下面是示例:

// 为内部 String 对象添加方法
String.prototype.myMethod = function(){
  return &quot;my define method&quot;;
}

// 为内部 String 对象重载方法
String.prototype.toString = function(){
  return &quot;my define toString method&quot;;
}

var myObj = new String(&quot;foo&quot;);

alert(myObj.myMethod());
alert(myObj);
alert(&quot;foo&quot;.toString());

　　另外需要注意的是, 所有 JavaScript 内部对的 prototype 属性都是只读的. 你可以像上面那样为内部对象的原型添加或重载属性和方法，但不能更改该内部对象的 prototype 原型. 然而, 自定义对象可以被赋给新的原型. 也就是说, 像下面这样做是没有意思的.

function Employee() {
  this.dept = &quot;HR&quot;;
  this.manager = &quot;John Johnson&quot;;
}

String.prototype = new Employee;

var myString = new String(&quot;foo&quot;);

上面的程序在运行之后不会报错, 但显然, 如果你调用 myString.dept 将会得到一个非定义的值.

另外, 一个经常使用的是 prototype 下的 isPrototypeOf() 方法, 它主要用来判断指定对象是否存在于另一个对象的原型链中. 语法如下:

object1.prototype.isPrototypeOf(0bject2);

上面的格式是用来判断 Object2 是否出现 Object1 的原型链中. 示例如下:

function Person() {
  this.name = &quot;Rob Roberson&quot;;
  this.age = 31;
}

function Employee() {
  this.dept = &quot;HR&quot;;
  this.manager = &quot;John Johnson&quot;;
}

Employee.prototype = new Person();

var Ken = new Employee();

当执行 Employee.prototype.isPrototypeOf(Ken), Person.prototype.isPrototypeOf(Ken) 和 Object.prototype.isPrototypeOf(Ken) 时, 结果都会返回 true.

　　用于 Netscape 下的特定继承检测

　　在 Netscape 浏览器 4.x 到 6, 及其 Mozilla 系列浏览中, JavaScript 将对象间的原型关系存储在一个特殊的内部属性对象中, __proto__ (前后是 2 个下划线). 下面是一个示例:

function Shape() {
  this.borderWidth = 5;
}

function Square() {
  this.edge = 12;
}

Square.prototype = new Shape;

myPicture = new Square;

alert(myPicture.__proto__);
alert(myPicture.borderWidth);

　　由于脚本执行过 Square.prototype = new Shape 语句, 所以 myPicture 具有了一个指向 Shape 对象的内部属性 __proto__. 在脚本的执行过程中, 当要获取对象的某个属性值, 并且此对象是通过原型赋值而建立的某个对象, 在自身并没有对某个属性进行定义时, JavaScript 解析器会查看它的 __proto__ 属性对象, 也就它的原型对象, 然后枚举其原型中的所有属性, 而得出的结果要么是有这个属性, 要么是没有这个属性. 如果没有此属性, 再枚举原型对象下面的原型对象, 直到此过程真正的结束. 而所有的这些 JavaScript 引擎内部的操作, 我们是不会知道的, 下面的内容就是对这个问题的解释.

　　其实, 对于所有的自定义对象, 无论它有没有使用过 prototype 赋值操作, 它都具有一个 __proto__ 内部对象. 而如果某个对象是通过多层 prototype &quot;继承&quot; 来的, 所有的 &quot;继承&quot; 而来的属性却可以通过简单的一层循环遍历出来, 而不需要使用什么递归算法, 因为 JavaScript 引擎自动给我们做了. 示例如下:

function Shape() {
  this.borderWidth = 5;
}

function Square() {
  this.edge = 12;
}

function RoundSquare()
{
  this.radio = 0.5;
}

Square.prototype = new Shape;
RoundSquare.prototype = new Square;

var myPicture = new RoundSquare;

for (property in myPicture.__proto__) {
alert(property);
}

　　我们或者还可以通过更改后面的循环, 来遍历某个子类对象继承来的所有属性, 如下:

for (property in RoundSquare.prototype) {
alert(property);
}

　　如果你不怕麻烦, 我们甚至还可以通过级连的方式, 取出其构造函数中定义的原始属性值.

alert(myPicture.__proto__.__proto__.borderWidth);

　　无论你是否修改过此属性值, 通过上面语句所取出的属性值都是原始定义值. 让我们沿着这个思路再往下看, 下面的代码涉及到另外一个问题, 这个问题和原型链 (prototype chain) 有关. 代码如下:

function State() {
}

function City() {
}
City.prototype = new State;

function Street() {
}

Street.prototype = new City;

var UniversityAvenue = new Street();

function tryIt() {
  alert(UniversityAvenue.__proto__== Street.prototype);
  alert(UniversityAvenue.__proto__.__proto__==
   City.prototype);
  alert(UniversityAvenue.__proto__.__proto__.__proto__
   == State.prototype);
  alert(UniversityAvenue.__proto__.__proto__.__proto__.
   __proto__== Object.prototype);
  alert(UniversityAvenue.__proto__.__proto__.__proto__.
   __proto__.__proto__== null);
}

　　当执行 tryIt 函数时, 所有的显示均为 true. 也就是说, 子类对象的 prototype.__proto__ 总是等于超类对象的 prototype 属性; 超类对象的 prototype.__proto__ 总是等于 Object.prototype; Object.prototype.__proto__ 总是为 null; 而实例对象的 __proto__ 总是等于其类对象的 prototype, 这就是为什么任何自定义对象都具有 __proto__ 属性的原因. 对于上面的叙述, 其对应的代码如下:

Street.prototype.__proto__ == City.prototype     // true
State.prototype.__proto__ == Object.prototype    // true
Object.prototype.__proto__ == null               // true
UniversityAvenue.__proto__ == Street.prototype    // true

　　模拟实现 instanceOf 函数

　　根据上一节的内容, 我们了解了有关 Netscape 所支持的 __proto__ 特性的内容. 这一节, 我们将利用此特性来创建自己的实例对象检测函数.

　　许多时候, 我们都需要判断某个对象是否是由某个类来定义的, 在其它的语言里, 你可以通过 instanceOf 函数来实现此判断. 在 JavaScript 中同样提供了一个 instanceof 运行符, 而在 __proto__ 的基础上, 我们完全可以自己定义一个同样的函数, 虽然这看上去是在重复劳动, 但有助于我们更深刻地了解有关 __proto__ 的知识. 下面的代码只是用来说明功能, 在实际的应用中, 你不需要重复定义 instanceOf 函数, 使用 instanceof 运算符即可.&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/ideagracedocs/361097324/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/ideagracedocs/361097324/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><pubDate>Thu, 29 May 2008 18:38:40 +0800</pubDate><guid isPermaLink="false">http://www.ideagrace.com/html/doc/2008/05/29/08715.html</guid><fs:srclink>http://www.ideagrace.com/html/doc/2008/05/29/08715.html</fs:srclink><fs:srcfeed>http://www.ideagrace.com/rss.php</fs:srcfeed><fs:itemid>feedsky/ideagracedocs/~6170083/361097324/4278026</fs:itemid></item><item><title>JavaScript面向对象编程</title><link>http://www.ideagrace.com/html/doc/2008/05/29/08714.html</link><content:encoded>开始写javascript的时候都是自己写，后来发现了prototype.js框架，发现很好用，就一直用的，他的对象创建方法被修改了，但很好用，再后来又转用jquery框架，受此框架影响，也不用自己创建类了，渐渐的竟然忘记了如何自己定义类了，猛的给一个一般方法，竟然看着别扭，混淆了很多东西，忘记了很多东西。今天回头整理下。
一下方法参考prototype.js
程序代码 程序代码
  
    //类的定义
    
    //方法一：类的一般定义方法
    function player1(_name)
    {
        this.name = _name;
        this.say = function() {alert(this.name);};
    }
    
    var p1 = new player1('llinzzi1');
    p1.say();
    
    
    //方法二：prototype定义方法
    var player2 = function() {}
    player2.prototype = {
        name:'',
        say:function(){
            alert(this.name);
        }
    }
    
    var p2 = new player2();
    p2.name = 'llinzzi2';
    p2.say();
    
    
    //方法三：上面的方法结构美观，便捷，但构建函数不能带参数，修改方法
    var player3 = function() {
        this.init.apply(this, arguments);
    }
    player3.prototype = {
        init:function(_name){
            this.name = _name;
        },
        say:function(){
            alert(this.name);
        }
    }
    
    var p3 = new player3('llinzzi3');
    p3.say();
    
    //类的继承
    
    //方法一
    var player4 = function(){
        this.init.apply(this, arguments);
    }
    player4.prototype = new player3;
    player4.prototype.shout = function(){
        alert(this.name.toUpperCase());
    }
    
    var p4 = new player4('llinzzi4');
    p4.shout();
    
    
    //方法二 上面的方法不能采用{}的方法，修改方法
    Object.extend = function(destination, source) {
      for (var property in source)
        destination[property] = source[property];
      return destination;
    };
    
    var player5 = function(){
        this.init.apply(this, arguments);
    }
    Object.extend(Object.extend(player5.prototype,player3.prototype),{
        shout:function(){
            alert(this.name.toUpperCase());
        }
    
    });
  
    var p5 = new player5('llinzzi5');
    p5.shout();
    
    
    
    
    //再从prototype.js抄一端浏览器判断代码

    Browser = {
        IE:     !!(window.attachEvent &amp;&amp; !window.opera),
        Opera:  !!window.opera,
        WebKit: navigator.userAgent.indexOf('AppleWebKit/') &gt; -1,
        Gecko:  navigator.userAgent.indexOf('Gecko') &gt; -1 &amp;&amp; navigator.userAgent.indexOf('KHTML') == -1,
        MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
    }
    
    alert(Browser.MobileSafari);&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/ideagracedocs/361097325/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/ideagracedocs/361097325/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><pubDate>Thu, 29 May 2008 18:27:59 +0800</pubDate><guid isPermaLink="false">http://www.ideagrace.com/html/doc/2008/05/29/08714.html</guid><fs:srclink>http://www.ideagrace.com/html/doc/2008/05/29/08714.html</fs:srclink><fs:srcfeed>http://www.ideagrace.com/rss.php</fs:srcfeed><fs:itemid>feedsky/ideagracedocs/~6170083/361097325/4278026</fs:itemid></item><item><title>Struts2自定义Theme</title><link>http://www.ideagrace.com/html/doc/2008/05/27/08713.html</link><content:encoded>Template directory can be selected using several different rules, in this order:

   1. The templateDir attribute on the specific tag
   2. The page-scoped attribute named templateDir
   3. The request-scoped attribute named templateDir
   4. The session-scoped attribute named templateDir
   5. The application-scoped attribute named templateDir
   6. The struts.ui.templateDir property in struts.properties (defaults to template)

1. Struts2 Theme与WebWork Theme
     用法上是一样的，几乎没有差别，默认都是xhtm，区别就是将WebWork的配置改成了Struts的配置

2. Theme的作用
     Theme可以理解为模版，struts ui标签都有与之对应的模版，可以解压struts2-all-2.0.1.jar来看看，里面有template目录，打开xhtm查看struts ui标签对应的模版。我认为theme的作用如下：
    1） 统一考虑控件的外观和行为。例如对于文本框，有必填和非必填的，那么我们可以定制必填文本框的模版，在文本框后面带上红色的&quot;*&quot;，并且带required校验。
    2） 统一的布局风格，我们只关注内容而不必关注布局。例如对form，一个应用中有多个查询界面，所有的查询界面都采用同样的form模版，保持统一的风格。

3. 定制Theme
   1） 在WEB-INF下建立文件夹themes/mytheme
   2） 配置struts.properties，指定使用的theme
           struts.ui.theme = mytheme
           struts.ui.templateDir = /WEB-INF/themes
   3） text.ftl
   普通文本框
&lt;input type=&quot;text&quot;&lt;#rt/&gt;
 name=&quot;${parameters.name?default(&quot;&quot;)?html}&quot;&lt;#rt/&gt;
&lt;#if parameters.get(&quot;size&quot;)?exists&gt;
 size=&quot;${parameters.get(&quot;size&quot;)?html}&quot;&lt;#rt/&gt;
&lt;/#if&gt;
&lt;#if parameters.maxlength?exists&gt;
 maxlength=&quot;${parameters.maxlength?html}&quot;&lt;#rt/&gt;
&lt;/#if&gt;
&lt;#if parameters.nameValue?exists&gt;
 value=&quot;&lt;@s.property value=&quot;parameters.nameValue&quot;/&gt;&quot;&lt;#rt/&gt;
&lt;/#if&gt;
&lt;#if parameters.disabled?default(false)&gt;
 disabled=&quot;disabled&quot;&lt;#rt/&gt;
&lt;/#if&gt;
&lt;#if parameters.readonly?default(false)&gt;
 readonly=&quot;readonly&quot;&lt;#rt/&gt;
&lt;/#if&gt;
&lt;#if parameters.tabindex?exists&gt;
 tabindex=&quot;${parameters.tabindex?html}&quot;&lt;#rt/&gt;
&lt;/#if&gt;
&lt;#if parameters.id?exists&gt;
 id=&quot;${parameters.id?html}&quot;&lt;#rt/&gt;
&lt;/#if&gt;
&lt;#if parameters.cssClass?exists&gt;
 class=&quot;${parameters.cssClass?html}&quot;&lt;#rt/&gt;
&lt;/#if&gt;
&lt;#if parameters.cssStyle?exists&gt;
 style=&quot;${parameters.cssStyle?html}&quot;&lt;#rt/&gt;
&lt;/#if&gt;
&lt;#if parameters.title?exists&gt;
 title=&quot;${parameters.title?html}&quot;&lt;#rt/&gt;
&lt;/#if&gt;
/&gt;

required text
&lt;input type=&quot;text&quot;&lt;#rt/&gt;
 name=&quot;${parameters.name?default(&quot;&quot;)?html}&quot;&lt;#rt/&gt;
&lt;#if parameters.get(&quot;size&quot;)?exists&gt;
 size=&quot;${parameters.get(&quot;size&quot;)?html}&quot;&lt;#rt/&gt;
&lt;/#if&gt;
&lt;#if parameters.maxlength?exists&gt;
 maxlength=&quot;${parameters.maxlength?html}&quot;&lt;#rt/&gt;
&lt;/#if&gt;
&lt;#if parameters.nameValue?exists&gt;
 value=&quot;&lt;@s.property value=&quot;parameters.nameValue&quot;/&gt;&quot;&lt;#rt/&gt;
&lt;/#if&gt;
&lt;#if parameters.disabled?default(false)&gt;
 disabled=&quot;disabled&quot;&lt;#rt/&gt;
&lt;/#if&gt;
&lt;#if parameters.readonly?default(false)&gt;
 readonly=&quot;readonly&quot;&lt;#rt/&gt;
&lt;/#if&gt;
&lt;#if parameters.tabindex?exists&gt;
 tabindex=&quot;${parameters.tabindex?html}&quot;&lt;#rt/&gt;
&lt;/#if&gt;
&lt;#if parameters.id?exists&gt;
 id=&quot;${parameters.id?html}&quot;&lt;#rt/&gt;
&lt;/#if&gt;
&lt;#if parameters.cssClass?exists&gt;
 class=&quot;${parameters.cssClass?html}&quot;&lt;#rt/&gt;
&lt;/#if&gt;
&lt;#if parameters.cssStyle?exists&gt;
 style=&quot;${parameters.cssStyle?html}&quot;&lt;#rt/&gt;
&lt;/#if&gt;
&lt;#if parameters.title?exists&gt;
 title=&quot;${parameters.title?html}&quot;&lt;#rt/&gt;
&lt;/#if&gt;
/&gt;
&lt;span style=&quot;color:red&quot;&gt;*&lt;/span&gt;

下面的一行使用requiredtext模版
&lt;s:textfield label=&quot;%{getText('username')}&quot; name=&quot;username&quot; template=&quot;requiredtext.ftl&quot;/&gt;

参考：http://www.jscud.com/srun/news/viewhtml/4_2006_3/182.htm&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/ideagracedocs/361097326/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/ideagracedocs/361097326/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><pubDate>Tue, 27 May 2008 23:35:23 +0800</pubDate><guid isPermaLink="false">http://www.ideagrace.com/html/doc/2008/05/27/08713.html</guid><fs:srclink>http://www.ideagrace.com/html/doc/2008/05/27/08713.html</fs:srclink><fs:srcfeed>http://www.ideagrace.com/rss.php</fs:srcfeed><fs:itemid>feedsky/ideagracedocs/~6170083/361097326/4278026</fs:itemid></item></channel></rss>
