﻿<?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-把永恒在一刹那间收藏-文章分类-design</title><link>http://www.blogjava.net/gm_jing/category/23408.html</link><description>生活之点点滴滴</description><language>zh-cn</language><lastBuildDate>Tue, 11 Sep 2007 21:56:29 GMT</lastBuildDate><pubDate>Tue, 11 Sep 2007 21:56:29 GMT</pubDate><ttl>60</ttl><item><title>类与类关系的UML图与代码表现</title><link>http://www.blogjava.net/gm_jing/articles/144236.html</link><dc:creator>黎夕</dc:creator><author>黎夕</author><pubDate>Tue, 11 Sep 2007 05:22:00 GMT</pubDate><guid>http://www.blogjava.net/gm_jing/articles/144236.html</guid><wfw:comment>http://www.blogjava.net/gm_jing/comments/144236.html</wfw:comment><comments>http://www.blogjava.net/gm_jing/articles/144236.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gm_jing/comments/commentRss/144236.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gm_jing/services/trackbacks/144236.html</trackback:ping><description><![CDATA[<p><font face="Arial">类与类之间的关系对于理解面向对象具有很重要的作用，以前在面试的时候也经常被问到这个问题，在这里我就介绍一下。<br />
类与类之间存在以下关系:<br />
<strong><font color="#3366ff">(1)泛化(Generalization)<br />
(2)关联(Association)<br />
(3)依赖(Dependency)<br />
(4)聚合(Aggregation)</font></strong></font></p>
<p><font face="Arial"><strong>UML图与应用代码例子:</strong><br />
<strong><font color="#ff9900" size="4"><font color="#3366ff">1.泛化(Generalization)</font><br />
</font><font color="#339966" size="3">[泛化]</font><br />
</strong>表示类与类之间的继承关系，接口与接口之间的继承关系，或类对接口的实现关系。一般化的关系是从子类指向父类的，与继承或实现的方法相反。<br />
<font color="#339966" size="3"><strong>[具体表现]<br />
</strong></font><font color="#ff0000">父类</font> 父类实例＝new <font color="#ff0000">子类</font>()<br />
<strong><font color="#339966" size="3">[UML图](图1.1)<br />
</font><img alt="" src="http://seagar.javaeye.com/upload/picture/pic/1320/10bfdb9d-ed2d-4226-bab2-f814d2e10a82.jpg" /><br />
</strong><font face="Arial"><font color="#339966"><strong>图1.1</strong></font> <strong>Animal类与Tiger类,Dog类的泛化关系<br />
</strong></font><br />
<strong><font color="#339966" size="3">[代码表现]</font><br />
<br />
</strong></font></p>
<div class="dp-highlighter">
<div class="bar"><strong></strong></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">class</span><span><strong>&nbsp;Animal{} &nbsp;&nbsp;</strong></span></span><strong> </strong>
    <li class=""><span class="keyword">class</span><strong><span>&nbsp;Tiger&nbsp;</span><span class="keyword">extends</span><span>&nbsp;Animal{} &nbsp;&nbsp;</span> </strong>
    <li class="alt"><span class="keyword">public</span><strong><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Test &nbsp;&nbsp;</span> </strong>
    <li class=""><strong><span>{ &nbsp;&nbsp;</span> </strong>
    <li class="alt"><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;test() &nbsp;&nbsp;</span> </strong>
    <li class=""><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</span> </strong>
    <li class="alt"><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Animal&nbsp;a=</span><span class="keyword">new</span><span>&nbsp;Tiger(); &nbsp;&nbsp;</span> </strong>
    <li class=""><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </strong>
    <li class="alt"><strong><span>}&nbsp;&nbsp;</span> </strong></li>
