﻿<?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-不朽的飞翔-随笔分类-SSH</title><link>http://www.blogjava.net/sitinspring/category/33626.html</link><description>真正的成熟，应当是独特个性的形成，真实自我的发现，精神上的结果和丰收。</description><language>zh-cn</language><lastBuildDate>Fri, 14 Nov 2008 12:07:55 GMT</lastBuildDate><pubDate>Fri, 14 Nov 2008 12:07:55 GMT</pubDate><ttl>60</ttl><item><title>Struts Tiles 示例</title><link>http://www.blogjava.net/sitinspring/archive/2008/11/14/240469.html</link><dc:creator>sitinspring</dc:creator><author>sitinspring</author><pubDate>Fri, 14 Nov 2008 02:44:00 GMT</pubDate><guid>http://www.blogjava.net/sitinspring/archive/2008/11/14/240469.html</guid><wfw:comment>http://www.blogjava.net/sitinspring/comments/240469.html</wfw:comment><comments>http://www.blogjava.net/sitinspring/archive/2008/11/14/240469.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sitinspring/comments/commentRss/240469.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sitinspring/services/trackbacks/240469.html</trackback:ping><description><![CDATA[代码下载：<br />
<a href="http://www.blogjava.net/Files/sitinspring/StrutsTilesSample20081114103940.rar">http://www.blogjava.net/Files/sitinspring/StrutsTilesSample20081114103940.rar</a> <br />
<br />
截图一：<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/sitinspring/Strutstiles01.jpg" border="0" /><br />
<br />
截图二：<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/sitinspring/Strutstiles02.jpg" border="0" />
<img src ="http://www.blogjava.net/sitinspring/aggbug/240469.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sitinspring/" target="_blank">sitinspring</a> 2008-11-14 10:44 <a href="http://www.blogjava.net/sitinspring/archive/2008/11/14/240469.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用模板方法模式简化控制层类（Action）的设计</title><link>http://www.blogjava.net/sitinspring/archive/2008/09/01/226045.html</link><dc:creator>sitinspring</dc:creator><author>sitinspring</author><pubDate>Mon, 01 Sep 2008 03:51:00 GMT</pubDate><guid>http://www.blogjava.net/sitinspring/archive/2008/09/01/226045.html</guid><wfw:comment>http://www.blogjava.net/sitinspring/comments/226045.html</wfw:comment><comments>http://www.blogjava.net/sitinspring/archive/2008/09/01/226045.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.blogjava.net/sitinspring/comments/commentRss/226045.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sitinspring/services/trackbacks/226045.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在基于Model2的应用中，控制层的类总会包含对业务层诸类的调用，业务层诸类不可避免的要产生各种异常，如果统一到控制层进行处理的话会导致代码变得庞大臃肿还有不少重复，这种的例子在Web应用中的Servlet和Action诸类中并不少见。<br><br>如果我们使用模板方法模式（Template Method Pattern）将业务处理和异常处理分开，能有效简化控制层诸类的代码，借用这种模式，我们可以把固定的异常处理代码放在基类中，而让子类来实现具体的业务，如果执行业务过程中出现异常如数据库无法连接，用户找不到等异常后，直接将异常抛出让基类来处理，这样做成功的把业务处理和异常处理分开到了子类和基类两种类中，涉及具体业务处理的子类代码得到了很大的简化，更方便阅读，修改和管理。<br><br>有点疑惑的是，现在还不确定这样做会有什么消极印象，如安全性或结构方面的，大家要是觉得有问题请不吝赐教。&nbsp;&nbsp;<a href='http://www.blogjava.net/sitinspring/archive/2008/09/01/226045.html'>阅读全文</a><img src ="http://www.blogjava.net/sitinspring/aggbug/226045.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sitinspring/" target="_blank">sitinspring</a> 2008-09-01 11:51 <a href="http://www.blogjava.net/sitinspring/archive/2008/09/01/226045.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring的ID增长器使用示例（MySql数据库）</title><link>http://www.blogjava.net/sitinspring/archive/2008/09/01/226040.html</link><dc:creator>sitinspring</dc:creator><author>sitinspring</author><pubDate>Mon, 01 Sep 2008 03:30:00 GMT</pubDate><guid>http://www.blogjava.net/sitinspring/archive/2008/09/01/226040.html</guid><wfw:comment>http://www.blogjava.net/sitinspring/comments/226040.html</wfw:comment><comments>http://www.blogjava.net/sitinspring/archive/2008/09/01/226040.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sitinspring/comments/commentRss/226040.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sitinspring/services/trackbacks/226040.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一般来说涉及数据库的应用中，表的主键有两种生成方案，一种是专门定义一个主键表，在其中放置一个自增长的字段为其它表提供主键；另一种是使用Oracle的sequence。这两种方案都有一定麻烦，Spring为此专门提供了一个ID增长器以简化具体步骤，下文就是它的相关使用方法的，使用的数据库是MySql5.<br><br>归纳<br>使用Spring的自增长ID生成器完成以下三步即可：<br>1）配置自增长id生成器，它需要一个数据源的支持。<br>2）根据配置将自增长id生成器注入DAO各类中。<br>3）使用nextStringValue，nextIntValue,nextLongValue方法得到ID。&nbsp;&nbsp;<a href='http://www.blogjava.net/sitinspring/archive/2008/09/01/226040.html'>阅读全文</a><img src ="http://www.blogjava.net/sitinspring/aggbug/226040.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sitinspring/" target="_blank">sitinspring</a> 2008-09-01 11:30 <a href="http://www.blogjava.net/sitinspring/archive/2008/09/01/226040.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Spring提供的MailSender异步发送文本邮件</title><link>http://www.blogjava.net/sitinspring/archive/2008/08/08/220880.html</link><dc:creator>sitinspring</dc:creator><author>sitinspring</author><pubDate>Fri, 08 Aug 2008 04:55:00 GMT</pubDate><guid>http://www.blogjava.net/sitinspring/archive/2008/08/08/220880.html</guid><wfw:comment>http://www.blogjava.net/sitinspring/comments/220880.html</wfw:comment><comments>http://www.blogjava.net/sitinspring/archive/2008/08/08/220880.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sitinspring/comments/commentRss/220880.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sitinspring/services/trackbacks/220880.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在工程中经常有发送邮件的任务,如果使用JavaMail来发送邮件，用到的代码较多，过程和细节也相对复杂，而使用Spring的MailSender能相对简单方便些，这样使程序员能更快捷的完成邮件发送任务。下面请看示例代码：&nbsp;注意在执行代码前，请确认已经将activation.jar，commons-logging-1.0.4.jar，mail.jar和spring.jar载入工程。...&nbsp;&nbsp;<a href='http://www.blogjava.net/sitinspring/archive/2008/08/08/220880.html'>阅读全文</a><img src ="http://www.blogjava.net/sitinspring/aggbug/220880.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sitinspring/" target="_blank">sitinspring</a> 2008-08-08 12:55 <a href="http://www.blogjava.net/sitinspring/archive/2008/08/08/220880.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从模板方法模式到反射再到Spring的IoC</title><link>http://www.blogjava.net/sitinspring/archive/2008/08/08/220881.html</link><dc:creator>sitinspring</dc:creator><author>sitinspring</author><pubDate>Fri, 08 Aug 2008 04:55:00 GMT</pubDate><guid>http://www.blogjava.net/sitinspring/archive/2008/08/08/220881.html</guid><wfw:comment>http://www.blogjava.net/sitinspring/comments/220881.html</wfw:comment><comments>http://www.blogjava.net/sitinspring/archive/2008/08/08/220881.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sitinspring/comments/commentRss/220881.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sitinspring/services/trackbacks/220881.html</trackback:ping><description><![CDATA[<p>软件开发过程中，唯一不变的就是变化。这是一句老生常谈，也就是说软件开发中永恒的主题就是变化。当你把代码都写好了，测试也完成了，准备交付的时候客户忽然要求你在指定时间做出变化，这种情况在外包行业中很常见；而对一些银行金融项目，边调研边开发边测试屡见不鲜；对于一些Web项目，从来就只有永远的Beta版，改来改去的事更是家常便饭。对此，程序员一定要求清晰的认识，抱怨只能是嘴上痛快，不解决实际问题。真要解决实际问题，非要动一番脑筋不可，如果合理使用了设计模式，反射或是Spring的IoC，便能变修改噩梦为一次有趣的智慧之旅。</p>
<p>&nbsp;</p>
<p>首先我们看原始要求：客户要求将一批雇员名单存入到CSV和XML两种文件中去，以后还有可能增加别的文件格式，比如PDF，XLS等，虽然这是下一期的内容，但这一期应该考虑到变化，客户要求扩展性一定要好。</p>
<p>没问题，有了设计模式响应变化不难。这时我们可以用到模板方法模式：</p>
<p><strong>定义一个操作中的算法的骨架，而将一些步骤延迟到子类中</strong>。</p>
<p>&nbsp;</p>
<p>先请看骨架抽象类：</p>
<div class="highlighter">
<ol class="highlighter-j">
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">abstract</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;FileMaker&nbsp;{</span>
    <li class="alt"><span>&nbsp;&nbsp;</span><span class="comment">/**</span>
    <li><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;雇员集合</span>
    <li class="alt"><span class="comment">&nbsp;&nbsp;&nbsp;*/</span>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;List&lt;Employee&gt;&nbsp;employees;</span>
    <li class="alt">
    <li><span>&nbsp;&nbsp;</span><span class="comment">/**</span>
    <li class="alt"><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;生成雇员列表文件，公开接口，供外界调用</span>
    <li><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;定义成final是不想让子类改写，因为调用的步骤在父类中就可以确定，子类只需实现makeFile函数</span>
    <li class="alt"><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;employees</span>
    <li><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;fileName</span>
    <li class="alt"><span class="comment">&nbsp;&nbsp;&nbsp;*/</span>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">final</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;makeFile(List&lt;Employee&gt;&nbsp;employees,String&nbsp;fileName){</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;setEmployees(employees);</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;makeFile(fileName);</span>
    <li class="alt"><span>&nbsp;&nbsp;}</span>
    <li><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;</span><span class="comment">/**</span>
    <li><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;生成具体的雇员列表文件，此函数留待子类实现</span>
    <li class="alt"><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;fileName</span>
    <li><span class="comment">&nbsp;&nbsp;&nbsp;*/</span>
    <li class="alt"><span>&nbsp;&nbsp;</span><span class="keyword">protected</span><span>&nbsp;</span><span class="keyword">abstract</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;makeFile(String&nbsp;fileName);&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">final</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setEmployees(List&lt;Employee&gt;&nbsp;employees)&nbsp;{</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">this</span><span>.employees&nbsp;=&nbsp;employees;</span>
    <li class="alt"><span>&nbsp;&nbsp;}</span>
    <li>
    <li class="alt"><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;List&lt;Employee&gt;&nbsp;getEmployees()&nbsp;{</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;employees;</span>
    <li class="alt"><span>&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;</span>
    <li><span>}</span>
    <li class="alt"></li>
