﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-我的隐式生活（My Implicit Life）-随笔分类-&lt;b&gt;-=Design Pattern=-&lt;/b&gt;</title><link>http://www.blogjava.net/marco/category/7337.html</link><description>&lt;b&gt;继续搞“对象”，玩OO.&lt;/b&gt;
</description><language>zh-cn</language><lastBuildDate>Thu, 01 Mar 2007 02:36:05 GMT</lastBuildDate><pubDate>Thu, 01 Mar 2007 02:36:05 GMT</pubDate><ttl>60</ttl><item><title>&lt;b&gt;Swing联想杂忆&lt;/b&gt;</title><link>http://www.blogjava.net/marco/archive/2006/03/14/35154.html</link><dc:creator>marco</dc:creator><author>marco</author><pubDate>Mon, 13 Mar 2006 17:51:00 GMT</pubDate><guid>http://www.blogjava.net/marco/archive/2006/03/14/35154.html</guid><wfw:comment>http://www.blogjava.net/marco/comments/35154.html</wfw:comment><comments>http://www.blogjava.net/marco/archive/2006/03/14/35154.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/marco/comments/commentRss/35154.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/marco/services/trackbacks/35154.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 关键字：Observer Pattern、Java Thread、Java Swing Application1 近来的阅读近来寒暑不常，希自珍慰。武汉天气不是狂冷，就是狂热，不时还给我整个雪花，就差冰雹了。&nbsp;自己做的事吧，也没有什么劲儿。看看自己喜欢的东西，等着希望中的学校能给我offers（是复数），看着自己想去又不想去的公司的未来同事在群里面幻想未来的样子，别操你大...&nbsp;&nbsp;<a href='http://www.blogjava.net/marco/archive/2006/03/14/35154.html'>阅读全文</a><img src ="http://www.blogjava.net/marco/aggbug/35154.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/marco/" target="_blank">marco</a> 2006-03-14 01:51 <a href="http://www.blogjava.net/marco/archive/2006/03/14/35154.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OO设计原则体会 </title><link>http://www.blogjava.net/marco/archive/2006/02/27/32568.html</link><dc:creator>marco</dc:creator><author>marco</author><pubDate>Sun, 26 Feb 2006 23:40:00 GMT</pubDate><guid>http://www.blogjava.net/marco/archive/2006/02/27/32568.html</guid><wfw:comment>http://www.blogjava.net/marco/comments/32568.html</wfw:comment><comments>http://www.blogjava.net/marco/archive/2006/02/27/32568.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/marco/comments/commentRss/32568.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/marco/services/trackbacks/32568.html</trackback:ping><description><![CDATA[<P>这几天瞄了几本设计模式的书，没有细看具体模式啦，而是老是琢磨那些深奥无比的话。这些话经常出现在计算机的书籍中，很有禅意，也有哲理。听说，高手就喜欢写点这样的话。</P>
<P>还有就是细心体味了一下OO的设计原则，这些原则是凌驾于模式之上的，也就是更宏观的原则。</P>
<P>其中，最高指导的一个就是“开－闭”原则。别的原则，里氏代换原则、依赖倒置原则、组合/聚合复用原则和迪米特法则都是为了达到“开－闭”原则而出现的规则。</P>
<P>这些原则告诉我很多东西，聚焦于一点就是要“面向抽象”来做一切事情。</P>
<P>分析对象的时候，要多分析设计“抽象”的概念，对象之间的联系要多基于抽象的概念而不是具体，这样具体才能能够变化，这样才是开闭。用我自己的话就是要“游走于 抽象”。</P>
<P>这里有一个我必须记住的就是，在封装变化时候，多用聚合/组合，少用继承。在封装原子变化并且是同类型对象时才用继承，别的都尽量用聚合/组合。而且尽量不要用多级继承，多级继承一般意味着有两种变化脉络，可能的话，让两种变化脉络独立演化。很明显，一独立演化，又要聚合/组合了。</P>
<P>还有一个必须记住的是：运用抽象以后，客户端的使用发生了巨大的变化。不再是指那儿用那儿。而是要做更多的准备工作，因为运用抽象，本身就把具体“组合”的职责推迟到使用的阶段。那谁使用，肯定是客户端。所以，客户端的使用要革新。要习惯用工厂，习惯把一系列的抽象定具体了，并按照一定方式“组合”起来用。而且，最终要善于用接口来调用方法。<BR><BR>用小飞推荐的一个工具画了个图，如下：<BR><IMG height=302 alt=o_好的OO思想.jpg src="http://www.blogjava.net/images/blogjava_net/marco/7898/o_好的OO思想.jpg" width=800 border=0><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MARCO ZHANG 2006年2月27日7:18:57</P><img src ="http://www.blogjava.net/marco/aggbug/32568.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/marco/" target="_blank">marco</a> 2006-02-27 07:40 <a href="http://www.blogjava.net/marco/archive/2006/02/27/32568.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>&lt;b&gt;Java Web Application开发日志之五&lt;/b&gt;&lt;br&gt;－－“design with the think of sharing objects”，Flyweight模式应用</title><link>http://www.blogjava.net/marco/archive/2006/02/23/32097.html</link><dc:creator>marco</dc:creator><author>marco</author><pubDate>Thu, 23 Feb 2006 06:14:00 GMT</pubDate><guid>http://www.blogjava.net/marco/archive/2006/02/23/32097.html</guid><wfw:comment>http://www.blogjava.net/marco/comments/32097.html</wfw:comment><comments>http://www.blogjava.net/marco/archive/2006/02/23/32097.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/marco/comments/commentRss/32097.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/marco/services/trackbacks/32097.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体"></SPAN></P><B><SPAN style="FONT-SIZE: 14pt; FONT-FAMILY: 宋体"><BR>“共享”的思想</SPAN></B><B><SPAN lang=EN-US style="FONT-SIZE: 14pt"><?xml:namespace prefix = o /><o:p></o:p></SPAN></B> 
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体">共享的</SPAN><SPAN lang=EN-US>idea</SPAN><SPAN style="FONT-FAMILY: 宋体">是生活中最基本的</SPAN><SPAN lang=EN-US>idea</SPAN><SPAN style="FONT-FAMILY: 宋体">，不必有意的使用，到处已经存在了。在生活中，大部分事物都是被多人多次使用的，这都是共享的实际应用。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B><SPAN style="FONT-SIZE: 14pt; FONT-FAMILY: 宋体">之于</SPAN></B><B><SPAN lang=EN-US style="FONT-SIZE: 14pt">OO</SPAN></B><B><SPAN style="FONT-SIZE: 14pt; FONT-FAMILY: 宋体">的共享</SPAN></B><B><SPAN lang=EN-US style="FONT-SIZE: 14pt"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>OO</SPAN><SPAN style="FONT-FAMILY: 宋体">中的共享，无非就是说让“对象”也能被“多人多次”（这里的“人”也无非就是进程、线程而已）使用，更详细的说，就是要让对象的生存空间更大一些，生存周期更长一些。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体">自己闷个儿脑子，提炼出了几个需要使用共享的环境（</SPAN><SPAN lang=EN-US>context</SPAN><SPAN style="FONT-FAMILY: 宋体">），也可以说是原因吧：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt"><SPAN lang=EN-US><SPAN>1.<SPAN style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体">为了保持“对象”的一致，我们需要共享。例如，“国家主席”就一个，不能多了，如果多了，难免决策混乱。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt"><SPAN lang=EN-US><SPAN>2.<SPAN style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体">为了控制“对象”的存储空间，我们需要共享。毕竟，目前来说，系统的</SPAN><SPAN lang=EN-US>memory</SPAN><SPAN style="FONT-FAMILY: 宋体">还是编程时最珍贵的资源。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt"><SPAN lang=EN-US><SPAN>3.<SPAN style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体">为了优化“对象”的创建消耗，我们需要共享。如果，一个对象的创建过程消耗太大，系统不能支持频繁的创建，共享的使用它也是一个好主意。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt"><SPAN lang=EN-US><SPAN>4.<SPAN style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体">等等。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体">而在实际的应用中，往往我并没有细想“我为什么使用共享？”，已经不自觉的就用了；如果真的认真分析起来，基于的环境也是多样，并不会只是上面的其中一种。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B><SPAN style="FONT-FAMILY: 宋体">常用的“共享”方法或模式（我曾经用过的，知道的不多，望谅解）：</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt"><SPAN lang=EN-US><SPAN>1.<SPAN style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体">“</SPAN><SPAN lang=EN-US>Singleton</SPAN><SPAN style="FONT-FAMILY: 宋体">模式”：一个</SPAN><SPAN lang=EN-US>class</SPAN><SPAN style="FONT-FAMILY: 宋体">就一个对象实例，大家都用它，满足</SPAN><SPAN lang=EN-US>context1</SPAN><SPAN style="FONT-FAMILY: 宋体">。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt"><SPAN lang=EN-US><SPAN>2.<SPAN style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体">“</SPAN><SPAN lang=EN-US>pool</SPAN><SPAN style="FONT-FAMILY: 宋体">技术”：只提供一定数目的对象，大家都用他们，实现</SPAN><SPAN lang=EN-US>context2</SPAN><SPAN style="FONT-FAMILY: 宋体">、</SPAN><SPAN lang=EN-US>context3</SPAN><SPAN style="FONT-FAMILY: 宋体">。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt"><SPAN lang=EN-US><SPAN>3.<SPAN style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体">“</SPAN><SPAN lang=EN-US>flyweight</SPAN><SPAN style="FONT-FAMILY: 宋体">模式”：一个</SPAN><SPAN lang=EN-US>class</SPAN><SPAN style="FONT-FAMILY: 宋体">的一个状态就一个对象实例，实现一个状态对象的共享，实现</SPAN><SPAN lang=EN-US>context2</SPAN><SPAN style="FONT-FAMILY: 宋体">、</SPAN><SPAN lang=EN-US>context3</SPAN><SPAN style="FONT-FAMILY: 宋体">。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B><SPAN style="FONT-FAMILY: 宋体">使用时要注意的地方：</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt"><SPAN lang=EN-US><SPAN>1.<SPAN style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体">确定共享的</SPAN><SPAN lang=EN-US>scope</SPAN><SPAN style="FONT-FAMILY: 宋体">。例如，在</SPAN><SPAN lang=EN-US>Java Web Application</SPAN><SPAN style="FONT-FAMILY: 宋体">中就是选择是</SPAN><SPAN lang=EN-US>page</SPAN><SPAN style="FONT-FAMILY: 宋体">，</SPAN><SPAN lang=EN-US>session</SPAN><SPAN style="FONT-FAMILY: 宋体">还是</SPAN><SPAN lang=EN-US>application</SPAN><SPAN style="FONT-FAMILY: 宋体">，当然也可以是</SPAN><SPAN lang=EN-US>jvm</SPAN><SPAN style="FONT-FAMILY: 宋体">级别的</SPAN><SPAN lang=EN-US>static</SPAN><SPAN style="FONT-FAMILY: 宋体">。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt"><SPAN lang=EN-US><SPAN>2.<SPAN style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体">确认</SPAN><SPAN lang=EN-US>thread safe</SPAN><SPAN style="FONT-FAMILY: 宋体">。当共享的对象可能被多个线程共享时，这是不可以回避的问题。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt"><SPAN lang=EN-US><SPAN>3.<SPAN style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体">应对对象状态的变化。一旦共享的对象发生了变化，我们怎么处理？改变之，舍弃之？也是我们需要确定的。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B><SPAN style="FONT-SIZE: 14pt; FONT-FAMILY: 宋体">项目中的应用：</SPAN></B><B><SPAN lang=EN-US style="FONT-SIZE: 14pt"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B><SPAN style="FONT-FAMILY: 宋体">项目需求：</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体">为学校的同学提供</SPAN><SPAN lang=EN-US>Web</SPAN><SPAN style="FONT-FAMILY: 宋体">查询，查询的内容有很多。其中，“查课表”、“查考表”是最为关键的需求，以后可能还要提供“查询空闲自习教室”的功能。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体">在这些查询中，有一个共同点，就是都涉及“教室”这一对象。“查课表”时要告诉同学在哪个教室上课，“查考表”时要告诉同学在哪个教室考试，等等。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B><SPAN style="FONT-FAMILY: 宋体">数据库设计：</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体">对于“查课表”用例，有关的数据库设计如下：</SPAN><SPAN lang=EN-US><o:p><BR><IMG style="WIDTH: 493px; HEIGHT: 416px" height=416 alt=o_5-1-1.jpg hspace=0 src="http://www.blogjava.net/images/blogjava_net/marco/7744/o_5-1-1.jpg" width=493 border=0>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B><SPAN style="FONT-FAMILY: 宋体"><BR>对象层的设计：<BR></SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><IMG height=529 alt=o_5-1.JPG src="http://www.blogjava.net/images/blogjava_net/marco/7744/o_5-1.JPG" width=308 border=0><BR>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体">学生每查询一门课程的课表，系统就会</SPAN><SPAN lang=EN-US>sql</SPAN><SPAN style="FONT-FAMILY: 宋体">查询“视图</SPAN><SPAN lang=EN-US>V_LESSONSCHEDULE</SPAN><SPAN style="FONT-FAMILY: 宋体">”，进而生成一个</SPAN><SPAN lang=EN-US>LessonSchedule</SPAN><SPAN style="FONT-FAMILY: 宋体">对象，然后返回给用户显示。当然，在生成这个</SPAN><SPAN lang=EN-US>LessonSchedule</SPAN><SPAN style="FONT-FAMILY: 宋体">对象的过程中，属于它的</SPAN><SPAN lang=EN-US>Classroom</SPAN><SPAN style="FONT-FAMILY: 宋体">对象，以及更深一步的</SPAN><SPAN lang=EN-US>Building</SPAN><SPAN style="FONT-FAMILY: 宋体">、</SPAN><SPAN lang=EN-US>Area</SPAN><SPAN style="FONT-FAMILY: 宋体">对象都会生成。下面就是这个过程的顺序图：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;<BR></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><IMG height=391 alt=o_5-2.JPG src="http://www.blogjava.net/images/blogjava_net/marco/7744/o_5-2.JPG" width=604 border=0>&nbsp;<BR></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体"><BR>因此，每生成一个“课表”对象（</SPAN><SPAN lang=EN-US>LessonSchedule</SPAN><SPAN style="FONT-FAMILY: 宋体">）或“考表”对象（</SPAN><SPAN lang=EN-US>ExamSchedule</SPAN><SPAN style="FONT-FAMILY: 宋体">）时，都要：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt"><SPAN lang=EN-US><SPAN>1.<SPAN style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体">查数据库中的教室、教学楼、校区的信息；</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt"><SPAN lang=EN-US><SPAN>2.<SPAN style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体">创建相应的“教室对象”（包括了属于它的“教学楼”对象和“校区”对象）。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B><SPAN style="FONT-FAMILY: 宋体">考虑共享“教室”对象</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体">“教室”对象一旦可以生成以后，完全可以给后续共享使用，不必要每个查询都要去生成。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体">详细说是基于下面的考虑：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt"><SPAN lang=EN-US><SPAN>1.<SPAN style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体">这类查询用例（查课表，查考表）发生的频繁很高很高，也就是说，一旦让用户查起来，系统中会产生大量的“教室”对象这类对象，应该说会占很大的内存空间。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt"><SPAN lang=EN-US><SPAN>2.<SPAN style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体">共享“教室”对象后，可以减少对数据库的查询次数，并降低了查询粒度（以前是基于二级视图查询，现在可以基于基本表查询），提高了一点数据库查询性能。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P><SPAN style="FONT-FAMILY: 宋体">
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当然，同时我脑袋中也有反对的声音：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l0 level1 lfo2"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">1.<SPAN style="FONT: 7pt 'Times New Roman'"><FONT size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">虽说，这类查询会产生很多相同的“教室”对象，但是</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">JVM</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">本生提供的垃圾回收功能完全可以处理它。除非，“同时”有很多很多这类对象都在被使用，根本回收不了，才会造成内存短缺。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l0 level1 lfo2"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">2.<SPAN style="FONT: 7pt 'Times New Roman'"><FONT size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果，我以某种共享机制让这些“教室”对象，在系统中存在下来（延长了生命周期）了。而它们本身的数目就很多（如，我们学校就有××），可能还没有等你用上，系统已经挂了。另外，如果不是同时有很多查询需要，我留这么多“教室”对象在系统里，反而是占了内存，而不是优化了内存的使用。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l2 level1 lfo1"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">1.<SPAN style="FONT: 7pt 'Times New Roman'"><FONT size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">所有模式的通病――“增加了复杂度”。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结论：</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">经过我们分析，系统对于“教室”对象的重复使用，频繁程度非常高。一般，有</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">10</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个人同时使用，就有</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">5</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个人左右涉及的用例要使用“教室”对象。把它共享起来，还是有一定必要的。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">进一步考虑：</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">而实际上，我们可以进一步共享下去：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">除了让客户端共享“教室对象（</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Classroom</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）”外，还可以让“教室对象”共享“教学楼对象（</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Building</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）”，和让“教学楼对象”共享“校区对象（</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Area</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）”。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">因此，最终的共享是在三级上都实现。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 14pt"><FONT face="Times New Roman">Flyweight</FONT></SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 14pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模式：</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 14pt"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">特点：</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">书上说：“享元模式可以使系统中的大量小粒度对象被共享使用”。第一，对象出现的量要大，想必这比较好理解，很少使用的也就没有必要共享了；第二，要小粒度，我比较纳闷？难道对于大粒度对象就不行吗？可能书上认为，大粒度对象的共享已经占了比较大的空间，没有小对象那么有效吧。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">另外，书上还说，要使用“享元模式”，被共享的对象的状态（类别）要比较固定，这样就可以为每一个状态仅仅创建一个对象。当然，如果每次使用对象时，对象的状态都是不一样的，那就根本不存在共享这些对象的必要了。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">联系项目思考：</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">基于上面对项目的分析，“教室”、“教学楼”、“校区”对象都是在系统中会被大量使用的对象，而且粒度的确比较小；并且它们有固定的类别，而且不易改变。如校区对象，暂时就有</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">4</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个。教学楼可能</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">40</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">－</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">50</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个左右。很适合“享元模式”的使用环境。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">确定共享方式：</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l1 level1 lfo3"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">1.<SPAN style="FONT: 7pt 'Times New Roman'"><FONT size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">确定共享对象的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">scope</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。在本</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">web</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">程序中，这些共享对象的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">scope</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">理应是</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">application</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，而更简单的一个作法就是把这些对象设为</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">static</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，我选择后者。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l1 level1 lfo3"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">2.<SPAN style="FONT: 7pt 'Times New Roman'"><FONT size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">确认</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">thread safe</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。这些对象是可能被多个</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">servlet</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">访问的，也就是有可能存在多线程访问。但是，由于这些对象的可变性很差，一旦创建就不大可能变化。因此，我决定把这写共享对象设计成不变模式的，一旦创建就只会被读取，而不会改写，这样就不存在多线程控制的问题了。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l1 level1 lfo3"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">3.<SPAN style="FONT: 7pt 'Times New Roman'"><FONT size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">应对对象状态的变化，如某个教室的类型变了。这里采取的是舍弃的方法，为每个工厂添加了一个清空方法――</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">clear()</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，用于清空已经生成的共享对象。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设计类图：</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt -0.3pt; TEXT-INDENT: -80.85pt; mso-para-margin-left: -7.73gd; mso-char-indent-count: -7.67"><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US><?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><v:shapetype id=_x0000_t75 path="m@4@5l@4@11@9@11@9@5xe" coordsize="21600,21600" o:spt="75" o:preferrelative="t" filled="f" stroked="f"><v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"></v:f><v:f eqn="sum @0 1 0"></v:f><v:f eqn="sum 0 0 @1"></v:f><v:f eqn="prod @2 1 2"></v:f><v:f eqn="prod @3 21600 pixelWidth"></v:f><v:f eqn="prod @3 21600 pixelHeight"></v:f><v:f eqn="sum @0 0 1"></v:f><v:f eqn="prod @6 1 2"></v:f><v:f eqn="prod @7 21600 pixelWidth"></v:f><v:f eqn="sum @8 21600 0"></v:f><v:f eqn="prod @7 21600 pixelHeight"></v:f><v:f eqn="sum @10 21600 0"></v:f></v:formulas><v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></v:path><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:lock v:ext="edit" aspectratio="t"></o:lock></v:shapetype><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US><o:p><FONT face="Times New Roman"><IMG height=506 alt=o_5-3.JPG src="http://www.blogjava.net/images/blogjava_net/marco/7744/o_5-3.JPG" width=772 border=0>&nbsp;</FONT></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当然，也可以把这些工厂都设计成“</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Singleton</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模式”的，使它们只会有一个实例。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">客户端使用：</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">由于共享的对象都被包含在了“课表”和“考表”对象里，不会被客户端直接访问，因而不会对客户端的使用有任何影响：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">实例代码</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt">
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="COLOR: blue"><FONT face="Times New Roman"><o:p></o:p></FONT></SPAN></P><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US><o:p><FONT face="Times New Roman">&nbsp; 
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #008080">&nbsp;1</SPAN><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">取得编号为32号课程的“课表对象”</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #008080">&nbsp;2</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">&nbsp;3</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>LessonSchedule&nbsp;oneLesson&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;LessonSchedule.findByLessonNum(</SPAN><SPAN style="COLOR: #000000">32</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;4</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR></SPAN><SPAN style="COLOR: #008080">&nbsp;5</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>&nbsp;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;6</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR></SPAN><SPAN style="COLOR: #008080">&nbsp;7</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">获得教室对象</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #008080">&nbsp;8</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">&nbsp;9</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>Classroom&nbsp;oneClassroom&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;oneLesson.getLnkClassroom();<BR></SPAN><SPAN style="COLOR: #008080">10</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR></SPAN><SPAN style="COLOR: #008080">11</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>&nbsp;<BR></SPAN><SPAN style="COLOR: #008080">12</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR></SPAN><SPAN style="COLOR: #008080">13</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">获得教学楼对象</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #008080">14</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">15</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>Building&nbsp;oneBuilding&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;oneClassroom.getLnkBuilding();<BR></SPAN><SPAN style="COLOR: #008080">16</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR></SPAN><SPAN style="COLOR: #008080">17</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>&nbsp;<BR></SPAN><SPAN style="COLOR: #008080">18</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR></SPAN><SPAN style="COLOR: #008080">19</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">获得校区对象</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #008080">20</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">21</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>Area&nbsp;oneArea&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;oneBuilding.&nbsp;getLnkArea();<BR></SPAN><SPAN style="COLOR: #008080">22</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR></SPAN><SPAN style="COLOR: #008080">23</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>&nbsp;<BR></SPAN><SPAN style="COLOR: #008080">24</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR></SPAN><SPAN style="COLOR: #008080">25</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">再次重新生成一个编号为32号的“课表对象”</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #008080">26</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">27</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>LessonSchedule&nbsp;twoLesson&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;LessonSchedule.findByLessonNum(</SPAN><SPAN style="COLOR: #000000">32</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">28</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR></SPAN><SPAN style="COLOR: #008080">29</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>&nbsp;<BR></SPAN><SPAN style="COLOR: #008080">30</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR></SPAN><SPAN style="COLOR: #008080">31</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">获得教室对象</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #008080">32</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">33</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>Classroom&nbsp;twoClassroom&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;twoLesson.getLnkClassroom();<BR></SPAN><SPAN style="COLOR: #008080">34</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR></SPAN><SPAN style="COLOR: #008080">35</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>&nbsp;<BR></SPAN><SPAN style="COLOR: #008080">36</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR></SPAN><SPAN style="COLOR: #008080">37</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">获得教学楼对象</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #008080">38</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">39</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>Building&nbsp;twoBuilding&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;twoClassroom.getLnkBuilding();<BR></SPAN><SPAN style="COLOR: #008080">40</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR></SPAN><SPAN style="COLOR: #008080">41</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>&nbsp;<BR></SPAN><SPAN style="COLOR: #008080">42</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR></SPAN><SPAN style="COLOR: #008080">43</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">获得校区对象</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #008080">44</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">45</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>Area&nbsp;twoArea&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;twoBuilding.&nbsp;getLnkArea();<BR></SPAN><SPAN style="COLOR: #008080">46</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN></DIV></FONT></o:p></SPAN></B>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">oneClassroom</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">与</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">twoClassroom</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">；</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">oneBuilding</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">与</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">twoBuilding</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">；</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">oneArea</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">与</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">twoArea</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">由于都是</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">32</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">号课程的东西，根据我们的设计意图，应该实现共享。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">而实际上，它们每对的确是同一个对象的引用。因此，实现了预期的设想。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 14pt"><FONT face="Times New Roman">Review</FONT></SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 14pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">：</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 14pt"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在本项目中，当第一次设计出来的时候，我们发现了某些对象恰好有共享的需要。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">而更多的实际情况是，这些需要共享的“信息或状态”在设计中并不是那么恰好的表现为“一个对象”的粒度，而是要不就包含在一个对象内部，要不就跨几个对象。在这样的情况下，共享的设计更多是发生在代码重构阶段而不是第一的设计阶段。当然，为了共享对象而做出的代码重构，最重要的一步就是把需要共享的“信息或状态”设计成为新的对象。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对于，“享元模式”来说，就是要把需要共享的“信息或状态”设计成“享元对象”。别的在此就不说了，因为我也不懂了，呵呵。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MARCO ZHANG 2006年2月23日13:48:49<IMG height=19 src="http://www.blogjava.net/Emoticons/music.gif" width=19 border=0></SPAN></P><img src ="http://www.blogjava.net/marco/aggbug/32097.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/marco/" target="_blank">marco</a> 2006-02-23 14:14 <a href="http://www.blogjava.net/marco/archive/2006/02/23/32097.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>&lt;b&gt;Java Web Application开发日志之四&lt;/b&gt;&lt;br&gt;－－“make the method become dynamic”，“洋葱”模式应用</title><link>http://www.blogjava.net/marco/archive/2006/02/18/31429.html</link><dc:creator>marco</dc:creator><author>marco</author><pubDate>Sat, 18 Feb 2006 15:53:00 GMT</pubDate><guid>http://www.blogjava.net/marco/archive/2006/02/18/31429.html</guid><wfw:comment>http://www.blogjava.net/marco/comments/31429.html</wfw:comment><comments>http://www.blogjava.net/marco/archive/2006/02/18/31429.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/marco/comments/commentRss/31429.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/marco/services/trackbacks/31429.html</trackback:ping><description><![CDATA[<H3 style="MARGIN: 13pt 0cm"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=5>废话：</FONT></SPAN></H3>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">预料中的日志</SPAN><SPAN lang=EN-US>3</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">暂时生产不出来，话说难产就好，别夭折就行，有点掉价哦，呵呵。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p><FONT size=4>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>因为有些东西还没有想清楚。那就先搞个四吧，这个东西还是清楚那么一点的。</FONT></SPAN></P>
<H3 style="MARGIN: 13pt 0cm"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=5>一版描述：</FONT></SPAN></H3>
<TABLE class=MsoNormalTable style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: auto auto auto 5.4pt; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; mso-border-alt: solid windowtext .5pt; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" cellSpacing=0 cellPadding=0 border=1>
<TBODY>
<TR style="HEIGHT: 30.8pt; mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e0e0e0; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 72pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; HEIGHT: 30.8pt; mso-border-alt: solid windowtext .5pt" width=96>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align=center><B style="mso-bidi-font-weight: normal"><SPAN style="COLOR: navy; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">项目需求</SPAN><SPAN lang=EN-US style="COLOR: navy"><o:p></o:p></SPAN></B></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 342pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; HEIGHT: 30.8pt; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt" vAlign=top width=456>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">使每个</SPAN><SPAN lang=EN-US>servlet</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">能对用户访问权限进行检查。简单来说，就是要给每个</SPAN><SPAN lang=EN-US>servlet</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">加个锁，有钥匙的用户才能访问。</SPAN></P></TD></TR></TBODY></TABLE>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">而项目中用户所谓的访问权限是基于他拥有的角色。也就是说，</SPAN><SPAN lang=EN-US>servlet</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对用户访问权限的检查，就是对他所拥有角色的检查。暂时，每个用户只能拥有一个角色。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT size=4>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">项目的角色很多，但是在</SPAN><SPAN lang=EN-US>web</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">端暂时只有如下的三种：</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<TABLE class=MsoNormalTable style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: auto auto auto 5.4pt; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; mso-border-alt: solid windowtext .5pt; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" cellSpacing=0 cellPadding=0 border=1>
<TBODY>
<TR style="HEIGHT: 30.8pt; mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e0e0e0; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 90pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; HEIGHT: 30.8pt; mso-border-alt: solid windowtext .5pt" width=120>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align=center><B style="mso-bidi-font-weight: normal"><SPAN style="COLOR: navy; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">项目暂时角色</SPAN><SPAN lang=EN-US style="COLOR: navy"><o:p></o:p></SPAN></B></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 324pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; HEIGHT: 30.8pt; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt" width=432>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align=center><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">游客，学生，教师</SPAN></P></TD></TR></TBODY></TABLE>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">既然这样，</SPAN><SPAN lang=EN-US>servlet</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的加锁方式就有：</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<TABLE class=MsoNormalTable style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: auto auto auto 5.4pt; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; mso-border-alt: solid windowtext .5pt; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" cellSpacing=0 cellPadding=0 border=1>
<TBODY>
<TR style="HEIGHT: 30.8pt; mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e0e0e0; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 90pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; HEIGHT: 30.8pt; mso-border-alt: solid windowtext .5pt" width=120>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align=center><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: navy">servlet</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN style="COLOR: navy; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">加锁方式</SPAN><SPAN lang=EN-US style="COLOR: navy"><o:p></o:p></SPAN></B></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 324pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; HEIGHT: 30.8pt; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt" width=432>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align=center><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">&nbsp;</SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">游客，学生，教师，<BR>游客或学生，游客或教师，学生或教师，<BR>游客或学生或教师</SPAN></P></TD></TR></TBODY></TABLE>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="COLOR: #993300; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&nbsp;<FONT size=4>注：上面的“游客”就是“游客角色有权访问”的意思，依此类推。</FONT></SPAN><SPAN lang=EN-US style="COLOR: #993300"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT size=4>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这里只有关系“或”（</SPAN><SPAN lang=EN-US>||</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">），如果一个</SPAN><SPAN lang=EN-US>servlet</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的加锁方式是“学生或教师”，也就是说拥有学生或教师角色的用户都可以访问它。关系“与”（</SPAN><SPAN lang=EN-US>&amp;&amp;</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）在这里不太可能存在，因为没有需求说：某个</SPAN><SPAN lang=EN-US>servlet</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一定只能由“既是学生又是教师的用户”才能访问，而且前面也说了，暂时一个用户“有且只有”一个角色。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<TABLE class=MsoNormalTable style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BACKGROUND: #ccffff; MARGIN: auto auto auto 14.4pt; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; mso-border-alt: solid windowtext .5pt; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" cellSpacing=0 cellPadding=0 border=1>
<TBODY>
<TR style="HEIGHT: 15.75pt; mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 396pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; HEIGHT: 15.75pt; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt" vAlign=top width=528>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>So we can get following function</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">：<BR></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 黑体"><BR>“加锁方式数” ＝<SPAN lang=EN-US> 2</SPAN>的“角色数”次方 －<SPAN lang=EN-US> 1<BR><o:p></o:p></SPAN></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><BR>“加锁方式数”是关于“角色数”的指数函数，也就是说它是关于“角色数”成“指数级”增长的，应该说很快了吧。<BR></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><BR>3</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个角色就有</SPAN><SPAN lang=EN-US>2</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</SPAN><SPAN lang=EN-US>3</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">次方－</SPAN><SPAN lang=EN-US>1</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个，也就是</SPAN><SPAN lang=EN-US>7</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个加锁方式。</SPAN></P></TD></TR></TBODY></TABLE>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">运用</SPAN><SPAN lang=EN-US>OO</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的最基本方式，就是封装对象。既然有为</SPAN><SPAN lang=EN-US>servlet</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">“看门”的责任，那就把这个责任封装成一个对象，用个俗名：</SPAN><SPAN lang=EN-US>validator</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>接着，运用共性和个性的分析方法，既然有那么多种不同的看门方式（加锁方式），那就搞一个接口，然后让各种“不同”都实现这个接口，形成子类。那就有下面的图：</FONT><BR><BR><IMG height=511 alt=o_4-1.JPG src="http://www.blogjava.net/images/blogjava_net/marco/7574/o_4-1.JPG" width=616 border=0><BR><BR></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以看到，由于有</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">7</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个加锁方式，那就要有</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">7</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个子类。每个子类根据自己逻辑</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">override</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">validate</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman" size=4>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这样，对于一个</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">servlet</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，想让它上什么样的锁，只要让它拿到对应的子类的引用即可，如下图中的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ClientServlet</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，我们规定只能有“学生或教师”才能访问它。它的部分代码便是：</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><BR><IMG height=512 alt=o_4-2.JPG src="http://www.blogjava.net/images/blogjava_net/marco/7574/o_4-2.JPG" width=620 border=0></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt">&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt">&nbsp;</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #008080">1</SPAN><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">new对应的Validator接口的子类。<BR></SPAN><SPAN style="COLOR: #008080">2</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">这里是学生或教师可访问，因此要new&nbsp;Student_Or_Teacher_Validator</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #008080">3</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">Validator&nbsp;validator&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Student_Validator();<BR></SPAN><SPAN style="COLOR: #008080">4</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">然后调用验证方法就可以了</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #008080">5</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">boolean</SPAN><SPAN style="COLOR: #000000">&nbsp;ok&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;validator.validate();</SPAN></DIV></SPAN><BR>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>至此，第一个解决方案就出来了。</FONT><BR></P>
<H3 style="MARGIN: 13pt 0cm"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=5>思考：</FONT></SPAN></H3>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt">
<TABLE class=MsoNormalTable style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: auto auto auto 5.4pt; BORDER-LEFT: medium none; WIDTH: 441pt; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; mso-border-alt: solid windowtext .5pt; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" cellSpacing=0 cellPadding=0 width=588 border=1>
<TBODY>
<TR style="HEIGHT: 24pt; mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #99ccff; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 36pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; HEIGHT: 24pt; mso-border-alt: solid windowtext .5pt" width=48>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align=center><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">不足</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></B></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 405pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; HEIGHT: 24pt; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt" vAlign=top width=540>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">validator</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口的子类数目随“角色数”成“指数级”增长，数量太多；而且子类中重复逻辑的代码很多，如“</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student_Or_Teacher_Validator</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">”就重复了“</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student_Validator</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">”和“</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Teacher_Validator</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">”的逻辑，万一“</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student_Validator</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">”的逻辑要改，只要涉及</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的子类都要跟着改，维护上不方便。</SPAN></P></TD></TR></TBODY></TABLE></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt">
<TABLE class=MsoNormalTable style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: auto auto auto 5.4pt; BORDER-LEFT: medium none; WIDTH: 441pt; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; mso-border-alt: solid windowtext .5pt; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" cellSpacing=0 cellPadding=0 width=588 border=1>
<TBODY>
<TR style="HEIGHT: 6.75pt; mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #99ccff; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 54pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; HEIGHT: 6.75pt; mso-border-alt: solid windowtext .5pt" width=72>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align=center><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">进一步改进的可能</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></B></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 387pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; HEIGHT: 6.75pt; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt" vAlign=top width=516>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">“</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student_Or_Teacher_Validator</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类”的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">validate</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法很大程度上就是“</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student_Validator</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类”的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">validate</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法和“</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Teacher_Validator</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类”的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">validate</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法“或操作”出来的结果。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">因此，能不能考虑由“</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student_Validator</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">validate</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法”和“</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Teacher_Validator</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">validate</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法”<B style="mso-bidi-font-weight: normal"><SPAN style="COLOR: red">动态的构造</SPAN></B>一个功能如“</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student_Or_Teacher_Validator</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">validate</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法”。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这样，“</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student_Or_Teacher_Validator</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">”就可以省略了，只剩下一些原子的“角色类”。要实现</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student_Or_Teacher_Validator</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的验证功能，拿</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student_Validator</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Teacher_Validator</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">装配一下就可以了。</SPAN></P></TD></TR></TBODY></TABLE></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结论，需要根据实际情况，动态的改变（装配）“</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Validator</FONT></SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口对象”的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">validate</FONT></SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法。</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></B></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman" size=4>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>第一个火花就是“装饰模式”。它可以让客户端动态的组装对象的方法。真神奇！</FONT></SPAN></P>
<H3 style="MARGIN: 13pt 0cm"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=5>第二版来啦</FONT></SPAN></H3>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><IMG height=460 alt=o_4.JPG src="http://www.blogjava.net/images/blogjava_net/marco/7342/o_4.JPG" width=569 border=0></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="COLOR: #993300; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">注：上图中出现了</SPAN><SPAN lang=EN-US style="COLOR: #993300"><FONT face="Times New Roman">AndRelation</FONT></SPAN><SPAN style="COLOR: #993300; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US style="COLOR: #993300"><FONT face="Times New Roman">And</FONT></SPAN><SPAN style="COLOR: #993300; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的一系列角色类，可以暂时省略不看，因为前面说了，现在还没有“与”关系这个需求。只看</SPAN><SPAN lang=EN-US style="COLOR: #993300"><FONT face="Times New Roman">Or</FONT></SPAN><SPAN style="COLOR: #993300; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的就可以。</SPAN><SPAN lang=EN-US style="COLOR: #993300"><o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman" size=4>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>我喜欢叫这个模式为洋葱模式，一层包一层，最外层对象某方法的逻辑是由内部一层一层对象的同一方法组合出来的。</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman" size=4>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">使用了这个模式，便不用如一版那样实现那么多子类，只要实现几个“角色类”即可，这里有</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">3</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个（学生角色：</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Or_Student</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、教师角色：</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Or_Teacher</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、游客角色：</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Or_Guest</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）。所有一版中<B style="mso-bidi-font-weight: normal">别的</B>子类都可以由这</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">3</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个组装出来。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman" size=4>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如要生成一版中的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student_Or_Teacher_Validator</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象，可以用</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Or_Student</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Or_Teacher</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">两个对象“</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Or</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">”出来：</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN><SPAN lang=EN-US><FONT face="Times New Roman"></P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #008080">1</SPAN><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">Validator&nbsp;validator&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Or_Student(</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Or_Teacher(OrRelation(req)));</SPAN></DIV>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"></FONT></SPAN><SPAN lang=EN-US><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如要生成一版中的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Guest_Or_Student_Or_Teacher_Validator</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象，可以用</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Or_Student</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Or_Teacher</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Or&nbsp;_Guest</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">三个对象“</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Or</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">”出来：</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman"></FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">&nbsp;</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #008080">1</SPAN><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">Validator&nbsp;validator&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Or_Student(</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Or_Teacher(</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Or_Guest(OrRelation(req))));</SPAN></DIV>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"></FONT></SPAN>&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这种一层包一层的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">new</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方式，是不是很像洋葱？第一次看是很不习惯，看多了就觉得习惯了。</SPAN></FONT></P>
<H3 style="MARGIN: 13pt 0cm"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=5>对客户端的影响：</FONT></SPAN></H3>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>一版中，客户端要什么样的验证类，就直接使用具体类。</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">二版中，客户端要什么样的验证类，它的工作多了那么一丁点，它需要先组装一下，正如上面的例子。这种组装的方法很易于理解和使用，不会给客户端带来任何的不便。如果实在觉得客户端组装不出来（傻</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">B</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">客户端），也可以搞个工厂给它</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">supply</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">！</SPAN></FONT></P>
<H3 style="MARGIN: 13pt 0cm"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=5>优点：</FONT></SPAN></H3>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; tab-stops: 42.75pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>相对一版最明显的优点就是类的数目少了很多。</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; tab-stops: 42.75pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman" size=4>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; tab-stops: 42.75pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一版不是说“指数级”吗？这里只是线性的了。假设某一天系统拓展到有</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">10</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个角色，一版就有</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">2</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">10</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">次方那么多个，也就是</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">1024</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个验证类。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; tab-stops: 42.75pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman" size=4>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; tab-stops: 42.75pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">而二版还是</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">10</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个角色类，别的都可以在客户端使用的时候，动态的组装</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; tab-stops: 42.75pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman" size=4>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">更重要的是代码结构好了，重复逻辑少了。每个逻辑都以最</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">atomic</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的大小放到最应该的地方。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman" size=4>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">进而，维护的代价少多了。如某天“教师角色”的验证逻辑发生了变化，只要改动</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Or_Teacher</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一个地方即可。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MARCO ZHANG 2006年2月18日23:49:56<IMG height=19 src="http://www.blogjava.net/Emoticons/beer_mug.gif" width=19 border=0></FONT><BR></SPAN></P><img src ="http://www.blogjava.net/marco/aggbug/31429.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/marco/" target="_blank">marco</a> 2006-02-18 23:53 <a href="http://www.blogjava.net/marco/archive/2006/02/18/31429.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>&lt;b&gt;Java Web Application开发日志之二&lt;/b&gt;&lt;br&gt;－－“Ignore how they were created”，工厂方法模式应用</title><link>http://www.blogjava.net/marco/archive/2006/02/16/30894.html</link><dc:creator>marco</dc:creator><author>marco</author><pubDate>Wed, 15 Feb 2006 19:53:00 GMT</pubDate><guid>http://www.blogjava.net/marco/archive/2006/02/16/30894.html</guid><wfw:comment>http://www.blogjava.net/marco/comments/30894.html</wfw:comment><comments>http://www.blogjava.net/marco/archive/2006/02/16/30894.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.blogjava.net/marco/comments/commentRss/30894.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/marco/services/trackbacks/30894.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN></SPAN>说起这个工厂模式，一时还真不知道该如何说起。反正这是我的开发日志，不提理论的东西，理论的东西那里都有，我只想把具体实践记录下来给师弟师妹们作个参考，积累点经验。所有这些文字都是集中讲一点――“在什么情况下为什么用某种模式好，为什么好，为什么在那种情况下能想起来用？”。</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">研究生院项目中“明显”使用了“工厂方法模式”。其实在遇到具体问题的时候，即使我们不知道有这个模式存在，我们也肯定会造一个类似的东西出来。但是，肯定没有书上论述的那么好，那么全面。我想这就是看书的好处吧。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p><FONT size=4>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 12pt; COLOR: #003366; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">工厂方法出现的必然（我的理解，一个很狭隘并幼稚理的人的理解）</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 12pt; COLOR: #003366"><o:p></o:p></SPAN></B></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 12pt; COLOR: #003366"><o:p><FONT size=4>&nbsp;</FONT></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">刚开始使用这个东西的时候，只是感觉是单纯的一种模式，用于创建需要的对象。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">但是随着使用和思考的深入，越发发现它给我的启示不只在于单纯的对象创建，而是告诉我应该怎么理解“产品”，怎么得到“产品”，怎么消费“产品”，以至于以后怎么设计“产品”。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT size=4>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>下面这个线索是我对它出现必然性的理解：</FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><SPAN><STRONG><FONT size=4><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">1.<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></FONT></SPAN>“针对接口编程”</FONT></STRONG></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&nbsp;&nbsp;这是</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">OO</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">世界中经典的规范，不管你主动还是被动，你天天都在用这个东西。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口是共性的表示，在对象的世界中，共性和个性的辩证关系是最重要的关系。在万千的对象中，通过它们之间的共性和个性，可以形成最基本对象层级架构。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">假设我们的讨论域中有以下一些对象：“学生”、“大学生”、“小学生”、“中学生”；我们不用细想，学过一天</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">OO</FONT></SPAN></FONT><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>的人都可以为这些耳熟能详的对象们，通过个性和共性的关系得出下面的结构图。<BR><BR></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"></SPAN><SPAN lang=EN-US><o:p><FONT size=4><IMG style="WIDTH: 356px; HEIGHT: 285px" height=285 alt=o_1.JPG hspace=0 src="http://www.blogjava.net/images/blogjava_net/marco/7462/o_1.JPG" width=356 border=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman" size=4>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">把这些对象之间的关系定义成这样是顺理成章的。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">下一步肯定是让客户端“使用”这个接口啦。也就是如下图：</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman" size=4>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><FONT size=4><IMG style="WIDTH: 464px; HEIGHT: 272px" height=272 alt=o_2.JPG hspace=0 src="http://www.blogjava.net/images/blogjava_net/marco/7462/o_2.JPG" width=464 border=2><BR><BR></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><SPAN><STRONG><FONT size=4><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">2.<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></FONT></SPAN>接口和具体类的矛盾</FONT></STRONG></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">勿庸置疑，我们只希望</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Client</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">跟接口</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">打交道，让它根本就不知道</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">有哪些子类，绝对不希望直接跟它们打交道。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">但这里出现的困难是，接口都是“假”的，都是由具体类</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">upcast</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Client</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">要使用接口</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Client</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中必须会出现下面的代码：</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US><FONT face="Times New Roman" size=4>Student marco = new Small_Student();</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">只要一出现这个代码，就说明</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Client</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">不只跟</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">打交道了，它知道了</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Small_Student</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类，这违反了我们预先的想法。</SPAN></FONT></P></SPAN><SPAN lang=EN-US><o:p>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><SPAN><STRONG><FONT size=4><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">3.<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></FONT></SPAN>找“人”帮我去创建“接口对象”</FONT></STRONG></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&nbsp;&nbsp;&nbsp; 从上图体现出来的结构看，</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Client</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">只想跟</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">打交道的目的是实现不了的了。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face="Times New Roman" size=4>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>最简单的方法就是找另外的“帮手”去帮我生成这个“接口对象”。这个帮手它知道“接口对象”的具体类型，但是它为客户端提供的却一定是“接口类型”。这就符合我们的要求了。如图：<BR><BR></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"></SPAN><SPAN lang=EN-US><o:p><FONT size=4><IMG style="WIDTH: 547px; HEIGHT: 364px" height=364 alt=o_3.JPG hspace=0 src="http://www.blogjava.net/images/blogjava_net/marco/7462/o_3.JPG" width=547 border=2><BR><BR></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&nbsp;&nbsp;&nbsp; 这样，</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Client</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">就可以既用到了“</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口对象”，又不用因为“只有具体类才能创建对象”的规则，而必须对其子类结构有完全的了解。它成功的解决了</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">2</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的矛盾。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">而“负责创建具体类对象的任务”全部都落在了这个“帮手”身上，这个“帮手”（</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student_Factory</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）就是工厂模式中的工厂类，更具体的说，它就是“简单工厂模式”中的“简单工厂类”。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">我觉得，即使一点都不知道工厂模式，一旦我遇到了</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">2</FONT></SPAN></FONT><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>里说的矛盾，我也会用这样的方法处理。</FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><SPAN><STRONG><FONT size=4><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">4.<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></FONT></SPAN>这个“帮手”不符合“开－闭原则”</FONT></STRONG></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>这个帮手的确不错了，而且一跃成为系统中最重要的对象了，所有“创建具体类的逻辑”都放进去了，也就是因为重要，万一挂了不就惨了。</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">再者，它不符合“开－闭”原则，我不能在不修改这个帮手的情况下添加任何一个产品。在这个例子中就是，如果那天我有病非要加一个“幼儿园学生”进来，那您就必须修改这个“帮手”的代码了，这个“帮手”现在就变成</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Version2</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（如下图）了，这个二版的帮手，可以在“代码”层实现对一版（还没有添加幼儿园学生之前</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">)</FONT></SPAN></FONT><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>的通用，但这种保证在“开－闭”原则看来，还是不够的，不保险的，它要的是在类的结构上的保证。声明一下，这是我很感性的理解，不正确的可能性很高。<BR><BR><IMG style="WIDTH: 620px; HEIGHT: 391px" height=391 alt=o_4.JPG hspace=0 src="http://www.blogjava.net/images/blogjava_net/marco/7462/o_4.JPG" width=620 border=2><BR><BR></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><SPAN><STRONG><FONT size=4><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">5.<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></FONT></SPAN>让“帮手”也多态</FONT></STRONG></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>这里可以尝试让“帮手”也多态一下，这样“每种学生类创建的任务”都被分派到了多态出来的类中去了。这时，再有新的学生类型加进来，添加一个对应的帮手就可以了。这样虽然类多了一些，但是符合“开－闭”原则，书上称之为“工厂方法模式”。如图：<BR><BR><IMG style="WIDTH: 636px; HEIGHT: 502px" height=502 alt=o_5.JPG hspace=0 src="http://www.blogjava.net/images/blogjava_net/marco/7462/o_5.JPG" width=636 border=2><BR><BR></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&nbsp;&nbsp;&nbsp; 假如</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Client</FONT></SPAN></FONT><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>现在要使用一个小学生，代码如下：<BR><BR></FONT></P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><FONT size=4><SPAN style="COLOR: #008080">1</SPAN><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">创建一个小学生工厂类这个帮手</SPAN></FONT><SPAN style="COLOR: #008000"><BR></SPAN><FONT size=4><SPAN style="COLOR: #008080">2</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Student_Factory&nbsp;factory&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000">&nbsp;Small_Student_Factory();<BR></SPAN><SPAN style="COLOR: #008080">3</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">求助这个帮手，帮我创建一个</SPAN></FONT><SPAN style="COLOR: #008000"><BR></SPAN><FONT size=4><SPAN style="COLOR: #008080">4</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Student&nbsp;primaryStudent&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000">&nbsp;factory.produce();<BR></SPAN><SPAN style="COLOR: #008080">5</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">这时就可以使用这个小学生了，让它玩玩游戏吧</SPAN></FONT><SPAN style="COLOR: #008000"><BR></SPAN><FONT size=4><SPAN style="COLOR: #008080">6</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;primaryStudent.playGames();<BR></SPAN><SPAN style="COLOR: #008080">7</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN></FONT></DIV></SPAN></SPAN></SPAN><SPAN lang=EN-US><o:p><BR></o:p></SPAN></SPAN>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><FONT size=4></FONT></SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></P></SPAN>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>&nbsp;&nbsp;&nbsp; 在这里还是要强调两点：</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><FONT size=4><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-bidi-font-family: Wingdings; mso-fareast-font-family: Wingdings"><SPAN style="mso-list: Ignore">n<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">虽然实际上</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Client</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的确使用了一个小学生对象（</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Small_Student</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">），但这里</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Client</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">也认为它就是</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象，这里一定要用</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口来隐藏它的具体类。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><FONT size=4><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-bidi-font-family: Wingdings; mso-fareast-font-family: Wingdings"><SPAN style="mso-list: Ignore">n<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">另外，却不需要用</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student_Factory</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个接口来隐藏它的具体类，因为，</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Client</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">实际就是通过“选择它的具体类”这招儿来“选择创建的学生类型”。这里的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student_Factory</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">更多的功能不是“隐藏”具体类，而是“规范”具体类。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman" size=4>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 12pt; COLOR: #003366; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">项目实践</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 12pt; COLOR: #003366"><o:p></o:p></SPAN></B></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 12pt; COLOR: #003366"><o:p><FONT face="Times New Roman" size=4>&nbsp;</FONT></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">扯淡到此，该联系我们的项目啦。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">由于是做研究生院的项目，其中巨大的需求就是要让同学能在网上提交各种申请单，申请退学的，申请转专业的，申请复学的，申请保留学籍的，除了申请女朋友的外，应有尽有。</SPAN><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对于这些单子，用最最基本</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">OO</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">思维，根据共性个性分析方式，抽象出一个申请单接口，和若干的具体类。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当然，除了概念上感性上吻合以外，在项目中它们也要“真”的有巨大的共性才行，如都要提交，修改，删除，审核，打印等功能。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">靠，既然都这样了，肯定就用一接口规定它了。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face="Times New Roman" size=4>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>想到这里，加上有了上面的思考，不用说了，就用工厂方法模式啦。<BR></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman" size=4>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><FONT size=4><IMG style="WIDTH: 629px; HEIGHT: 468px" height=468 alt=o_6.JPG hspace=0 src="http://www.blogjava.net/images/blogjava_net/marco/7462/o_6.JPG" width=629 border=2><BR><BR></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&nbsp;&nbsp;&nbsp; 图中</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Ent_Shift</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">就是申请单接口。等于前面分析的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口。还可以看到有很多具体类，前面例子中是代表各种学生，这里就是代表各种申请单。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face="Times New Roman" size=4>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>当然，这里还有很多工厂，也就是前面一直叫的“帮手”。<BR><BR></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><FONT size=4><IMG style="WIDTH: 665px; HEIGHT: 277px" height=277 alt=o_7.JPG hspace=0 src="http://www.blogjava.net/images/blogjava_net/marco/7462/o_7.JPG" width=665 border=2><BR><BR></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Bean_Shift</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">就是工厂接口，相当于前面的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Student_Factory</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口。还有很多的具体类就是生产各种申请单的工厂类。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face="Times New Roman" size=4>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>下面就是使用“申请单工厂方法模式”的一段客户端代码：<BR><BR></FONT></P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><FONT size=4><SPAN style="COLOR: #008080">&nbsp;1</SPAN><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">声明申请单接口</SPAN></FONT><SPAN style="COLOR: #008000"><BR></SPAN><FONT size=4><SPAN style="COLOR: #008080">&nbsp;2</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ent_Shift&nbsp;es&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000">;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;3</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">声明申请单工厂接口</SPAN></FONT><SPAN style="COLOR: #008000"><BR></SPAN><FONT size=4><SPAN style="COLOR: #008080">&nbsp;4</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Bean_Shift&nbsp;bs&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000">;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;5</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">根据传入的申请单类型数字身成对应的申请单工厂</SPAN></FONT><SPAN style="COLOR: #008000"><BR></SPAN><FONT size=4><SPAN style="COLOR: #008080">&nbsp;6</SPAN><SPAN style="COLOR: #008000"><IMG id=Codehighlighter1_137_479_Open_Image onclick="this.style.display='none'; Codehighlighter1_137_479_Open_Text.style.display='none'; Codehighlighter1_137_479_Closed_Image.style.display='inline'; Codehighlighter1_137_479_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_137_479_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_137_479_Closed_Text.style.display='none'; Codehighlighter1_137_479_Open_Image.style.display='inline'; Codehighlighter1_137_479_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">switch</SPAN><SPAN style="COLOR: #000000">&nbsp;(shiftTypeID)&nbsp;</SPAN><SPAN id=Codehighlighter1_137_479_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN></FONT><SPAN id=Codehighlighter1_137_479_Open_Text><FONT size=4><SPAN style="COLOR: #000000">{<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;7</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">case</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000">&nbsp;Bean_Shift.SHIFT_CHANGETEAAP&nbsp;:<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;8</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bs&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000">&nbsp;Bean_Shift_CHANGETEAAP();<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;9</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">break</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000">;<BR></SPAN><SPAN style="COLOR: #008080">10</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">case</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000">&nbsp;Bean_Shift.SHIFT_RESERVEAP&nbsp;:<BR></SPAN><SPAN style="COLOR: #008080">11</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bs&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000">&nbsp;Bean_Shift_RESERVEAP();<BR></SPAN><SPAN style="COLOR: #008080">12</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">break</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000">;<BR></SPAN><SPAN style="COLOR: #008080">13</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">case</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000">&nbsp;Bean_Shift.SHIFT_RENEWAP&nbsp;:<BR></SPAN><SPAN style="COLOR: #008080">14</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bs&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000">&nbsp;Bean_Shift_RENEWAP();<BR></SPAN><SPAN style="COLOR: #008080">15</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">break</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000">;<BR></SPAN><SPAN style="COLOR: #008080">16</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">省略了别的申请单……………………</SPAN></FONT><SPAN style="COLOR: #008000"><BR></SPAN><FONT size=4><SPAN style="COLOR: #008080">17</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">default</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000">&nbsp;:<BR></SPAN><SPAN style="COLOR: #008080">18</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.forwardErr(req,&nbsp;resp,&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">所选择的异动类别不存在</SPAN><SPAN style="COLOR: #000000">"</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">19</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></FONT></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080"><FONT size=4>20</FONT></SPAN><FONT size=4><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR></SPAN><SPAN style="COLOR: #008080">21</SPAN><SPAN style="COLOR: #000000"><IMG id=Codehighlighter1_488_546_Open_Image onclick="this.style.display='none'; Codehighlighter1_488_546_Open_Text.style.display='none'; Codehighlighter1_488_546_Closed_Image.style.display='inline'; Codehighlighter1_488_546_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_488_546_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_488_546_Closed_Text.style.display='none'; Codehighlighter1_488_546_Open_Image.style.display='inline'; Codehighlighter1_488_546_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">try</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN id=Codehighlighter1_488_546_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN></FONT><SPAN id=Codehighlighter1_488_546_Open_Text><FONT size=4><SPAN style="COLOR: #000000">{<BR></SPAN><SPAN style="COLOR: #008080">22</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">调用工厂接口的生产方法</SPAN></FONT><SPAN style="COLOR: #008000"><BR></SPAN><FONT size=4><SPAN style="COLOR: #008080">23</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;es&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000">&nbsp;bs.getBlankShift(stuID);<BR></SPAN><SPAN style="COLOR: #008080">24</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR></SPAN><SPAN style="COLOR: #008080">25</SPAN><SPAN style="COLOR: #000000"><IMG id=Codehighlighter1_568_613_Open_Image onclick="this.style.display='none'; Codehighlighter1_568_613_Open_Text.style.display='none'; Codehighlighter1_568_613_Closed_Image.style.display='inline'; Codehighlighter1_568_613_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_568_613_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_568_613_Closed_Text.style.display='none'; Codehighlighter1_568_613_Open_Image.style.display='inline'; Codehighlighter1_568_613_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></FONT></SPAN><FONT size=4><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">catch</SPAN><SPAN style="COLOR: #000000">&nbsp;(Exception&nbsp;e)&nbsp;</SPAN><SPAN id=Codehighlighter1_568_613_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN></FONT><SPAN id=Codehighlighter1_568_613_Open_Text><FONT size=4><SPAN style="COLOR: #000000">{<BR></SPAN><SPAN style="COLOR: #008080">26</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000">.forwardErr(req,&nbsp;resp,&nbsp;DB_ERROR);<BR></SPAN><SPAN style="COLOR: #008080">27</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></FONT></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><FONT size=4><SPAN style="COLOR: #008080">28</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">调用单子的提交方法</SPAN></FONT><SPAN style="COLOR: #008000"><BR></SPAN><FONT size=4><SPAN style="COLOR: #008080">29</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;es.submit(req);<BR></SPAN><SPAN style="COLOR: #008080">30</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR></SPAN><SPAN style="COLOR: #008080">31</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">发给页面去显示</SPAN></FONT><SPAN style="COLOR: #008000"><BR></SPAN><FONT size=4><SPAN style="COLOR: #008080">32</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;es.fowrardWithSessionObject(<BR></SPAN><SPAN style="COLOR: #008080">33</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;req,<BR></SPAN><SPAN style="COLOR: #008080">34</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resp,<BR></SPAN><SPAN style="COLOR: #008080">35</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ent_Shift.nameInSessionAndRequest);<BR></SPAN><SPAN style="COLOR: #008080">36</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN></FONT></DIV></SPAN>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman" size=4>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 12pt; COLOR: #003366; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">升华</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 12pt; COLOR: #003366"><o:p></o:p></SPAN></B></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 12pt; COLOR: #003366"><o:p><FONT face="Times New Roman" size=4>&nbsp;</FONT></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个人比较同意《</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Design Pattern Explained</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">》中作者讲的，要用好很多的模式，其中都有一个思路，就是用接口或抽象类来隐藏子类的不同。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">我每当看到这时，老是会被一种思路困扰――“</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">new</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">只能</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">new</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">具体类啊，这咋能隐藏呢，这隐藏还有什么用呢？”。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">作者仿佛也曾经有过我的这个傻</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">B</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">苦恼，它的解决方法就是：根本在使用对象的时候，特别是设计阶段，尽量不去想对象是在那里被</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">new</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的。他认为：反正有了工厂模式后，你总有办法把他们</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">new</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">出来的。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">所以，我用了工厂模式后更发的启发是：以后设计的时候不要想一个</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Client</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">怎么创建一个对象，尽管放心大胆的先继续想，直接使用就好了。反正最后我还有工厂模式呢。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">因此俺的副标题才是“</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Ignore how they were created</FONT></SPAN></FONT><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>”，呵呵。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MARCO ZHANG 2006年2月16日3:52:10 </FONT></SPAN></o:p></SPAN></o:p></SPAN></o:p></SPAN></SPAN><FONT size=4><IMG height=19 src="http://www.blogjava.net/Emoticons/Pizza.gif" width=19 border=0></FONT></P><img src ="http://www.blogjava.net/marco/aggbug/30894.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/marco/" target="_blank">marco</a> 2006-02-16 03:53 <a href="http://www.blogjava.net/marco/archive/2006/02/16/30894.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>&lt;b&gt;Java Web Application开发日志之一&lt;/b&gt;&lt;br&gt;－－自己设计简易framework</title><link>http://www.blogjava.net/marco/archive/2006/02/10/30078.html</link><dc:creator>marco</dc:creator><author>marco</author><pubDate>Thu, 09 Feb 2006 21:48:00 GMT</pubDate><guid>http://www.blogjava.net/marco/archive/2006/02/10/30078.html</guid><wfw:comment>http://www.blogjava.net/marco/comments/30078.html</wfw:comment><comments>http://www.blogjava.net/marco/archive/2006/02/10/30078.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/marco/comments/commentRss/30078.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/marco/services/trackbacks/30078.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;&nbsp; 前段时间，实验室接了学校研究生院的MIS系统。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;采用Delphi的CS和J2EE的BS结合的构架方式。数据库用的是师兄最熟悉的Oracle。说道Oracle，对我来说，基本使用没有问题了，只是数据建模我还没有主导设计过，心里还是没有底。&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;&nbsp;<a href='http://www.blogjava.net/marco/archive/2006/02/10/30078.html'>阅读全文</a><img src ="http://www.blogjava.net/marco/aggbug/30078.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/marco/" target="_blank">marco</a> 2006-02-10 05:48 <a href="http://www.blogjava.net/marco/archive/2006/02/10/30078.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>