</ol>
</div>
<br />
<font face="Arial"><strong><font color="#3366ff" size="4">2.依赖(Dependency)</font><br />
</strong><font color="#339966" size="3"><strong>[依赖]<br />
</strong></font>对于两个相对独立的对象，当一个对象负责构造另一个对象的实例，或者依赖另一个对象的服务时，这两个对象之间主要体现为依赖关系。<br />
<font color="#339966" size="3"><strong>[具体表现]<br />
</strong></font>依赖关系表现在<font color="#ff0000">局部变量</font>，<font color="#ff0000">方法的参数</font>，以及对<font color="#ff0000">静态方法的调用</font><br />
<font color="#339966" size="3"><strong>[现实例子]<br />
</strong></font>比如说你要去拧螺丝，你是不是要借助(也就是依赖)螺丝刀(Screwdriver)来帮助你完成拧螺丝(screw)的工作<br />
<font color="#339966" size="3"><strong>[UML表现](图1.2)</strong></font><br />
<p align="left"><strong><img alt="" src="http://seagar.javaeye.com/upload/picture/pic/1319/ec7bca6c-c01a-4772-a91b-3a695773ddfb.jpg" /></strong></p>
<p align="left"><br />
<font face="Arial"><strong><font color="#339966">图1.2 </font>Person类与Screwdriver类的依赖关系</strong><br />
<font face="Arial"><font color="#339966" size="3"><strong><br />
[代码表现] </strong></font></font></font></p>
<div class="dp-highlighter">
<div class="bar"><strong></strong></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">public</span><strong><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Person{ &nbsp;&nbsp;</span></strong></span><strong> </strong>
    <li class=""><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">/**&nbsp;拧螺丝&nbsp;*/</span><span>&nbsp;&nbsp;</span> </strong>
    <li class="alt"><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;screw(Screwdriver&nbsp;screwdriver){ &nbsp;&nbsp;</span> </strong>
    <li class=""><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;screwdriver.screw(); &nbsp;&nbsp;</span> </strong>
    <li class="alt"><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </strong>
    <li class=""><strong><span>}&nbsp;&nbsp;</span> </strong></li>