</ol>
</div>
<p>很好，固定的函数和步骤都在抽象基类中写定了，再看两个具体实现类，它们要实现的就是makeFile函数而已。</p>
<div class="highlighter">
<ol class="highlighter-j">
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;CSVFileMaker&nbsp;</span><span class="keyword">extends</span><span>&nbsp;FileMaker{</span>
    <li class="alt"><span>&nbsp;&nbsp;</span><span class="keyword">protected</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;makeFile(String&nbsp;fileName){</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>&nbsp;{</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BufferedWriter&nbsp;out&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;BufferedWriter(</span><span class="keyword">new</span><span>&nbsp;FileWriter(fileName));</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">for</span><span>(Employee&nbsp;emp:getEmployees()){</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;line=</span><span class="string">""</span><span>;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;line+=emp.getName()+</span><span class="string">","</span><span>;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;line+=(emp.isMale()?</span><span class="string">"男"</span><span>:</span><span class="string">"女"</span><span>)+</span><span class="string">","</span><span>;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;line+=emp.getAge()+</span><span class="string">","</span><span>;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.write(line+</span><span class="string">"\r\n"</span><span>);</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.close();</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span class="keyword">catch</span><span>&nbsp;(Exception&nbsp;e)&nbsp;{</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span>
    <li><span>&nbsp;&nbsp;}</span>
    <li class="alt"><span>}</span></li>
</ol>
</div>
<div class="highlighter">
<ol class="highlighter-j">
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;XMLFileMaker&nbsp;</span><span class="keyword">extends</span><span>&nbsp;FileMaker{</span>
    <li class="alt"><span>&nbsp;&nbsp;</span><span class="keyword">protected</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;makeFile(String&nbsp;fileName){</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>&nbsp;{</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Document&nbsp;document&nbsp;=&nbsp;DocumentHelper.createDocument();</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Element&nbsp;root&nbsp;=&nbsp;document.addElement(</span><span class="string">"employees"</span><span>);</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">for</span><span>(Employee&nbsp;emp:getEmployees()){</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Element&nbsp;empElm=root.addElement(</span><span class="string">"employee"</span><span>);</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Element&nbsp;nameElm=empElm.addElement(</span><span class="string">"name"</span><span>);</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nameElm.setText(emp.getName());</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Element&nbsp;sexElm=empElm.addElement(</span><span class="string">"sex"</span><span>);</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sexElm.setText(emp.isMale()?</span><span class="string">"男"</span><span>:</span><span class="string">"女"</span><span>);</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Element&nbsp;ageElm=empElm.addElement(</span><span class="string">"age"</span><span>);</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ageElm.setText(String.valueOf(emp.getAge()));</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OutputFormat&nbsp;format&nbsp;=&nbsp;OutputFormat.createPrettyPrint();</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;format.setEncoding(</span><span class="string">"GBK"</span><span>);&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;指定XML编码&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XMLWriter&nbsp;writer&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;XMLWriter(</span><span class="keyword">new</span><span>&nbsp;FileWriter(fileName),format);</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer.write(document);</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer.close();</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span class="keyword">catch</span><span>&nbsp;(Exception&nbsp;e)&nbsp;{</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span>
    <li><span>&nbsp;&nbsp;}</span>
    <li class="alt"><span>}</span>
    <li></li>
</ol>
</div>
<p>这样昨完以后感觉很好，因为我们成功的把变化和不变分离开来，不变的部分放在了抽象基类中，而容易变化的部分放在了两个具体的子类中，这样如果再增加一种新文件格式，从抽象基类再扩展出一个子类即可。很好，这样就不怕变化了。客户对此也没有异议。</p>
<p>&nbsp;</p>
<p>调用示例如下：</p>
<div class="highlighter">
<ol class="highlighter-j">
    <li><span>List&lt;Employee&gt;&nbsp;emps=</span><span class="keyword">new</span><span>&nbsp;ArrayList&lt;Employee&gt;();</span>
    <li class="alt"><span>emps.add(</span><span class="keyword">new</span><span>&nbsp;Employee(</span><span class="string">"Andy"</span><span>,</span><span class="keyword">true</span><span>,</span><span class="number">21</span><span>));</span>
    <li><span>emps.add(</span><span class="keyword">new</span><span>&nbsp;Employee(</span><span class="string">"Bill"</span><span>,</span><span class="keyword">false</span><span>,</span><span class="number">23</span><span>));</span>
    <li class="alt"><span>emps.add(</span><span class="keyword">new</span><span>&nbsp;Employee(</span><span class="string">"Cindy"</span><span>,</span><span class="keyword">true</span><span>,</span><span class="number">25</span><span>));</span>
    <li><span>emps.add(</span><span class="keyword">new</span><span>&nbsp;Employee(</span><span class="string">"Douglas"</span><span>,</span><span class="keyword">false</span><span>,</span><span class="number">28</span><span>));</span>
    <li class="alt">
    <li><span>FileMaker&nbsp;fileMaker=</span><span class="keyword">new</span><span>&nbsp;CSVFileMaker();</span>
    <li class="alt"><span>fileMaker.makeFile(emps,&nbsp;</span><span class="string">"1.csv"</span><span>);</span>
    <li>
    <li class="alt"><span>fileMaker=</span><span class="keyword">new</span><span>&nbsp;XMLFileMaker();</span>
    <li><span>fileMaker.makeFile(emps,&nbsp;</span><span class="string">"2.xml"</span><span>);</span>
    <li class="alt"></li>
</ol>
</div>
<p>客户看到了我们的调用的例子，觉得应该更灵活一些，他说存成各种不同的文件是通过点击按钮来实现的，如果每个按钮的事件处理函数都要生成具体子类岂不是太死板了吗？这样做每个文件下载按钮的事件处理代码不是都不一样？</p>
<p>&nbsp;</p>
<p>有点道理，如今理解到这一层的客户实在是不多见了。不过很容易满足他的需求，我们可以引入反射的方法：</p>
<div class="highlighter">
<ol class="highlighter-j">
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args)&nbsp;{</span>
    <li class="alt"><span>&nbsp;&nbsp;List&lt;Employee&gt;&nbsp;emps=</span><span class="keyword">new</span><span>&nbsp;ArrayList&lt;Employee&gt;();</span>
    <li><span>&nbsp;&nbsp;emps.add(</span><span class="keyword">new</span><span>&nbsp;Employee(</span><span class="string">"Andy"</span><span>,</span><span class="keyword">true</span><span>,</span><span class="number">21</span><span>));</span>
    <li class="alt"><span>&nbsp;&nbsp;emps.add(</span><span class="keyword">new</span><span>&nbsp;Employee(</span><span class="string">"Bill"</span><span>,</span><span class="keyword">false</span><span>,</span><span class="number">23</span><span>));</span>
    <li><span>&nbsp;&nbsp;emps.add(</span><span class="keyword">new</span><span>&nbsp;Employee(</span><span class="string">"Cindy"</span><span>,</span><span class="keyword">true</span><span>,</span><span class="number">25</span><span>));</span>
    <li class="alt"><span>&nbsp;&nbsp;emps.add(</span><span class="keyword">new</span><span>&nbsp;Employee(</span><span class="string">"Douglas"</span><span>,</span><span class="keyword">false</span><span>,</span><span class="number">28</span><span>));</span>
    <li><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;callByReflect(</span><span class="string">"csv"</span><span>,emps,</span><span class="string">"1.csv"</span><span>);</span>
    <li><span>&nbsp;&nbsp;callByReflect(</span><span class="string">"xml"</span><span>,emps,</span><span class="string">"2.xml"</span><span>);</span>
    <li class="alt"><span>}</span>
    <li>
    <li class="alt"><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;callByReflect(String&nbsp;type,List&lt;Employee&gt;&nbsp;emps,String&nbsp;fileName){</span>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">try</span><span>{</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;Class&nbsp;cls=Class.forName(</span><span class="string">"com.heyang."</span><span>+type.toUpperCase()+</span><span class="string">"FileMaker"</span><span>);</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;FileMaker&nbsp;fileMaker=(FileMaker)cls.newInstance();</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;fileMaker.makeFile(emps,&nbsp;fileName);</span>
    <li><span>&nbsp;&nbsp;}</span>
    <li class="alt"><span>&nbsp;&nbsp;</span><span class="keyword">catch</span><span>(Exception&nbsp;ex){</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;ex.printStackTrace();</span>
    <li class="alt"><span>&nbsp;&nbsp;}</span>
    <li><span>}</span></li>
</ol>
</div>
<p class="alt"><span>因为按钮上的文字和类名是有关的，如下载CSV的按钮上就有CSV的文字，这可以通过正则表达式取道，再组合一下不就是类名了吗？</span><span>csv到com.heyang.CSVFileMaker,xml到com.heyang.XMLFileMaker，其实变化就是三个字母而已。如果增加按钮，取出按钮中的三个字母再调用callByReflect函数即可，这个过程简直可以固化。</span></p>
<p class="alt">&nbsp;</p>
<p class="alt"><span>客户看到反射方法以后很是满意，没有意见了。待客户走后，项目经理把你拉到一边，说：</span></p>
<p class="alt"><span>&#8220;你刚才的方法不错，确实很强，但看得懂反射并能灵活掌握的人水平要够一年经验才行，维护的活让一年经验的人去干太可惜了，最好改改，最好达到让新手也能掌握并修改的程度。&#8221;。</span></p>
<p class="alt">&nbsp;</p>
<p class="alt"><span>没办法，领导总有领导的考虑，他这么说也很合理，成本问题我可以不考虑，但如果把程序搞得复杂貌似NB，能让一些学艺不精的人产生云山雾罩的感觉，有时还能被人尊称一声&#8220;大侠&#8221;，但谁也不比谁傻多少，这声大侠不是白叫的，但是出了问题或是有了变化别人还是要找你，到头来还是给自己添乱，这些都是义务劳动，何苦来呢？还是应该改得容易些，让大家都能修改，我可不愿意半夜三更被人叫起来问问题。</span></p>
<p class="alt">&nbsp;</p>
<p class="alt"><span>用Spring的IoC就可以解决问题，写一个新类并配置到XML文件中对新手来说问题不大，这下可以让领导放心了，自己就更放心了。</span></p>
<p class="alt">&nbsp;</p>
<p class="alt"><span>IoC方案代码如下：</span><span></p>
<div class="highlighter">
<ol class="highlighter-j">
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Main&nbsp;{</span>
    <li class="alt"><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args)&nbsp;{</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;List&lt;Employee&gt;&nbsp;emps=</span><span class="keyword">new</span><span>&nbsp;ArrayList&lt;Employee&gt;();</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;emps.add(</span><span class="keyword">new</span><span>&nbsp;Employee(</span><span class="string">"Andy"</span><span>,</span><span class="keyword">true</span><span>,</span><span class="number">21</span><span>));</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;emps.add(</span><span class="keyword">new</span><span>&nbsp;Employee(</span><span class="string">"Bill"</span><span>,</span><span class="keyword">false</span><span>,</span><span class="number">23</span><span>));</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;emps.add(</span><span class="keyword">new</span><span>&nbsp;Employee(</span><span class="string">"Cindy"</span><span>,</span><span class="keyword">true</span><span>,</span><span class="number">25</span><span>));</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;emps.add(</span><span class="keyword">new</span><span>&nbsp;Employee(</span><span class="string">"Douglas"</span><span>,</span><span class="keyword">false</span><span>,</span><span class="number">28</span><span>));</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;callByIoc(</span><span class="string">"csv"</span><span>,emps,</span><span class="string">"1.csv"</span><span>);</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;callByIoc(</span><span class="string">"xml"</span><span>,emps,</span><span class="string">"2.xml"</span><span>);</span>
    <li><span>&nbsp;&nbsp;}</span>
    <li class="alt"><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;callByIoc(String&nbsp;type,List&lt;Employee&gt;&nbsp;emps,String&nbsp;fileName){</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>{</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ApplicationContext&nbsp;ctx&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;FileSystemXmlApplicationContext(</span><span class="string">"bean.xml"</span><span>);</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileMaker&nbsp;fileMaker=(FileMaker)ctx.getBean(type);</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fileMaker.makeFile(emps,&nbsp;fileName);</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">catch</span><span>(Exception&nbsp;ex){</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ex.printStackTrace();</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;}</span>
    <li class="alt"><span>&nbsp;&nbsp;}</span>
    <li><span>}</span></li>