</ol>
</div>
<br />
<font face="Arial"><strong><font color="#3366ff" size="4">3.关联(Association)</font><br />
</strong><font color="#339966" size="3"><strong>[关联]<br />
</strong></font>对于两个相对独立的对象，当一个对象的实例与另一个对象的一些特定实例存在固定的对应关系时，这两个对象之间为关联关系。<br />
<font color="#339966" size="3"><strong>[具体表现]<br />
</strong></font>关联关系是使用<font color="#ff0000">实例变量</font>来实现<br />
<font color="#339966" size="3"><strong>[现实例子]<br />
</strong></font>比如客户和订单，每个订单对应特定的客户，每个客户对应一些特定的订单；再例如公司和员工，每个公司对应一些特定的员工，每个员工对应一特定的公司<br />
<strong><font color="#339966" size="3">[UML图] (图1.3)<br />
</font><img alt="" src="http://seagar.javaeye.com/upload/picture/pic/1318/d4b10677-364d-4c34-beb7-416f8e835d8c.jpg" /><br />
<font face="Arial"><strong><font color="#339966">图1.3 </font></strong>公司和员工的关联关系</font></strong></font><br />
<font face="Arial"><strong><br />
<font color="#339966" size="3">[代码表现]</font></strong>
<div class="dp-highlighter">
<div class="bar"><strong></strong></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">public</span><strong><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Company{ &nbsp;&nbsp;</span></strong></span><strong> </strong>
    <li class=""><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;Employee&nbsp;employee; &nbsp;&nbsp;</span> </strong>
    <li class="alt"><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;Employee&nbsp;getEmployee(){ &nbsp;&nbsp;</span> </strong>
    <li class=""><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;employee; &nbsp;&nbsp;</span> </strong>
    <li class="alt"><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </strong>
    <li class=""><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setEmployee(Employee&nbsp;employee){ &nbsp;&nbsp;</span> </strong>
    <li class="alt"><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">this</span><span>.employee=employee; &nbsp;&nbsp;</span> </strong>
    <li class=""><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </strong>
    <li class="alt"><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//公司运作 </span><span>&nbsp;&nbsp;</span> </strong>
    <li class=""><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;run(){ &nbsp;&nbsp;</span> </strong>
    <li class="alt"><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;employee.startWorking(); &nbsp;&nbsp;</span> </strong>
    <li class=""><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </strong>
    <li class="alt"><strong><span>}&nbsp;&nbsp;</span> </strong></li>
</ol>
</div>
</font></font><font face="Arial"><strong><font color="#3366ff" size="4">(4)聚合（Aggregation）</font><br />
<font color="#339966" size="3">[聚合]<br />
</font></strong>当对象A被加入到对象B中，成为对象B的组成部分时，对象B和对象A之间为聚集关系。聚合是关联关系的一种，是较强的关联关系，强调的是<font color="#ff0000">整体</font>与<font color="#ff0000">部分</font>之间的关系。<br />
<font color="#339966" size="3"><strong>[具体表现]<br />
</strong></font>与关联关系一样，聚合关系也是通过<font color="#ff0000">实例变量</font>来实现这样关系的。关联关系和聚合关系来语法上是没办法区分的，从<font color="#ff0000">语义</font>上才能<font color="#ff0000">更好的区分</font>两者的区别。<br />
<font color="#339966" size="3"><strong>[关联与聚合的区别]</strong></font><br />
(1)关联关系所涉及的两个对象是处在同一个层次上的。比如人和自行车就是一种关联关系，而不是聚合关系，因为人不是由自行车组成的。<br />
聚合关系涉及的两个对象处于不平等的层次上，一个代表整体，一个代表部分。比如电脑和它的显示器、键盘、主板以及内存就是聚集关系，因为主板是电脑的组成部分。<br />
(2)对于具有聚集关系（尤其是强聚集关系）的两个对象，整体对象会制约它的组成对象的生命周期。部分类的对象不能单独存在，它的生命周期依赖于整体类的对象的生命周期，当整体消失，部分也就随之消失。比如张三的电脑被偷了，那么电脑的所有组件也不存在了，除非张三事先把一些电脑的组件（比如硬盘和内存）拆了下来。<br />
<font color="#339966" size="3"><strong>[UML图](图1.4)</strong></font><br />
<strong><img alt="" src="http://seagar.javaeye.com/upload/picture/pic/1326/7032798b-36ca-4b89-a462-97ba056cbe48.jpg" /><br />
<font face="Arial"><strong><font color="#339966">图1.3 </font><font color="#000000">电脑和组件的聚合关系</font></strong></font><br />
<br />
<font face="Arial"><font color="#339966" size="3"><strong>[代码表现]</strong></font></font></strong>
<div class="dp-highlighter">
<div class="bar"><strong></strong></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">public</span><strong><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Computer{ &nbsp;&nbsp;</span></strong></span><strong> </strong>
    <li class=""><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;CPU&nbsp;cpu; &nbsp;&nbsp;</span> </strong>
    <li class="alt"><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;CPU&nbsp;getCPU(){ &nbsp;&nbsp;</span> </strong>
    <li class=""><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;cpu; &nbsp;&nbsp;</span> </strong>
    <li class="alt"><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </strong>
    <li class=""><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setCPU(CPU&nbsp;cpu){ &nbsp;&nbsp;</span> </strong>
    <li class="alt"><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">this</span><span>.cpu=cpu; &nbsp;&nbsp;</span> </strong>
    <li class=""><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </strong>
    <li class="alt"><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//开启电脑 </span><span>&nbsp;&nbsp;</span> </strong>
    <li class=""><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;start(){ &nbsp;&nbsp;</span> </strong>
    <li class="alt"><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//cpu运作 </span><span>&nbsp;&nbsp;</span> </strong>
    <li class=""><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cpu.run(); &nbsp;&nbsp;</span> </strong>
    <li class="alt"><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </strong>
    <li class=""><strong><span>}&nbsp;&nbsp;</span> </strong></li>
</ol>
</div>
<br />
<br />
<font face="Arial" color="#99cc00"><strong>[参考资料]<br />
1.《Java与模式》(阎宏 编著) 第2章 统一建模语言UML简介</strong></font></font>
<img src ="http://www.blogjava.net/gm_jing/aggbug/144236.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gm_jing/" target="_blank">黎夕</a> 2007-09-11 13:22 <a href="http://www.blogjava.net/gm_jing/articles/144236.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring中的Template和Callback模式 </title><link>http://www.blogjava.net/gm_jing/articles/127447.html</link><dc:creator>黎夕</dc:creator><author>黎夕</author><pubDate>Mon, 02 Jul 2007 02:46:00 GMT</pubDate><guid>http://www.blogjava.net/gm_jing/articles/127447.html</guid><wfw:comment>http://www.blogjava.net/gm_jing/comments/127447.html</wfw:comment><comments>http://www.blogjava.net/gm_jing/articles/127447.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gm_jing/comments/commentRss/127447.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gm_jing/services/trackbacks/127447.html</trackback:ping><description><![CDATA[<p><span>Spring</span><span>中的</span><span>Callback</span><span>模式与</span><span>Template</span><span>模式合用，随处可见。</span><span>Template method</span><span>被广泛的使用，像</span><span>Servlet</span><span>就是使用这个模式。</span><span>Template mothod</span><span>模式虽然能简化很多重复的代码，但这种模式的也有不少限制。</span><span>Template mothod</span><span>将一个功能的实现分成许多小的步骤，在父类中定义了这些步骤的顺序，让子类来具体实现每一个小的步骤。这些小的步骤是</span><span>protected</span><span>，以防止用户不正确的使用这些小的步骤而产生异常。这样就产生了一个限制，那就是你需要继承</span><span>Template</span><span>然后重新实现具体的小步骤。如果这个</span><span>Template</span><span>有许多方法，就像</span><span>JdbcTemplate,</span><span>如果你每次继承这个庞大的类，然后只是重写某个小步骤中来订制你自己的功能，就会显得非常笨重，更何况数据库操作使用的如此频繁，难道你每进行一个操作就通过继承订制一个，显然不可能这么做。</span></p>
<p><span>Spring</span><span>使用</span><span>Callback</span><span>模式与之配合，达到了去掉重复代码的效果，同时增加了很大的灵活性，你只需要实现某些</span><span>CallBack</span><span>就可轻松订制出</span><span>Template</span><span>。</span></p>
<p><span>那么什么时候才是</span><span>Callback</span><span>模式与</span><span>Template</span><span>模式结合的最佳时机呢。显然如果每个具体的步骤都需要真正去具体实现而不是简单的改变参数或设置某个对象就</span><span>ok</span><span>的话，使用</span><span>Callback</span><span>很难去订制，因为你可能需要传递多个</span><span>Callback</span><span>作为参数，并让用户去实现，是用</span><span>Java</span><span>的内部类本来就是一个比较丑陋的语法，更何况参数是多个。这相当于你把每个小步骤封装成为接口，然后分别继承之然后实现。显然没有达到方便灵活的效果，这时候直接使用</span><span>Template method</span><span>模式就比结合</span><span>Callback</span><span>要好。而如果用户只需要定制一个方法能就达到用户的要求，或者更简单，只是设置不同的参数，那么使用</span><span>Callback</span><span>就具有很好的灵活性。</span></p>
<br><br>Template例子<br><span>Servlet</span><br><br><br>Callback&nbsp;例子<br>JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);<br>jdbcTemplate<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .update(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "UPDATE user SET age = ? WHERE id = ?",<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new PreparedStatementSetter() {<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;public void setValues(PreparedStatementSetter ps)<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; throws SQLException {<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; ps.setInt(1, 18);<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; ps.setString(2, "erica");<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;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<img src ="http://www.blogjava.net/gm_jing/aggbug/127447.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gm_jing/" target="_blank">黎夕</a> 2007-07-02 10:46 <a href="http://www.blogjava.net/gm_jing/articles/127447.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Session Facade模式 </title><link>http://www.blogjava.net/gm_jing/articles/124855.html</link><dc:creator>黎夕</dc:creator><author>黎夕</author><pubDate>Sun, 17 Jun 2007 15:25:00 GMT</pubDate><guid>http://www.blogjava.net/gm_jing/articles/124855.html</guid><wfw:comment>http://www.blogjava.net/gm_jing/comments/124855.html</wfw:comment><comments>http://www.blogjava.net/gm_jing/articles/124855.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gm_jing/comments/commentRss/124855.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gm_jing/services/trackbacks/124855.html</trackback:ping><description><![CDATA[<table class=width_fix cellSpacing=0 cellPadding=0 border=0>
    <tbody>
        <tr>
            <td class=title colSpan=2>Session Facade设计模式</td>
        </tr>
        <tr>
            <td class=p9 style="PADDING-LEFT: 2px"><script language=javascript>putUrl();
            superUrl('\/b391997\/','JAVA 基础','JAVA 基础','\/b391997\/d26431792.htm','Session Facade设计模式','Session Facade设计模式');
            </script>引用地址：http://www.xici.net/b391997/d26431792.htm</span>&nbsp;[<a onclick='clipboardData.setData("Text", document.title + "\r\nhttp://www.xici.net" + location.pathname + "\r\n");alert("地址复制成功！");return false;' href="http://www.xici.net/b391997/d26431792.htm#"><font color=#1111cc>复制</font></a>│<a onclick='clipboardData.setData("Text", superPath);alert("地址复制成功！");return false;' href="http://www.xici.net/b391997/d26431792.htm#"><font color=#1111cc>超文本复制</font></a>] </td>
            <td align=right><a href="http://www.xici.net/b391997/board.asp" target=_blank><font color=#1111cc>返回《JAVA 基础》</font></a> <a onclick=closeWindow() href="http://www.xici.net/b391997/d26431792.htm#"><font color=#1111cc>关闭窗口</font></a> </td>
        </tr>
    </tbody>
</table>
<table class=board_padding cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td align=middle>
            <table class=width_fix cellSpacing=0 cellPadding=0 border=0>
                <tbody>
                    <tr>
                        <td class=doc_td style="PADDING-RIGHT: 8px" vAlign=top>
                        <div class=photo_64><span><br></span>&nbsp;</div>
                        </td>
                        <td class=doc_td vAlign=top width="99%" colSpan=2>
                        <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                            <tbody>
                                <tr>
                                    <td class=p9><img height=15 src="http://files.xici.net/_img/board/doc0.gif" width=15>&nbsp;</td>
                                    <td class=p9 align=right></td>
                                </tr>
                            </tbody>
                        </table>
                        <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                            <tbody>
                                <tr>
                                    <td class=doc_txt id=text_1_0>
                                    <table cellSpacing=0 cellPadding=0 width=580 border=0>
                                        <tbody>
                                            <tr>
                                                <td>
                                                <p><font size=3>J2EE是Sun公司提出的开发和运行企业级Web应用的标准，可以用于开发大型的、多层次的以及分布式的企业级Web应用系统。J2EE技术为组件开发提供了广泛的支持，同时也提供了丰富的开发工具和服务，便于开发模块化的，可重用的和平台独立的业务逻辑<sup> [4]</sup>。设计模式的优势在J2EE应用的设计中得到了充分的体现。</font>
                                                <p>
                                                <p><font size=3>EJB的设计是J2EE应用设计中的核心模块。它强调的是可复用性、可维护性、可移植性等。当开发者设计EJB时，最困难的工作就是要选择一个正确的体系结构，或者一个正确的逻辑层的划分<sup> [5]</sup>。目前，EJB的设计模式有几十种，如何选择适合自己项目的模式是EJB设计的关键问题，也是最难解决的问题。</font>
                                                <p>
                                                <p><strong>1引入Session Facade模式</strong>
                                                <p>
                                                <p><font size=3>EJB客户端可以直接通过网络访问</font>参与工作流的业务对象，如图1所示：
                                                <p>
                                                <p align=center>&nbsp;<img height=191 alt="" src="http://www.blogjava.net/images/blogjava_net/gm_jing/cs.jpg" width=362 border=0>
                                                <p>
                                                <p align=center>图1：无Session Facade时的情况
                                                <p>
                                                <p><font size=3>这样处理时存在着几个问题：</font>
                                                <p>
                                                <p><font size=3>l</font>　　　　 <font size=3>当依靠RMI-IIOP技术进行跨越网络的调用时，系统性能会受到极大影响。如果一个客户端需要两个业务对象的信息，比如用户在网上购物时，同时需要得到CustomerEJB中的用户名及购物密码、AddressEJB中的用户E-MAIL和电话等，则将需要两个远程方法调用，并且这两个调用都是细粒度的。如果一个EJB客户端需要调用三个业务对象的方法，则将需要三个远程方法调用。当存在着大量的EJB客户端，而每个客户端又需要调用多个业务对象时，这种细粒度的网络调用就会成倍的增加，系统性能就会因为网络负载而降低。</font>
                                                <p>
                                                <p><font size=3>l</font>　　　　 <font size=3>更重要的是，如果允许 EJB 客户端直接访问业务对象，那么就要求客户端了解业务对象的内部方法，这样就把业务模型的细节不适当地暴露给了客户端，从而增加了客户端与业务对象之间的耦合度。当业务对象的方法做了改动时，调用它的客户端的程序也要进行相应的修改。这样做就违背了EJB的设计中要求具有良好的可移植性的原则。</font>
                                                <p>
                                                <p><font size=3>为了解决这个问题，有几个常见的解决方案：</font>
                                                <p>
                                                <p><font size=3>1．在业务对象中加入额外的逻辑，在一个单独的客户调用中完成许多操作。这个解决方案引入了维护问题。如果每次需要性能增强时都在业务对象上增加应用逻辑，则业务对象将很快变得臃肿和难于理解，难以维护和复用。</font>
                                                <p>
                                                <p><font size=3>2．为客户端划分一个聚合，该聚合通过JTA构建一个大的事务。每个业务对象的方法调用都工作在一个相同的事务之下。这个改进的解决方案也有很多缺点，如网络开销高，并发性差，耦合度高，可复用性差，可维护性差等。</font>
                                                <p>
                                                <p><font size=3>3．在EJB设计中，避免直接访问业务对象的最佳解决方案就是运用Session Facade模式。</font>
                                                <p>
                                                <p><strong>2 Session Facade模式介绍</strong>
                                                <p>
                                                <p><font size=3>Facade模式描述为：&#8220;为子系统中的一套接口提供了一个统一的接口。Facade 定义了一个更高层次的接口，使子系统更容易使用。&#8221;<sup>[6]</sup> 在EJB设计中，Session Facade是应用最广泛的设计模式。它应用Session Bean来实现Facade模式的思想,把构成子系统的一套业务对象&#8220;包装&#8221;在Session Bean中。这样，Session Facade作为客户端访问业务对象的拦截器，屏蔽了业务对象。EJB客户端访问Session Bean来代替访问业务对象，当一个EJB客户端需要调用多个业务对象的方法时，它只需要进行一次粗粒度的远程方法调用，将请求送给Session Facade, 再由Session Facade通过本地方法调用，调用相应的业务对象，执行其方法。这样就减轻了网络负载，提高了系统性能。并且当业务对象的方法改动时，只需要修改Session Bean，而客户端可以保持不变。这就减少了客户端和业务对象之间的耦合度，同时客户端也不必管理事务的细节。如图2所示：</font>
                                                <p>
                                                <p align=center>&nbsp;<img height=191 alt="" src="http://www.blogjava.net/images/blogjava_net/gm_jing/935cs.jpg" width=467 border=0>
                                                <p>
                                                <p>图2：有Session Facade时的情况
                                                <p>
                                                <p><strong>3 Session Facade模式的优点</strong>
                                                <p>
                                                <p><font size=3>1)</font>　　　 <font size=3>严格分离了业务逻辑和表示层，降低系统的耦合度，提高可管理性。Session Facade作为客户端和业务对象之间的控制器，实现客户端和业务对象之间的交互。</font>Session Facade模式将业务逻辑完全封装在Session Bean中。客户端作为表示层，无须关心业务逻辑层的事情，这就严格的将业务逻辑从表示逻辑分离。从而可以减少紧密耦合，以及客户端对业务组件的依赖性。
                                                <p>
                                                <p><font size=3>2)</font>　　　 <font size=3>提供简单的统一接口。客户端和业务对象之间的交互是非常复杂的。Session Facade抽象了该复杂性，并向客户端提供了一个容易理解和使用简单的统一接口。Session Facade可以向不同类型的客户端提供统一的粗粒度访问接口。</font>
                                                <p>
                                                <p><font size=3>3)</font><font color=#ff0000>　　　</font> <font size=3>降低网络开销，提高系统性能。由于Session Facade提供了粗粒度的访问，因此，客户端可以只调用一次Session Facade的远程方法，即只需要一次网络调用；在</font>服务器端，Session Facade和业务对象通过本地接口来调用，从而不需要任何网络开销。 即使Session Facade和业务对象通过远程接口来调用, 大多数应用服务器也将优化它们之间的通信。
                                                <p>
                                                <p><font size=3>4)</font><font color=#ff0000>　　　</font> <font size=3>安全集成管理。由于Session Facade是客户端访问服务器的接口，这样应用程序的安全策略就可以在Session Facade层进行管理。同时由于Session Facade只需要管理相对较少的粗粒度方法，所以安全策略变得更加容易使用和实现。</font>
                                                <p>
                                                <p><font size=3>5)</font>　　　 <font size=3>事务集成控制。Session Facade提供了管理和定义事务的集中点。在Session Facade上实施事务控制比在所参与的每一个业务对象上实施事务控制关注的对象要少，粒度更大，更容易管理和控制。</font></p>
                                                </td>
                                            </tr>
                                        </tbody>
                                    </table>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/gm_jing/aggbug/124855.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gm_jing/" target="_blank">黎夕</a> 2007-06-17 23:25 <a href="http://www.blogjava.net/gm_jing/articles/124855.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>