</ol>
</div>
</span>
<p class="alt"><span>Bean。xml文件内容很简单吧：</span><span></p>
<div class="highlighter">
<ol class="highlighter-xml">
    <li><span class="tag">&lt;?</span><span class="tag-name">xml</span><span>&nbsp;</span><span class="attribute">version</span><span>=</span><span class="attribute-value">"1.0"</span><span>&nbsp;</span><span class="attribute">encoding</span><span>=</span><span class="attribute-value">"UTF-8"</span><span class="tag">?&gt;</span>
    <li class="alt"><span class="tag">&lt;!DOCTYPE&nbsp;beans&nbsp;PUBLIC&nbsp;"-//SPRING//DTD&nbsp;BEAN//EN"&nbsp;"http://www.springframework.org/dtd/spring-beans.dtd"&gt;</span>
    <li><span class="tag">&lt;</span><span class="tag-name">beans</span><span class="tag">&gt;</span>
    <li class="alt"><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"csv"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"com.heyang.CSVFileMaker"</span><span class="tag">/&gt;</span>
    <li><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"xml"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"com.heyang.XMLFileMaker"</span><span class="tag">/&gt;</span>
    <li class="alt"><span class="tag">&lt;/</span><span class="tag-name">beans</span><span class="tag">&gt;</span><span>&nbsp;</span></li>
</ol>
</div>
</span>
<p class="alt"><span>好了。到这里问题就彻底结束了，终于满足了客户和上级的要求，可以回家睡个好觉了，不用担心别人打搅了。</span></p>
<p class="alt">&nbsp;</p>
<p class="alt"><span>态度改变一切，变化来了人总是要多做一些，心理当然是不愿意的，但抱怨或是消极抵制都不是解决问题之道；如果把它看做一个挑战的契机，凡事多思考一些，不但能解决问题，自己也会有所提高，这就是积极的态度带来的好处。</span></p>
  <img src ="http://www.blogjava.net/sitinspring/aggbug/220881.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sitinspring/" target="_blank">sitinspring</a> 2008-08-08 12:55 <a href="http://www.blogjava.net/sitinspring/archive/2008/08/08/220881.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>动态代理机制初探</title><link>http://www.blogjava.net/sitinspring/archive/2008/05/28/203359.html</link><dc:creator>sitinspring</dc:creator><author>sitinspring</author><pubDate>Tue, 27 May 2008 16:06:00 GMT</pubDate><guid>http://www.blogjava.net/sitinspring/archive/2008/05/28/203359.html</guid><wfw:comment>http://www.blogjava.net/sitinspring/comments/203359.html</wfw:comment><comments>http://www.blogjava.net/sitinspring/archive/2008/05/28/203359.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/sitinspring/comments/commentRss/203359.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sitinspring/services/trackbacks/203359.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Spring的AOP支持可以被用于从系统核心逻辑中分离交叉业务（cross-business）如日志，事务管理和安全等，使用AOP，你可以用各种功能层来覆盖核心业务层，这些功能层可以灵活的应用到你的系统中，甚至核心业务层都不知道它们的存在，这是一个强大的概念。<br>AOP（aspect-oriented programming）的核心就是动态代理，掌握它对于理解AOP尤为重要，犹如反射对理解IoC一样。<br>&nbsp;&nbsp;<a href='http://www.blogjava.net/sitinspring/archive/2008/05/28/203359.html'>阅读全文</a><img src ="http://www.blogjava.net/sitinspring/aggbug/203359.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sitinspring/" target="_blank">sitinspring</a> 2008-05-28 00:06 <a href="http://www.blogjava.net/sitinspring/archive/2008/05/28/203359.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts的ActionServlet模拟实现</title><link>http://www.blogjava.net/sitinspring/archive/2008/03/29/189385.html</link><dc:creator>sitinspring</dc:creator><author>sitinspring</author><pubDate>Fri, 28 Mar 2008 16:31:00 GMT</pubDate><guid>http://www.blogjava.net/sitinspring/archive/2008/03/29/189385.html</guid><wfw:comment>http://www.blogjava.net/sitinspring/comments/189385.html</wfw:comment><comments>http://www.blogjava.net/sitinspring/archive/2008/03/29/189385.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/sitinspring/comments/commentRss/189385.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sitinspring/services/trackbacks/189385.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Struts中，ActionServlet作为总控Servlet接受请求并转发到各Action，它的原理并不复杂，本文即展示了ActionServlet模拟实现过程。&nbsp;&nbsp;<a href='http://www.blogjava.net/sitinspring/archive/2008/03/29/189385.html'>阅读全文</a><img src ="http://www.blogjava.net/sitinspring/aggbug/189385.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sitinspring/" target="_blank">sitinspring</a> 2008-03-29 00:31 <a href="http://www.blogjava.net/sitinspring/archive/2008/03/29/189385.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>