??xml version="1.0" encoding="utf-8" standalone="yes"?>一区二区三区四区不卡在线 ,97久久超碰精品国产,国产成人久久精品http://www.aygfsteel.com/dreamstone/category/24599.html开发出高质量的pȝzh-cnMon, 20 Aug 2007 03:41:36 GMTMon, 20 Aug 2007 03:41:36 GMT60l于可以在Java中用lazy loading的单态了http://www.aygfsteel.com/dreamstone/archive/2007/02/27/101000.htmldreamstonedreamstoneTue, 27 Feb 2007 12:10:00 GMThttp://www.aygfsteel.com/dreamstone/archive/2007/02/27/101000.htmlhttp://www.aygfsteel.com/dreamstone/comments/101000.htmlhttp://www.aygfsteel.com/dreamstone/archive/2007/02/27/101000.html#Feedback12http://www.aygfsteel.com/dreamstone/comments/commentRss/101000.htmlhttp://www.aygfsteel.com/dreamstone/services/trackbacks/101000.html在我的这文章http://www.aygfsteel.com/dreamstone/archive/2006/11/04/79026.html中写了ؓ什么不要用Java的lazy loading ,即是double-check也解决不了问题,但是有h解决了这个问题?br>佩服啊。实在是巧妙Q如此简?br>注意Q在多个虚拟机的情况下这个方法还是不能用的,但是一般情况下是可以的?br>实现方式Q?br>

public   class  Singleton  {   
  
  
static   class  SingletonHolder  {   
    
static  Singleton instance  =   new  Singleton();   
  }
   
  
  
public   static  Singleton getInstance()  {   
    
return  SingletonHolder.instance;   
  }
   
  
}
  

q个写法的发明者是Google公司的Bob lee?br>他还写了个轻量IoC容器Q据说不要配制文Ӟ性能比spring?00倍。感?00倍有些夸张,不过可以看看?br>



dreamstone 2007-02-27 20:10 发表评论
]]>
推荐l大家一个很有趣的话题: Javaeye上的"奇技淫y"http://www.aygfsteel.com/dreamstone/archive/2007/02/27/100950.htmldreamstonedreamstoneTue, 27 Feb 2007 08:34:00 GMThttp://www.aygfsteel.com/dreamstone/archive/2007/02/27/100950.htmlhttp://www.aygfsteel.com/dreamstone/comments/100950.htmlhttp://www.aygfsteel.com/dreamstone/archive/2007/02/27/100950.html#Feedback0http://www.aygfsteel.com/dreamstone/comments/commentRss/100950.htmlhttp://www.aygfsteel.com/dreamstone/services/trackbacks/100950.htmlhttp://www.javaeye.com/topic/39694?page=1
文中׃个问题提Z各种各样的思\Q很多hl出了自q观点Q是个对人有启发的话题?br>下边是我惛_的一个思\Q就是利用jdk1.6的script支持Q也一个办法吧。徏议看完了上边的讨论再?br>我下边的内容Q要不可能不知道是什么意思?br>
    static double getOverall(Details[] arr ,String method){
        
double sum = 0;
        
try{
            ScriptEngineManager factory 
= new ScriptEngineManager();
            ScriptEngine engine 
= factory.getEngineByName("JavaScript");
            
for(int i=0;i<arr.length;i++){
                engine.put(
"obj", arr[i]);
                Object obj 
= engine.eval("obj."+method);
                
if (obj instanceof Double){
                    sum 
+= ((Double)obj).doubleValue();
                }

            }

        }
catch(Exception e){
            e.printStackTrace();
        }

        
return sum;
    }

    
    
static double getOverallBalance(Details[] arr) {
        
return getOverall(arr,"getBalance()");
    }


    
static double getOverallFixed(Details[] arr) {
        
return getOverall(arr,"getFixed()");
    }

    ..    
最l的实现是上边的样子,利用script我们能实现通过函数名来调用函数Q其实内部和动态代理,反射
 的效果是一L。不q就是写h单,学习成本低。因为用java的h大部分是了解javascript的?

dreamstone 2007-02-27 16:34 发表评论
]]>
设计模式相关文章 -- 目录http://www.aygfsteel.com/dreamstone/archive/2007/01/08/92491.htmldreamstonedreamstoneMon, 08 Jan 2007 15:42:00 GMThttp://www.aygfsteel.com/dreamstone/archive/2007/01/08/92491.htmlhttp://www.aygfsteel.com/dreamstone/comments/92491.htmlhttp://www.aygfsteel.com/dreamstone/archive/2007/01/08/92491.html#Feedback2http://www.aygfsteel.com/dreamstone/comments/commentRss/92491.htmlhttp://www.aygfsteel.com/dreamstone/services/trackbacks/92491.html阅读全文

dreamstone 2007-01-08 23:42 发表评论
]]>
更详l的 Bridge Adapter Facade模式之间的比?/title><link>http://www.aygfsteel.com/dreamstone/archive/2007/01/08/92482.html</link><dc:creator>dreamstone</dc:creator><author>dreamstone</author><pubDate>Mon, 08 Jan 2007 15:21:00 GMT</pubDate><guid>http://www.aygfsteel.com/dreamstone/archive/2007/01/08/92482.html</guid><wfw:comment>http://www.aygfsteel.com/dreamstone/comments/92482.html</wfw:comment><comments>http://www.aygfsteel.com/dreamstone/archive/2007/01/08/92482.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.aygfsteel.com/dreamstone/comments/commentRss/92482.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/dreamstone/services/trackbacks/92482.html</trackback:ping><description><![CDATA[<a href="http://www.aygfsteel.com/dreamstone/archive/2007/01/07/92268.html">在这文章中</a>Q我写了Bridge和adapter模式的区?但是 maninred?br>Bridge和adapter是没有关pȝQ而和Facade比较象,但在我的l验中更多的时?br>是会hBridge和adapter而不是FacadeQ这里详l的列出三个模式的比?.<br>一,定义:<br>1.Facade模式是ؓ一个复杂系l提供一个简单的接口?br>比如你要d物馆参观Q很多东西,你一个个到处去问每个东西的管理员很麻烦,所以你找一个导游,让他l你一个个介绍Q你只要扑ֈ导游好了。导游就是门面?br>2Q适配器模式,引用一下GOF95中的?<br>适配器模式是把一个类的接口变换成客户端所期待的另一U接口,从而原本因接口不匚w而无法工作的两个c能够工作到一赗?br>举个例子Q例如变压器<br>3QBridge模式:<br>GOF95中的桥梁模式的描qͼ桥梁模式的用意是"抽象化与实现化p,使的二者可以独立变化?br>例如AWT的实?br>?目的:<br>1,Facade模式使用在给一个复杂的pȝ提供l一的门?接口),目的是简化客L的操?但ƈ没有改变接口.<br>2,Adapter模式使用在两个部分有不同的接口的情况,目的是改变接?使两个部分协同工?br>3,桥梁模式是ؓ了分L象和实现<br>?使用场合<br>1,Facade模式出现较多的情冉|q样的情?你有一个复杂的pȝ,对应了各U情?<br>客户看了说功能不?但是使用太麻?你说没问?我给你提供一个统一的门?<br>所以Facade使用的场合多是对pȝ?优化".<br>2,Adapter模式出现的情冉|q样,你有一个类提供接口A,但是你的客户需要一个实现接口B的类,<br>q个时候你可以写一个Adapter让把A接口变成B接口,所以Adapter使用的场合是<br>指鹿为马.是你受Ҏ气的时?一边告诉你我只能提供给你A(?,一边告诉你?br>我只要B(?,他长了四条腿,你没办法?把鹿牵过去说,q是?你看他有四条?<br>(当然实现指鹿为马也有两种Ҏ,一个方法是你只露出鹿的四条?说你看这是马,q种方式是<br>装方式的Adapter实现,另一U方式是你把鹿牵q去,但是首先介绍l他说这是马,因ؓ他长了四条腿<br>q种是承的方式.)<br>3,Bridge模式在一般的开发中出现的情况ƈ不多,AWT是一?SWT也算部分?<br>如果你的客户要求你开发一个系l?q个pȝ在Windows下运行界面的样子是Windows的样?<br>在Linux下运行是Linux下的样子.在Macintosh下运行要是Mac Os的样?<br>怎么? 定义一pd的控件Button,Text,radio,checkBox{等.供上层开发?br>使用,他们使用q些控g的方?利用q些控g构造一个系l的GUI,然后你ؓq些控g<br>写好Linux的实?让它在Linux上调用Linux本地的对应控?<br>在Windows上调用Windows本地的对应控?在Macintosh上调用Macintosh本地的对应控?br>ok,你的d完成?<br>?需求程?br>1,Facade的需求程度是"中等",因ؓ你不提供FacadeE序照样能工?只是不够?<br>2,Adapter的需求程度是"必须",因ؓ你不q么做就不能工作,除非你自׃头实C?<br>3,Bridge的需求程度是"一?,适合_求精的h,因ؓ你可以写三个E序l客?<br>?出现时期<br>1,Facade出现在项目中?再优?br>2,Adapter出现在项目后?大部分都有了,差的仅仅是接口不?br>3,Bridge出现在项目前?你想让你的系l更灉|,更cool<br>?在写文章的时候想到的<br>1,Facade很多时候是1:m的关p?br>2,Adapter很多是候是1:1的关p?br>3,Bridge很多时候是m:n的关p?br>呵呵.<br>?最?br>另外:回应一下maninred<br>1,我ƈ没有把模式看的很独立,其实很多模式是配合用的,而且在一定情况下可以<br>用一个替换另一?同一个需?有可能当你思考的角度不同?使用的模式就不同?<br>2,设计模式q不?用OO的封装来装所有的东西",模式其实可以应用于所有的设计?br>和OO没有直接的关p?只是因ؓ计算机的设计模式大部分是GOF攉ȝ?<br>他们讲解设计模式是用的C++,而在Java中得C大量应用,所以我们谈到设计模?br>的时候多提到OO.其实模式更早应用于徏{学,Alexander的《徏{的永恒之道》讲?br>是设计模式。所以说设计模式应该是设计过E中U篏下来的一些成型的东西?br>更深入一点,《Java与模式》的作者认为模式v源于中国的道教思想Q讲的是哲学。呵c?br>3Q对于模式的使用Q个人感觉,模式很大E度上是Z对应q类需求的所有情况,也就<br>是最复杂情况Q最灉|情况Q当我们实际的开发中q没有遇到这么多q样的情c?br>所以在需要的时候用,Ҏ需求简化用,而不是照搬?br>4,虽然模式是相关的Q但是只有知道了每个模式的区别点Q才能更好的Ҏ需求选择使用哪个模式? <img src ="http://www.aygfsteel.com/dreamstone/aggbug/92482.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/dreamstone/" target="_blank">dreamstone</a> 2007-01-08 23:21 <a href="http://www.aygfsteel.com/dreamstone/archive/2007/01/08/92482.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>桥接模式和适配器模式的区别http://www.aygfsteel.com/dreamstone/archive/2007/01/07/92268.htmldreamstonedreamstoneSun, 07 Jan 2007 13:53:00 GMThttp://www.aygfsteel.com/dreamstone/archive/2007/01/07/92268.htmlhttp://www.aygfsteel.com/dreamstone/comments/92268.htmlhttp://www.aygfsteel.com/dreamstone/archive/2007/01/07/92268.html#Feedback4http://www.aygfsteel.com/dreamstone/comments/commentRss/92268.htmlhttp://www.aygfsteel.com/dreamstone/services/trackbacks/92268.html
共同点:桥接和适配器都是让两个东西配合工作
不同点:出发点不同?br>         适配器:改变已有的两个接口,让他们相宏V?br>         桥接模式Q分L象化和实玎ͼ使两者的接口可以不同Q目的是分离?br>
所以说Q如果你拿到两个已有模块Q想让他们同时工作,那么你用的适配器?br>如果你还什么都没有Q但是想分开实现Q那么桥接是一个选择?br>
桥接是先有桥Q才有两端的东西
适配是先有两边的东西Q才有适配?br>
桥接是在桥好了之后,两边的东西还可以变化?br>
例如游戏手柄Q就象个桥,它把你的M操作转化成指令?br>Q虽Ӟ你可以Q何操作组合,但是你的操作׃开׃左右Qa,bQ选择 Q确定)
JRE本n是一个就是一个很好的桥,先写好在linux上执行的JreQ再写好可以在windows下执行的JREQ?br>q样无论什么样的JavaE序Q只要配和相应的Jrep在Linux或者Windows上运?
两个Jreq没有限定你写什么样的程序,但要求你必须用Java来写?

dreamstone 2007-01-07 21:53 发表评论
]]>
Java与模?--- 适配器模?/title><link>http://www.aygfsteel.com/dreamstone/archive/2007/01/07/92229.html</link><dc:creator>dreamstone</dc:creator><author>dreamstone</author><pubDate>Sun, 07 Jan 2007 08:07:00 GMT</pubDate><guid>http://www.aygfsteel.com/dreamstone/archive/2007/01/07/92229.html</guid><wfw:comment>http://www.aygfsteel.com/dreamstone/comments/92229.html</wfw:comment><comments>http://www.aygfsteel.com/dreamstone/archive/2007/01/07/92229.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/dreamstone/comments/commentRss/92229.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/dreamstone/services/trackbacks/92229.html</trackback:ping><description><![CDATA[适配器模式:<br>如果你有两个~译好的(无源代码)c,cA有某些功能,但是需要一个xmld模块才能工作Q?br>q个模块要实现这个接?<br>public interface XmlReader{<br>       public InputStream xmlReader();<br>}<br>你的另一个类B恰好有这个功能,但是B实现的是q个接口:<br>public interface ReaderXml{<br>       public InputStream readerXml();<br>}<br>q个时候我们的做法是写个适配?br>public class Adapter implements XmlReader extends B{<br>       public InputStream xmlReader(){<br>              return readerXml();<br>      }<br>}<br>q个是适配器模式了?br>适配器模式还有另外一U实现方?br>public class Adapter implements XmlReader<br>       ReaderXml b = new B();<br>       public InputStream xmlReader(){<br>               return b.readerXml();<br>       }<br>} <img src ="http://www.aygfsteel.com/dreamstone/aggbug/92229.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/dreamstone/" target="_blank">dreamstone</a> 2007-01-07 16:07 <a href="http://www.aygfsteel.com/dreamstone/archive/2007/01/07/92229.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java中的模式 Q-Q?构造者模?/title><link>http://www.aygfsteel.com/dreamstone/archive/2007/01/07/92222.html</link><dc:creator>dreamstone</dc:creator><author>dreamstone</author><pubDate>Sun, 07 Jan 2007 07:19:00 GMT</pubDate><guid>http://www.aygfsteel.com/dreamstone/archive/2007/01/07/92222.html</guid><wfw:comment>http://www.aygfsteel.com/dreamstone/comments/92222.html</wfw:comment><comments>http://www.aygfsteel.com/dreamstone/archive/2007/01/07/92222.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.aygfsteel.com/dreamstone/comments/commentRss/92222.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/dreamstone/services/trackbacks/92222.html</trackback:ping><description><![CDATA[一Q一般来说你要做一件复杂的事情的时候,把它分成多个的部分来做是比较好的方法,<br>把每个小部分做完Q然后结合成一个完整的事情。例如生产一辆汽车,你是一个个零g<br>生完了Q才l装成一辆辆汽R。这个就是徏造模式的工作?br>二,建造模式的角色<br>1、抽象徏造?br>2、具体构造?br>3、导演?br>4、品角?br>三、实C?Q?br> <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.aygfsteel.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">抽象构造?<br></span><span style="COLOR: #008080"> 2</span><span style="COLOR: #000000"><img id=Codehighlighter1_28_171_Open_Image onclick="this.style.display='none'; Codehighlighter1_28_171_Open_Text.style.display='none'; Codehighlighter1_28_171_Closed_Image.style.display='inline'; Codehighlighter1_28_171_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_28_171_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_28_171_Closed_Text.style.display='none'; Codehighlighter1_28_171_Open_Image.style.display='inline'; Codehighlighter1_28_171_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span style="COLOR: #0000ff">abstract</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span id=Codehighlighter1_28_171_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.aygfsteel.com/Images/dot.gif"></span><span id=Codehighlighter1_28_171_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080"> 3</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">构造零?/span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080"> 4</span><span style="COLOR: #008000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">abstract</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> buildPart1();<br></span><span style="COLOR: #008080"> 5</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">构造零?/span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080"> 6</span><span style="COLOR: #008000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">abstract</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> buildPart2();<br></span><span style="COLOR: #008080"> 7</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">q还商品</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080"> 8</span><span style="COLOR: #008000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">abstract</span><span style="COLOR: #000000"> Product retrieveResult();<br></span><span style="COLOR: #008080"> 9</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>    <br></span><span style="COLOR: #008080">10</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">11</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/None.gif" align=top>具体构造?<br></span><span style="COLOR: #008080">12</span><span style="COLOR: #000000"><img id=Codehighlighter1_224_568_Open_Image onclick="this.style.display='none'; Codehighlighter1_224_568_Open_Text.style.display='none'; Codehighlighter1_224_568_Closed_Image.style.display='inline'; Codehighlighter1_224_568_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_224_568_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_224_568_Closed_Text.style.display='none'; Codehighlighter1_224_568_Open_Image.style.display='inline'; Codehighlighter1_224_568_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> ConcreteBuilder </span><span style="COLOR: #0000ff">extends</span><span style="COLOR: #000000"> Builder</span><span id=Codehighlighter1_224_568_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.aygfsteel.com/Images/dot.gif"></span><span id=Codehighlighter1_224_568_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">13</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>    </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> Product product ;<br></span><span style="COLOR: #008080">14</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>    <br></span><span style="COLOR: #008080">15</span><span style="COLOR: #000000"><img id=Codehighlighter1_287_402_Open_Image onclick="this.style.display='none'; Codehighlighter1_287_402_Open_Text.style.display='none'; Codehighlighter1_287_402_Closed_Image.style.display='inline'; Codehighlighter1_287_402_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_287_402_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_287_402_Closed_Text.style.display='none'; Codehighlighter1_287_402_Open_Image.style.display='inline'; Codehighlighter1_287_402_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> Product retrieveResult()</span><span id=Codehighlighter1_287_402_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.aygfsteel.com/Images/dot.gif"></span><span id=Codehighlighter1_287_402_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">16</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>        product</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> Product();<br></span><span style="COLOR: #008080">17</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>        product.setPart1(buildPart1());<br></span><span style="COLOR: #008080">18</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>        product.setPart2(buildPart2());<br></span><span style="COLOR: #008080">19</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> product;<br></span><span style="COLOR: #008080">20</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>    }</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">21</span><span style="COLOR: #000000"><img id=Codehighlighter1_431_484_Open_Image onclick="this.style.display='none'; Codehighlighter1_431_484_Open_Text.style.display='none'; Codehighlighter1_431_484_Closed_Image.style.display='inline'; Codehighlighter1_431_484_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_431_484_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_431_484_Closed_Text.style.display='none'; Codehighlighter1_431_484_Open_Image.style.display='inline'; Codehighlighter1_431_484_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> Object buildPart1()</span><span id=Codehighlighter1_431_484_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.aygfsteel.com/Images/dot.gif"></span><span id=Codehighlighter1_431_484_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">22</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">构造part1</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">23</span><span style="COLOR: #008000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">        Object part1 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> <img src="http://www.aygfsteel.com/Images/dot.gif">;<br></span><span style="COLOR: #008080">24</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> part1;<br></span><span style="COLOR: #008080">25</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>    }</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">26</span><span style="COLOR: #000000"><img id=Codehighlighter1_513_566_Open_Image onclick="this.style.display='none'; Codehighlighter1_513_566_Open_Text.style.display='none'; Codehighlighter1_513_566_Closed_Image.style.display='inline'; Codehighlighter1_513_566_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_513_566_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_513_566_Closed_Text.style.display='none'; Codehighlighter1_513_566_Open_Image.style.display='inline'; Codehighlighter1_513_566_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> Object buildPart2()</span><span id=Codehighlighter1_513_566_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.aygfsteel.com/Images/dot.gif"></span><span id=Codehighlighter1_513_566_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">27</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">构造part2</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">28</span><span style="COLOR: #008000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">        Object part2 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> <img src="http://www.aygfsteel.com/Images/dot.gif">;<br></span><span style="COLOR: #008080">29</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> part2;<br></span><span style="COLOR: #008080">30</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>    }</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">31</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">32</span><span style="COLOR: #000000"><img id=Codehighlighter1_590_746_Open_Image onclick="this.style.display='none'; Codehighlighter1_590_746_Open_Text.style.display='none'; Codehighlighter1_590_746_Closed_Image.style.display='inline'; Codehighlighter1_590_746_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_590_746_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_590_746_Closed_Text.style.display='none'; Codehighlighter1_590_746_Open_Image.style.display='inline'; Codehighlighter1_590_746_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Product</span><span id=Codehighlighter1_590_746_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.aygfsteel.com/Images/dot.gif"></span><span id=Codehighlighter1_590_746_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">33</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>    Object Part1;<br></span><span style="COLOR: #008080">34</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>    Object Part2;<br></span><span style="COLOR: #008080">35</span><span style="COLOR: #000000"><img id=Codehighlighter1_657_682_Open_Image onclick="this.style.display='none'; Codehighlighter1_657_682_Open_Text.style.display='none'; Codehighlighter1_657_682_Closed_Image.style.display='inline'; Codehighlighter1_657_682_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_657_682_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_657_682_Closed_Text.style.display='none'; Codehighlighter1_657_682_Open_Image.style.display='inline'; Codehighlighter1_657_682_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> setPart1(Object Part1)</span><span id=Codehighlighter1_657_682_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.aygfsteel.com/Images/dot.gif"></span><span id=Codehighlighter1_657_682_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">36</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>        </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.part1 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> part1;<br></span><span style="COLOR: #008080">37</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>    }</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">38</span><span style="COLOR: #000000"><img id=Codehighlighter1_719_744_Open_Image onclick="this.style.display='none'; Codehighlighter1_719_744_Open_Text.style.display='none'; Codehighlighter1_719_744_Closed_Image.style.display='inline'; Codehighlighter1_719_744_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_719_744_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_719_744_Closed_Text.style.display='none'; Codehighlighter1_719_744_Open_Image.style.display='inline'; Codehighlighter1_719_744_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> setPart2(Object Part2)</span><span id=Codehighlighter1_719_744_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.aygfsteel.com/Images/dot.gif"></span><span id=Codehighlighter1_719_744_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">39</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>        </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.part2 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> part2;<br></span><span style="COLOR: #008080">40</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>    }</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">41</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">42</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/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">43</span><span style="COLOR: #008000"><img id=Codehighlighter1_775_943_Open_Image onclick="this.style.display='none'; Codehighlighter1_775_943_Open_Text.style.display='none'; Codehighlighter1_775_943_Closed_Image.style.display='inline'; Codehighlighter1_775_943_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_775_943_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_775_943_Closed_Text.style.display='none'; Codehighlighter1_775_943_Open_Image.style.display='inline'; Codehighlighter1_775_943_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Director</span><span id=Codehighlighter1_775_943_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.aygfsteel.com/Images/dot.gif"></span><span id=Codehighlighter1_775_943_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">44</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>    </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> Builder builder;<br></span><span style="COLOR: #008080">45</span><span style="COLOR: #000000"><img id=Codehighlighter1_827_941_Open_Image onclick="this.style.display='none'; Codehighlighter1_827_941_Open_Text.style.display='none'; Codehighlighter1_827_941_Closed_Image.style.display='inline'; Codehighlighter1_827_941_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_827_941_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_827_941_Closed_Text.style.display='none'; Codehighlighter1_827_941_Open_Image.style.display='inline'; Codehighlighter1_827_941_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> construct()</span><span id=Codehighlighter1_827_941_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.aygfsteel.com/Images/dot.gif"></span><span id=Codehighlighter1_827_941_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">46</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>        builder </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> ConcreteBuilder();<br></span><span style="COLOR: #008080">47</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>        builder.retrieveResult();<br></span><span style="COLOR: #008080">58</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>    }</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">49</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div> <br> <img src ="http://www.aygfsteel.com/dreamstone/aggbug/92222.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/dreamstone/" target="_blank">dreamstone</a> 2007-01-07 15:19 <a href="http://www.aygfsteel.com/dreamstone/archive/2007/01/07/92222.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>visitor模式概念-------------Q?---- visitor模式q一?/title><link>http://www.aygfsteel.com/dreamstone/archive/2006/12/20/88948.html</link><dc:creator>dreamstone</dc:creator><author>dreamstone</author><pubDate>Tue, 19 Dec 2006 17:26:00 GMT</pubDate><guid>http://www.aygfsteel.com/dreamstone/archive/2006/12/20/88948.html</guid><wfw:comment>http://www.aygfsteel.com/dreamstone/comments/88948.html</wfw:comment><comments>http://www.aygfsteel.com/dreamstone/archive/2006/12/20/88948.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/dreamstone/comments/commentRss/88948.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/dreamstone/services/trackbacks/88948.html</trackback:ping><description><![CDATA[<p>visitor模式理论及学术概?------------Q?----   visitor模式q一?br>一Q访问者模式的角色Q?br>抽象讉K者:声明一个或者多个访问操作,形成所有的具体元素都要实现的接?br>具体讉K者:实现抽象讉K者所声明的接?br>抽象节点Q声明一个接受操作,接受一个访问者对象作为参?br>具体节点Q实C抽象元素所规定的接受操?br>l构对象Q遍历结构中的所有元素,cMList Set{?br>二,在什么情况下应当使用讉K者模?br>讉K者模式应该用在被讉Kcȝ构比较稳定的时候,换言之系l很出现增加新节点?br>情况。因问者模式对开Q闭原则的支持ƈ不好Q访问者模式允许在节点中加入方法,<br>是倾斜的开闭原则,cM抽象工厂?br>三,讉K者模式的~点Q?br>1Q增加节点困?br>2Q破坏了装<br>因ؓ讉K者模式的~点和复杂性,很多设计师反对用访问者模式。个人感觉应该在了解?br>情况下考虑衡量选择?/p> <p>最后的部分Q?<br>看完本文Q如果你对visitor模式有更多的兴趣Q想了解更多L如下几篇文章?br>1,<a href="http://www.aygfsteel.com/dreamstone/archive/2006/12/20/88947.html"><font color=#7297ce>静态分z,动态分z,多分z,单分z?--------------   visitor模式准备</font></a><br>2<a href="http://www.aygfsteel.com/dreamstone/archive/2006/12/18/88623.html"><font color=#7297ce>,讉K差异cd的集合类 ------------------------   visitor模式入门</font></a><br>3,visitor模式理论及学术概?------------Q?----   visitor模式q一?font color=#7297ce>(<font color=#000000>本文Q?/font></font><br>4Q?a href="http://www.aygfsteel.com/dreamstone/archive/2006/12/18/88623.html"><font color=#7297ce>重蝲overloading和覆写overriding哪个更早执行--   visitor帮助?/font></a><br>虽然排列序?,2,3,4 但是我个人徏议的学习方式?,1,3,4因ؓq个序更方便一般h理解</p> <p> </p> <img src ="http://www.aygfsteel.com/dreamstone/aggbug/88948.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/dreamstone/" target="_blank">dreamstone</a> 2006-12-20 01:26 <a href="http://www.aygfsteel.com/dreamstone/archive/2006/12/20/88948.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>静态分z,动态分z,多分z,单分z?-------------- visitor模式准备http://www.aygfsteel.com/dreamstone/archive/2006/12/20/88947.htmldreamstonedreamstoneTue, 19 Dec 2006 17:08:00 GMThttp://www.aygfsteel.com/dreamstone/archive/2006/12/20/88947.htmlhttp://www.aygfsteel.com/dreamstone/comments/88947.htmlhttp://www.aygfsteel.com/dreamstone/archive/2006/12/20/88947.html#Feedback4http://www.aygfsteel.com/dreamstone/comments/commentRss/88947.htmlhttp://www.aygfsteel.com/dreamstone/services/trackbacks/88947.html1Q定义:发生在编译时期,分派Ҏ静态类型信息发生,重蝲是静态分z?br>2Q什么是静态类型:变量被声明时的类型是静态类?br>      什么是动态类型:变量所引用的对象的真实cd
3Q有两个c?BlackCat ,WhiteCat都承自Cat
如下调用
class Cat{}
class WhiteCat extends Cat{}
class BlackCat extends Cat{}
public class Person {
    
public void feed(Cat cat){
        System.out.println(
"feed cat");
    }

    
public void feed(WhiteCat cat){
        System.out.println(
"feed WhiteCat");
    }

    
public void feed(BlackCat cat){
        System.out.println(
"feed BlackCat");
    }

    
public static void main(String[] args) {
        Cat wc 
= new WhiteCat();
        Cat bc 
= new BlackCat();
        Person p 
= new Person();
        p.feed(wc);
        p.feed(bc);
    }


}

q行l果?
feed cat
feed cat
q样的结果是因ؓ重蝲是静态分z,在编译器执行的,取决于变量的声明cdQ因为wc ,bc都是Cat所以调用的都是feed(Cat cat)的函?
二,动态分z?br>1Q定义:发生在运行期Q动态分z,动态的|换掉某个方法?br>q是上边cM的例子:
class Cat{
    
public void eat(){
        System.out.println(
"cat eat");
    }

}

public class BlackCat extends Cat{
    
public void eat(){
        System.out.println(
"black cat eat");
    }

    
public static void main(String[] args){
        Cat cat 
= new BlackCat();
        cat.eat();
    }

}
q个时候的l果?
black cat eat
q样的结果是因ؓ在执行期发生了向下{型,是动态分z了?br>
三,单分z:
1Q定义:Ҏ一个宗量的cdq行Ҏ的选择
?多分z:
1Q定义:Ҏ多于一个宗量的cdҎ法的选择
2Q说明:多分zօ实是一pd的单分派l成的,区别的地方就是这些但分派不能分割?br>3,C++ ,Java都是动态单分派Q静态多分派语言
多分z语言有:CLOS  Cecil

最后的部分Q?

看完本文Q如果你对visitor模式有更多的兴趣Q想了解更多L如下几篇文章?br>1,静态分z,动态分z,多分z,单分z?--------------   visitor模式准备(本文Q?/font>
2,讉K差异cd的集合类 ------------------------   visitor模式入门
3,visitor模式理论及学术概?------------Q?----   visitor模式q一?br>4Q?a href="http://www.aygfsteel.com/dreamstone/archive/2006/12/18/88623.html">重蝲overloading和覆写overriding哪个更早执行--   visitor帮助?/a>
虽然排列序?,2,3,4但是我个人徏议的学习方式?,1,3,4因ؓq个序更方便一般h理解



dreamstone 2006-12-20 01:08 发表评论
]]>
讉K差异cd的集合类--visitor模式入门http://www.aygfsteel.com/dreamstone/archive/2006/12/18/88623.htmldreamstonedreamstoneMon, 18 Dec 2006 12:18:00 GMThttp://www.aygfsteel.com/dreamstone/archive/2006/12/18/88623.htmlhttp://www.aygfsteel.com/dreamstone/comments/88623.htmlhttp://www.aygfsteel.com/dreamstone/archive/2006/12/18/88623.html#Feedback13http://www.aygfsteel.com/dreamstone/comments/commentRss/88623.htmlhttp://www.aygfsteel.com/dreamstone/services/trackbacks/88623.html讉K差异cd的集合类--visitor模式入门
本文对应代码下蝲q里
一Q问题提?br>讉K同一cd的集合类是我们最常见的事情了Q我们工作中q样的代码太常见了?br>

1 Iterator ie  =  list.iterator();
2 while (ie.hasNext()) {
3     Person p  =  (Person)ie.next();
4     p.doWork();
5 }


q种讉K的特Ҏ集合cM的对象是同一cd象PersonQ他们拥有功能的Ҏrun,我们调用的恰好是q个共同的方法?br>在大部䆾的情况下Q这个是可以的,但在一些复杂的情况Q如被访问者的l承l构复杂Q被讉K者的q不是同一cd象,
也就是说不是l承自同一个根cR方法名也ƈ不相同。例如Java GUI中的事g是一个例子?br>例如q样的问题,有如下类和方?
c:PA ,ҎQrunPA();
c:PB ,ҎQrunPB();
c:PC ,ҎQrunPC();
c:PD ,ҎQrunPD();
c:PE ,ҎQrunPE();
有一个集合类List
List list = new ArrayList();
list.add(new PA());
list.add(new PB());
list.add(new PC());
list.add(new PD());
list.add(new PE());
....
?解决
要求能访问到每个cȝ对应的方法。我们第一反应应该是这L?br>

 1 Iterator ie  =  list.iterator();
 2 while (ie.hasNext()) {
 3     Object obj  =  ie.next();
 4      if  (obj  instanceof  PA) {
 5         ((PA)obj).runPA();
 6     }
else   if (obj  instanceof  PB) {
 7         ((PB)obj).runPB();
 8     }
else   if (obj  instanceof  PC) {
 9         ((PC)obj).runPC();
10     }
else   if (obj  instanceof  PD) {
11         ((PD)obj).runPD();
12     }
else   if (obj  instanceof  PE) {
13         ((PE)obj).runPE();
14     }

15 }


三:新问题及分析解决
当数目变多的时候,l护if else是个费力气的事情Q?br>仔细分析if,else做的工作Q首先判断类型,然後Ҏcd执行相应的函?br>如何才能解决q两个问题呢Q首先想到的是java的多态,多态就是根据参数执行相应的内容Q?br>能很Ҏ的解决第二个问题Q我们可以写q样一个类Q?br>

 1 public   class  visitor {
 2      public   void  run(PA pa) {
 3         pa.runPA();
 4     }

 5      public   void  run(PB pb) {
 6         pb.runPB();
 7     }

 8      public   void  run(PC pc) {
 9         pc.runPC();
10     }

11      public   void  run(PD pd) {
12         pd.runPD();
13     }

14      public   void  run(PE pe) {
15         pe.runPE();
16     }

17 }


q样只要调用runҎQ传入对应的参数p执行了?br>q有一个问题就是判断类型。由于重?overloading)是静态多分配Qjava语言本n是支?静态多分配"的?br>关于q个概念Lq里)所以造成重蝲只根据传入对象的定义cdQ而不是实际的cdQ所以必d传入前就定cdQ?br>q可是个隄问题,因ؓ在容器中对象全是ObjectQ出来后要是判断是什么类型必ȝ
if (xx instanceof xxx)q种ҎQ如果用q种Ҏ启不是又回到了原点,有没有什么更好的办法呢?

我们知到Javaq有另外一个特点,覆写(overriding)Q而覆写是"动态单分配"的(关于q个概念见这?Q?br>那如何利用这个来实现呢?看下边这个方?
 我们让上边的一些类PA PB PC PD PE都实C个接口P,加入一个方?accept();

 1 public   void  accept(visitor v) {
 2      // 把自׃?
 3     v.run( this );
 4 }

 5 然後在visitor中加入一个方?br> 6 public   void  run(P p) {
 7      // 把自׃?
 8     p.accept( this );
 9 }

10 // q样你在遍历中可以这样写
11 Visitor v  =   new  Visitor();
12 Iterator ie  =  list.iterator();
13 while (ie.hasNext()) {
14     P p  =  (P)ie.next();
15         p.accept(v);
16     }

17 }


首先执行的是"把自׃?"Q在q里׃Java的特性,实际执行的是子类的accept(),也就是实际类的accept
然後?把自׃?"Q在q里再次把this传入Q就明确cdQok我们巧妙的利用overriding解决了这个问?br>其实归纳一下第二部分,一个关键点?自己认识自己"Q是不是很可W?br>其实在计计技术领域的很多技术上看v来很高深的东西,其实是现有C会中h的生zL式的一U映?br>而且q种方式是简单的不能再简单的方式。上边的全部q程基本上是一个简单的visitor模式实现,visitor模式
已经是设计模式中比较复杂的模式了Q但其实原理单到你想W。看看下边这个比M怽的理解会更深刅R?/p>

四:一个帮助理解的比喻Q?br>题目Q指挥工人工?br>条gQ你?0个全能工人,10L同工作?br>需求:做完工作
实现Q大喊一声所有hd?/p>

条g变了Q工Z是全能,但是工作相同Qok问题不大
条g再变,工作不是相同Q但工h是全能,ok问题不大

以上三种情况在现实生zM是很发生得Q最多的情况是这P
10个工人,每h会做一U工作,10样工作。你又一份名单Collection)写着谁做什么。但你不认识M?br>q个时候你怎么指挥呢,Ҏ一Q?br>你可以一个个的叫工hQ然後问他们名字Q认识他们,查名单,告诉他们做什么工作?br>你可以直接叫Z们名字,告诉他们q什么,不需要知C是谁?br>看v来很单。但如果你要指挥10万h?Q而且人员是流动的Q每天的Z同,你每天拿C张文?br>其实很简单,最常用的做法是Q你把这份名单脓在墙上,然後大喊一壎ͼ所有h按照ȝQ按照自q分配情况d?br>q里利用的关键点?所有工p识自?Q你不能苛求每个工h会做所有工作,不能苛求所有工作相同,但你
能要求所有工人都认识自己?/p>

再想x们开始的E序,每个工h对应着PA PB PC PD PE....
所有的工h都工hP
每个工h会做的东西不一样runPA runPB runPC
你有一份名单VisitorQ重载)记录着谁做什么工作?/p>

看完上边q些Q你是不是会产生如下的问题:
问题Qؓ什么不把这些方法的Ҏ名做成一LQ那可以解决了?br>例如Q我们每个PA ,PB ,PC都加入一个run ҎQ然後run内部再调用自己对应的runPx()Ҏ?br>{案Q有些时候从不同的角度考虑Q或者因为实现的复杂度早成很隄一Ҏ名?br>例如上边指挥人工作的例子的例子,其实runҎ是大叫一声去工作Q因为每个工人只会做一U工作,所以能?br>但我们不能要求所有h只能会做一U事情,q个要求很愚蠢。所以如果每个工Zq两U或者多U工作呢,
也就是我PA 有runPA() walkPA(){等ҎQ?PB有runPB() climbPB(){等。。?br>q个时候按照名单做事才是最好的办法?/p>

五:作者的?br>所以说模式中很多复杂的东西Q在现实中其实是很基本的东西Q多多代入代帮助理解模式?/p>

看完本文Q如果你对visitor模式有更多的兴趣Q想了解更多L如下几篇文章?br>1,静态分z,动态分z,多分z,单分z?--------------   visitor模式准备
2,讉K差异cd的集合类 ------------------------   visitor模式入门Q本文)
3,visitor模式理论及学术概?------------Q?----   visitor模式深入
4Q?a href="http://www.aygfsteel.com/dreamstone/archive/2006/12/18/88625.html">重蝲overloading和覆写overriding哪个更早执行--   visitor帮助?
虽然排列序?,2,3,4 但是我个人徏议的学习方式?,1,3,4因ؓq个序更方便一般h理解

 

 

 

 

 

 

 

 

 

 


 



dreamstone 2006-12-18 20:18 发表评论
]]>
控制反{的资料的集合及简单的概念Ҏhttp://www.aygfsteel.com/dreamstone/archive/2006/12/04/85428.htmldreamstonedreamstoneMon, 04 Dec 2006 09:57:00 GMThttp://www.aygfsteel.com/dreamstone/archive/2006/12/04/85428.htmlhttp://www.aygfsteel.com/dreamstone/comments/85428.htmlhttp://www.aygfsteel.com/dreamstone/archive/2006/12/04/85428.html#Feedback0http://www.aygfsteel.com/dreamstone/comments/commentRss/85428.htmlhttp://www.aygfsteel.com/dreamstone/services/trackbacks/85428.html控制反{Q?br>控制反{的资料的集合
参考一?br>标题Q向依赖关系宣战Q-Q-依赖倒置、控制反转和依赖注入辨析
url:http://www.contextfree.net/wangyw/source/dip_ioc.html
说明:详细分析了几个概늚不同
参考二?br>Spring guide
参考三?br>WebWork In Action IOC一?br>参考四?br>Martin fowler的文?br>http://www.aygfsteel.com/Files/dreamstone/DependencyInjection.rar
强烈大家看一下第一文章和W四,作者写的真的很?br>

Ҏ依赖倒置Q控制反转,依赖注入?
Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q?br>1Q依赖倒置Q?br>先说明什么是"正置"
正置是Q当你设计一些类库的时候,考虑到用L需要定义一些接口,用户的应用程序依赖这些接?/p>

Ҏ"正置"?倒置"
正置Q应用依赖接口,接口q库设计者定?br>优点Q类库实C自由度大Q实现容易?br>~点Q类库设计复杂,要预应用的需求,同时有可能不W合应用的需?/p>

倒置Q应用定义接口,cd设计者实现接口,按照接口实现cd
优点Q类库设计不再需要预,肯定W合应用需?br>~点Q类库有可能难以实现

单来_正置和倒置的区别在于,谁来制定标准。现实中因ؓ需求的定义是客户决定的Q所以倒置?br>适合E序的设计。从需求出发,到底层实现?/p>

使用目的Q便于应用按照需求设?br>x?接口的设?br>Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q?br>2Q控制反转:
正常的控Ӟ
 没有一定的控制程Q下一个流E由上一个流E决定,实现应用需要自己控制流E?br>控制反{  Q?br> 抽象出固定的程Q实现应用就是填充流E中的一个个炏V?br> 所有的框架都是Z控制反{的。Windows GUI开发也多是q样?br>目的Q高度抽象,设计框架
x点:程的设?br>Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q?br>3,依赖注入
原始的情况:
 应用自己new c,或者用工厂模式创建类
依赖注入Q?br> 容器创徏c,通过构造函敎ͼsetterҎQ接口等ҎQ运行时"注入"到应用中

实现Q?br>Spring        setterҎ
webwork IOC  实现接口的方?br>pico   构造函数的Ҏ

目的Q完全分d?br>x点:构造对?/p>

Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q?br>关系Q?br>"控制反{"?依赖倒置"的一U?"依赖注入"是在"控制反{"的基上,让容器来完成"注入"q程?br>Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q?br>最需要依赖注入的情况Q?br>"调用?和多?被调用?分别开发,分别打包分发Q实施者根据实际情况决定用哪?被调用?被?br>做成可配制的Q这U情冉|l常需要的。这个时候调用者内不能出现q样的代?
interface inter = new interfaceimplA();cM的语句。因Z用的可能是interfaceimplB
Z避免q样语句的出玎ͼ我们直接使用接口Q而对象的构造推q,让容器根据实施者的配制来构造,q注?br>正确的位|?/p>

 

 

 

 

 

 

 


 



dreamstone 2006-12-04 17:57 发表评论
]]>
依赖倒置、控制反转和依赖注入辨析http://www.aygfsteel.com/dreamstone/archive/2006/12/04/85400.htmldreamstonedreamstoneMon, 04 Dec 2006 08:50:00 GMThttp://www.aygfsteel.com/dreamstone/archive/2006/12/04/85400.htmlhttp://www.aygfsteel.com/dreamstone/comments/85400.htmlhttp://www.aygfsteel.com/dreamstone/archive/2006/12/04/85400.html#Feedback0http://www.aygfsteel.com/dreamstone/comments/commentRss/85400.htmlhttp://www.aygfsteel.com/dreamstone/services/trackbacks/85400.htmlhttp://www.contextfree.net/wangyw/source/dip_ioc.html

依赖倒置、控制反转和依赖注入辨析

 

  在《道法自然——面向对象实跉|南》一书中Q我们采用了一个对立统一的辩证关pL说明“模板Ҏ”模式—?“正向依赖 vs. 依赖倒置”Q参见:《道法自然》第15章[王咏武, 王咏?2004]Q。这U把“好莱?#8221;原则?“依赖倒置”原则{量齐观的看法其实来自于轻量U容器PicoContainer主页上的一D话Q?br>  “控制反{QInversion of ControlQ的一个著名的同义原则是由Robert C. Martin提出的依赖倒置原则QDependency Inversion PrincipleQ,它的另一个昵U是好莱坞原则(Hollywood PrincipleQ不要调用我Q让我来调用你)”[PicoContainer 2004]?br>  和网友们在CSDN Blog上进行了深入的讨论后Q我又把q些概念重新梳理了一下。我发现Q这几个概念虽然在思\和动机等宏观层面上是l一的,但在具体的应用层面还是存在着许多很微妙的差别。本文通过几个单的例子对依赖倒置QDependency Inversion PrincipleQ、控制反转(Inversion of ControlQ、依赖注入(Dependency InjectionQ等概念q行了更为深入的辨析Q也是对于《道法自然》正文内容的一个补充吧?

依赖和耦合QDependency and CouplingQ?nbsp;

  Rational Rose的帮助文档上是这样定?#8220;依赖”关系的:“依赖描述了两个模型元素之间的关系Q如果被依赖的模型元素发生变化就会媄响到另一个模型元素。典型的Q在cd上,依赖关系表明客户cȝ操作会调用服务器cȝ操作?#8221;
  Martin Fowler在《Reducing Coupling》一文中q样描述耦合Q?#8220;如果改变E序的一个模块要求另一个模块同时发生变化,p两个模块发生了耦合?#8221; [Fowler 2001]
  从上面的定义可以看出Q如果模块A调用模块B提供的方法,或访问模块B中的某些数据成员Q当Ӟ在面向对象开发中一般不提倡这样做Q,我们p为模块A依赖于模块BQ模块A和模块B之间发生了耦合?br>  那么Q依赖对于我们来说究竟是好事q是坏事呢?
  ׃人类的理解力有限Q大多数人难以理解和把握q于复杂的系l。把软gpȝ划分成多个模块,可以有效控制模块的复杂度Q每个模块都易于理解和l护。但在这U情况下Q模块之间就必须以某U方式交换信息,也就是必然要发生某种耦合关系。如果某个模块和其它模块没有M兌Q哪怕只是潜在的或隐含的依赖关系Q,我们几乎可以断定,该模块不属于此Y件系l,应该从系l中剔除。如果所有模块之间都没有M耦合关系Q其l果必然是:整个软g不过是多个互不相q的pȝ的简单堆U,Ҏ个系l而言Q所有功能还是要在一个模块中实现Q这{于没有做Q何模块的分解?br>  因此Q模块之间必定会有这h那样的依赖关p,永远不要qL消除所有依赖。但是,q强的耦合关系Q如一个模块的变化会造成一个或多个其他模块也同时发生变化的依赖关系Q会对Y件系l的质量造成很大的危実뀂特别是当需求发生变化时Q代码的l护成本非帔R。所以,我们必须惛_办法来控制和消解不必要的耦合Q特别是那种会导致其它模块发生不可控变化的依赖关pR依赖倒置、控制反转、依赖注入等原则是Z在和依赖关系q行艰苦卓绝的斗争过E中不断产生和发展v来的?br>

接口和实现分?nbsp;

  把接口和实现分开是h们试图控制依赖关pȝW一个尝试,?1是Robert C. Martin在《依赖倒置》[Martin 1996]一文中所丄W一个例子。其中,ReadKeyboard()和WritePrinter()为函数库中的两个函数Q应用程序@环调用这两个函数Q以便把用户键入的字W拷贝到打印出?br>

  Z使应用程序不依赖于函数库的具体实玎ͼC语言把函数的定义写在了一个分ȝ头文Ӟ函数?hQ中。这U做法的好处是:虽然应用E序要调用函数库、依赖于函数库,但是Q当我们要改变函数库的实现时Q只要重写函数的实现代码Q应用程序无需发生变化。例如,改变函数?c文gQ把WritePrinter()函数重新实现成向盘中输出,q时只要应用程序和函数库重新链接,E序的功能就会发生相应的变化?br>  上面的函数库也可以采用C++语言来实现。我们通常把这U用面向对象技术实现的Qؓ应用E序提供多个支持cȝ模块UCؓ “cd”Q如?2所C。这U通过分离接口和实现来消解应用E序和类库之间依赖关pȝ做法h以下特点Q?br>  1. 应用E序调用cdQ依赖于cd?br>  2. 接口和实现的分离从一定的E度上消解了q个依赖关系Q具体实现可以在~译期间发生变化。但是,q种消解Ҏ的作用非常有限。比如说Q一个系l中无法容纳多个实现Q不同的实现不能动态发生变化,用WritePrinter函数名来实现向磁盘中输出的功能也昑־非常古怪,{等?br>  3. cd可以单独重用。但是应用程序不能脱ȝ库而重用,除非提供一个实C相同接口的类库?

 

依赖倒置QDependency Inversion PrincipleQ?nbsp;

  可以看出Q上面讨论的单分L口的Ҏ对于依赖关系的消解作用非常有限。Java语言提供了纯_的接口c,q种接口cM包括M实现代码Q可以更好地隔离两个模块。C++语言中虽然没有定义这U纯_的接口c,但所有成员函数都是纯虚函数的抽象cM不包含Q何实C码,可以起到cM于Java接口cȝ作用。ؓ了和上一节中提到的简单接口相区别Q本文后面将把基于Java 接口cLC++抽象cd义的接UCؓ抽象接口。依赖倒置原则是建立在抽象接口的基础上的。Robert Martinq样描述依赖倒置原则[Martin 1996]Q?br>  A. 上层模块不应该依赖于下层模块Q它们共同依赖于一个抽象?br>  B. 抽象不能依赖于具象,兯依赖于抽象?br>  其含义是Qؓ了消解两个模块间的依赖关p,应该在两个模块之间定义一个抽象接口,上层模块调用抽象接口定义的函敎ͼ下层模块实现该接口。如?3所C,对于上一节的例子Q我们可以定义两个抽象类Reader和Writer作ؓ抽象接口Q其中的Read()和Write()函数都是U虚函数Q而具体的KeyboardReader和PrinterWritercdCq些接口。当应用E序调用Read()和Write()函数Ӟ׃多态性机制的作用Q实际调用的是具体的KeyboardReader和PrinterWritercM的实现。因此,抽象接口隔离了应用程序和cd中的具体c,使它们之间没有直接的耦合关系Q可以独立地扩展或重用。例如,我们可以用类似的Ҏ实现FileReader或DiskWriterc,应用E序既可以根据需要选择从键盘或文g输入Q也可以选择向打印机或磁盘输出,甚至同时完成多种不同的输入、输ZQ务。由此可以ȝ出,q种通过抽象接口消解应用E序和类库之间依赖关pȝ做法h以下特点Q?br>  1. 应用E序调用cd的抽象接口,依赖于类库的抽象接口Q具体的实现cL生自cd的抽象接口,也依赖于cd的抽象接口?br>  2. 应用E序和具体的cd实现完全独立Q相互之间没有直接的依赖关系Q只要保持接口类的稳定,应用E序和类库的具体实现都可以独立地发生变化?br>  3. cd完全可以独立重用Q应用程序可以和M一个实C相同抽象接口的类库协同工作?

  一般情况下Q由于类库的设计者ƈ不知道应用程序会如何使用cdQ抽象接口大多由cd设计者根据自p想的典型使用模式ȝ出来Qƈ保留一定的灉|度,以提供给应用E序的开发者用?br>  但还有另外一U情c图 4是Martin Fowler在《Reducing Coupling》一文中使用的一个例子[Fowler 2001]。其中,Domain包要使用数据库包Q即Domain包依赖于数据库包。ؓ了隔Domain包和数据库包Q可以引入一个Mapper包。如果在特定的情况下Q我们希望Domain包能够被多次重用Q而Mapper包可以随时变化,那么Q我们就必须防止Domain包过分地依赖于Mapper包。这Ӟ可以?Domain包的设计者ȝ己需要的抽象接口Q如StoreQ,而由Mapper包的设计者来实现该抽象接口。这样一来,无论是在接口层面Q还是在实现层面Q依赖关p都完全颠倒过来了?

 

控制反{QInversion of ControlQ?nbsp;

  前面描述的是应用E序和类库之间的依赖关系。如果我们开发的不是cdQ而是框架pȝQ依赖关pd会更强烈一炏V那么,该如何消解框架和应用E序之间的依赖关pdQ?br>  《道法自然》第5章描qC框架和类库之间的区别Q?br>  “框架和类库最重要的区别是Q框架是一?#8216;半成?#8217;的应用程序,而类库只包含一pd可被应用E序调用的类?br>  “cdl用h供了一pd可复用的c,q些cȝ设计都符合面向对象原则和模式。用户用时Q可以创些类的实例,或从q些cMl承出新的派生类Q然后调用类中相应的功能。在q一q程中,cdL被动地响应用L调用h?br>  “框架则会为某一特定目的实现一个基本的、可执行的架构。框架中已经包含了应用程序从启动到运行的主要程Q流E中那些无法预先定的步骤留l用h实现。程序运行时Q框架系l自动调用用户实现的功能lg。这Ӟ框架pȝ的行为是d的?br>  “我们可以_cd是死的,而框架是zȝ。应用程序通过调用cd来完成特定的功能Q而框架则通过调用应用E序来实现整个操作流E。框架是控制倒置原则的完体现?#8221;
  框架pȝ的一个最好的例子是囑Ş用户界面QGUIQ系l。一个简单的Q用面向过E的设计Ҏ开发的GUIpȝ如图 5所C?

  从图 5中可以看出,应用E序调用GUI框架中的CreateWindow()函数来创建窗口,在这里,我们可以说应用程序依赖于GUI框架。但GUI框架q不了解该窗口接收到H口消息后应该如何处理,q一点只有应用程序最为清楚。因此,当GUI框架需要发送窗口消息时Q又必须调用应用E序定义的某个特定的H口函数Q如上图中的MyWindowProcQ。这ӞGUI框架又必M赖于应用E序。这是一个典型的双向依赖关系。这U双向依赖关pL一个非怸重的~陷Q由于GUI框架调用了应用程序中的某个特定函敎ͼMyWindowProcQ, GUI框架Ҏ无法独立存在Q换一个新的应用程序,GUI框架多半p做相应的修改。因此,如何消解框架pȝ对应用程序的依赖关系是实现框架系l的关键?br>  q只有面向对象的方法才能解册一问题。WIN32 API早就为我们提供了在面向过E的设计思\下解决类似问题的范例。类WIN32 的架构模型如?6所C?
  在图 6中,应用E序调用CreateWindow()函数Ӟ要传递一个消息处理函数的指针lGUI框架Q对WIN32而言Q我们在注册H口cL传递这一指针Q,GUI框架把该指针记录在窗口信息结构中。需要发送窗口消息时QGUI框架通过该指针调用窗口函数。和?5 相比QGUI框架仍然需要调用应用程序,但这一调用从一个硬~码的函数调用变成了一个由应用E序事先注册被调用对象的动态调用。图 6用一条虚U表CU动态调用。可以看出,q种动态的调用关系有一个非常大的好处:当应用程序发生变化时Q它可以自行改变框架pȝ的调用目标,GUI框架无需随之发生变化。现在,我们可以_虽然q存在着从GUI框架到应用程序的调用关系Q但GUI框架已经完全不再依赖于应用程序了。这U动态调用机刉常也被UCؓ“回调函数”?br>  在面向对象领域,“回调函数”的替代物是“模板Ҏ模式”Q也是“好莱坞原则(不要调用我们Q让我们调用你)”。GUI框架的一个面向对象的实现如图 7所C?
  ?7中,“GUI框架抽象接口”是GUI框架pȝ提供l应用程序用的接口。抽象出该接口的动机是根?#8220;依赖倒置”的原则,消解从应用程序到GUI框架之间的直接依赖关p,以得GUI框架实现的变化对应用E序的媄响最化。Window接口cd?#8220;模板Ҏ模式”的核心。应用程序调用CreateWindow()函数ӞGUI框架会把该窗口的引用保存在窗口链表中。需要发送窗口消息时QGUI框架p用窗口对象的SendMessage()函数Q该函数是实现在WindowcM的非虚成员函数。SendMessage()函数又调用WindowProc()虚函敎ͼq里实际执行的是应用E序MyWindowcM实现的WindowProc()函数。在?7中,我们已经看不CGUI框架到应用程序之间的直接依赖关系了。因此,模板Ҏ模式完全实现了回调函数的动态调用机Ӟ消解了从框架到应用程序之间的依赖关系?br>  从上面的分析可以看出Q模板方法模式是框架pȝ的基QQ何框架系l都M开模板Ҏ模式。Martin Fowler也说 [Folwer 2004]Q?#8220;几位轻量U容器的作者曾骄傲地对我说Q这些容器非常有用,因ؓ它们实现?#8216;控制反{’。这L说辞让我深感qhQ控制反转是框架所共有的特征,如果仅仅因ؓ使用了控制反转就认ؓq些轻量U容器与众不同,好像在?#8216;我的轿R是与众不同的Q因为它有四个轮?#8217;。问题的关键在于Q它们反转了哪方面的控制Q我W一ơ接触到的控制反转针对的是用L面的L权。早期的用户界面是完全由应用E序来控制的Q你预先设计一pd命oQ例?#8216;输入姓名’?#8216;输入地址’{,应用E序逐条输出提示信息Qƈ取回用户的响应。而在囑Ş用户界面环境下,UI 框架负责执行一个主循环Q你的应用程序只需为屏q的各个区域提供事g处理函数卛_。在q里Q程序的L权发生了反{Q从应用E序Ud了框架?#8221;
  实Q对比图 3和图 7可以看出Q用普通类库时Q程序的d@环位于应用程序中Q而用框架系l的应用E序不再包括一个主循环Q只是实现某些框架定义的接口Q框架系l负责实现系l运行的d@环,q在必要的时候通过模板Ҏ模式调用应用E序?br>  也就是说Q虽?#8220;依赖倒置”?#8220;控制反{”在设计层面上都是消解模块耦合的有效方法,也都是试图o具体的、易变的模块依赖于抽象的、稳定的模块的基本原则,但二者在使用语境和关注点上存在差异:“依赖倒置”的是对于传统的、源于面向过E设计思想的层ơ概늚“倒置”Q?#8220;控制反{”的是对程序流E控制权的反转;“依赖倒置”的用范围更为宽泛,既可用于对程序流E的描述Q如程的主从和层次关系Q,也可用于描述其他拥有概念层次的设计模型(如服务组件与客户lg、核心模块与外围应用{)Q?#8220;控制反{”则仅适用于描q流E控制权的场合(如算法流E或业务程的控制权Q?br>  从某U意义上_我们也可以把“控制反{”看作?#8220;依赖倒置”的一个特例。例如,用模板方法模式实现的“控制反{”机制其实是在框架系l和应用E序之间抽象Z一个描q所有算法步骤原型的接口c,框架pȝ依赖于该接口cd义ƈ实现E序程Q应用程序依赖于该接口类提供具体法步骤的实玎ͼ应用E序Ҏ架系l的依赖?#8220;倒置”Z者对抽象接口的依赖?br>  d说来Q应用程序和框架pȝ之间的依赖关pL以下特点Q?br>  1. 应用E序和框架系l之间实际上是双向调用,双向依赖的关pR?br>  2. 依赖倒置原则可以减弱应用E序到框架之间的依赖关系?br>  3. “控制反{”及具体的模板Ҏ模式可以消解框架到应用程序之间的依赖关系Q这也是所有框架系l的基础?br>  4. 框架pȝ可以独立重用?

 

依赖注入QDependency InjectionQ?nbsp;

  在前面的例子里,我们通过“依赖倒置”原则Q最大限度地减弱了应用程序Copycdcd提供的服务ReadQWrite之间的依赖关pR但是,如果需要把Copy()函数也实现在cd中,又会发生什么情况呢Q假讑֜cd中实C?#8220;服务c?#8221;Q?#8220;服务c?#8221;提供Copy()Ҏ供应用程序用。应用程序用时Q首先创?#8220;服务c?#8221;的实例,调用其中的Copy()函数?#8220;服务c?#8221;的实例初始化时会创徏KeyboardReader 和PrinterWritercȝ实例对象。如?8所C?

  从图 8中可以看出,虽然Reader和Writer接口隔离?#8220;服务c?#8221;和具体的Reader和Writerc,使它们之间的耦合降到了最。但?“服务c?#8221;创徏具体的Reader和Writer对象Ӟ“服务c?#8221;q是和具体的Reader和Writer对象发生了依赖关pZ—图 8中用蓝色的虚U描qCq种依赖关系?br>  在这U情况下Q如何实例化具体的Reader和Writerc,同时又尽量减服务类对它们的依赖Q就是一个非常关键的问题了。如果服务类位于应用E序中,q一依赖关系Ҏ们造成的媄响还不算大。但?#8220;服务c?#8221;位于需要独立发布的cd中,它的代码׃能随着应用E序的变化而改变了。这也意味着Q如?#8220;服务c?#8221;q度依赖于具体的Reader和Writerc,用户无法自行添加新的Reader和Writer 的实C?br>  解决q一问题的方法是“依赖注入”Q即切断“服务c?#8221;到具体的Reader和WritercM间的依赖关系Q而由应用E序来注入这一依赖关系。如?9所C?
  在图 9中,“服务c?#8221;q不负责创徏具体的Reader和Writercȝ实例对象Q而是由应用程序来创徏。应用程序创?#8220;服务c?#8221;的实例对象时Q把具体的Reader和Write对象的引用注?#8220;服务c?#8221;内部。这P“服务c?#8221;中的代码只和抽象接口相关的了。具体实C码发生变化时Q?#8220;服务c?#8221;不会发生M变化。添加新的实现时Q也只需要改变应用程序的代码Q就可以定义q用新的Reader和Writerc,q种依赖注入方式通常也被UCؓ“构造器注入”?br>  如果专门为CopycL象出一个注入接口,应用E序通过接口注入依赖关系Q这U注入方式通常被称?#8220;接口注入”。如果ؓCopycL供一个设值函敎ͼ应用E序通过调用讑ր函数来注入依赖关系Q这U依赖注入的Ҏ被称?#8220;讑ր注?#8221;。具体的“接口注入”?#8220;讑ր注?#8221;请参考[Martin 2004]?br>  PicoContainer和Spring轻量U容器框枉提供了相应的机制来帮助用户实现各U不同的“依赖注入”。ƈ且,通过不同的方式,他们也都支持在XML文g中定义依赖关p,然后由应用程序调用框架来注入依赖关系Q当依赖关系需要发生变化时Q只要修改相应的 XML文g卛_?br>  因此Q依赖注入的核心思想是:
  1. 抽象接口隔离了用者和实现之间的依赖关p,但创建具体实现类的实例对象仍会造成对于具体实现的依赖?br>  2. 采用依赖注入可以消除q种创徏依赖性。用依赖注入后Q某些类完全是基于抽象接口编写而成的,q可以最大限度地适应需求的变化?

 

l论 

  分离接口和实现是Z有效地控制依赖关pȝ最初尝试,而纯_的抽象接口更好地隔M怺依赖的两个模块,“依赖倒置”?“控制反{”原则从不同的角度描述了利用抽象接口消解耦合的动机,GoF的设计模式正是这一动机的完体现。具体类的创E是另一U常见的依赖关系Q?#8220;依赖注入”模式可以把具体类的创E集中到合适的位置Q这一动机和GoF的创建型模式有相g处?br>  q些原则Ҏ们的实践有很好的指导作用Q但它们不是圣经Q在不同的场合可能会有不同的变化Q我们应该在开发过E中Ҏ需求变化的可能性灵z运用?

参考文?nbsp;

[PicoContainer 2004]  http://www.picocontainer.org/Inversion+of+Control
[Martin 1996]  The Dependency Inversion Principle, Robert C. Martin, C++ Report, May, 1996, http://www.objectmentor.com/resources/articles/dip.pdf
[Fowler 2001]  Martin Fowler: Reducing Coupling. IEEE Software 18(4): 102-104 (2001) http://www.martinfowler.com/ieeeSoftware/coupling.pdf
[Folwer 2004]  Inversion of Control Containers and the Dependency Injection pattern http://martinfowler.com/articles/injection.html
[透明2004]  透明QInversion of Control Containers and the Dependency Injection pattern 的译?a >http://gigix.blogdriver.com/gigix/inc/DependencyInjection.pdf
[王咏? 王咏?2004]  王咏? 王咏? 道法自然—面向对象实跉|? 电子工业出版C? 2004



dreamstone 2006-12-04 16:50 发表评论
]]>
Java 中的模式 --- 单的状态模?/title><link>http://www.aygfsteel.com/dreamstone/archive/2006/12/03/85173.html</link><dc:creator>dreamstone</dc:creator><author>dreamstone</author><pubDate>Sun, 03 Dec 2006 03:51:00 GMT</pubDate><guid>http://www.aygfsteel.com/dreamstone/archive/2006/12/03/85173.html</guid><wfw:comment>http://www.aygfsteel.com/dreamstone/comments/85173.html</wfw:comment><comments>http://www.aygfsteel.com/dreamstone/archive/2006/12/03/85173.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.aygfsteel.com/dreamstone/comments/commentRss/85173.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/dreamstone/services/trackbacks/85173.html</trackback:ping><description><![CDATA[状态模式很单,无论是理解,q是实现Q都很简单?br>一、定义:<br>1Q状态模式允怸?对象"在其内部状态改变的时候改变其行ؓ?br>2Q状态模式的角色Q?br>抽象状态,具体状态,环境(context)角色<br>状态模式的角色比较单,不用解释了,看名字就能了解?br>二、状态模式的实现<br>1,单实?br> <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 id=Codehighlighter1_20_167_Open_Image onclick="this.style.display='none'; Codehighlighter1_20_167_Open_Text.style.display='none'; Codehighlighter1_20_167_Closed_Image.style.display='inline'; Codehighlighter1_20_167_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_20_167_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_20_167_Closed_Text.style.display='none'; Codehighlighter1_20_167_Open_Image.style.display='inline'; Codehighlighter1_20_167_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ContractedBlock.gif" align=top><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Context</span><span id=Codehighlighter1_20_167_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.aygfsteel.com/Images/dot.gif"></span><span id=Codehighlighter1_20_167_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080"> 2</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>    </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> State state;<br></span><span style="COLOR: #008080"> 3</span><span style="COLOR: #000000"><img id=Codehighlighter1_74_104_Open_Image onclick="this.style.display='none'; Codehighlighter1_74_104_Open_Text.style.display='none'; Codehighlighter1_74_104_Closed_Image.style.display='inline'; Codehighlighter1_74_104_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_74_104_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_74_104_Closed_Text.style.display='none'; Codehighlighter1_74_104_Open_Image.style.display='inline'; Codehighlighter1_74_104_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> sampleOperation()</span><span id=Codehighlighter1_74_104_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.aygfsteel.com/Images/dot.gif"></span><span id=Codehighlighter1_74_104_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080"> 4</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>        state.sampleOperation();<br></span><span style="COLOR: #008080"> 5</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>    }</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 6</span><span style="COLOR: #000000"><img id=Codehighlighter1_140_165_Open_Image onclick="this.style.display='none'; Codehighlighter1_140_165_Open_Text.style.display='none'; Codehighlighter1_140_165_Closed_Image.style.display='inline'; Codehighlighter1_140_165_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_140_165_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_140_165_Closed_Text.style.display='none'; Codehighlighter1_140_165_Open_Image.style.display='inline'; Codehighlighter1_140_165_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> setState(State state)</span><span id=Codehighlighter1_140_165_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.aygfsteel.com/Images/dot.gif"></span><span id=Codehighlighter1_140_165_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080"> 7</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>        </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.state </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> state;<br></span><span style="COLOR: #008080"> 8</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>    }</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 9</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">10</span><span style="COLOR: #000000"><img id=Codehighlighter1_191_218_Open_Image onclick="this.style.display='none'; Codehighlighter1_191_218_Open_Text.style.display='none'; Codehighlighter1_191_218_Closed_Image.style.display='inline'; Codehighlighter1_191_218_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_191_218_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_191_218_Closed_Text.style.display='none'; Codehighlighter1_191_218_Open_Image.style.display='inline'; Codehighlighter1_191_218_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">interface</span><span style="COLOR: #000000"> State</span><span id=Codehighlighter1_191_218_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.aygfsteel.com/Images/dot.gif"></span><span id=Codehighlighter1_191_218_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">11</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>    </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> sampleOperation();<br></span><span style="COLOR: #008080">12</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">13</span><span style="COLOR: #000000"><img id=Codehighlighter1_264_298_Open_Image onclick="this.style.display='none'; Codehighlighter1_264_298_Open_Text.style.display='none'; Codehighlighter1_264_298_Closed_Image.style.display='inline'; Codehighlighter1_264_298_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_264_298_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_264_298_Closed_Text.style.display='none'; Codehighlighter1_264_298_Open_Image.style.display='inline'; Codehighlighter1_264_298_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> ConcreteState </span><span style="COLOR: #0000ff">implements</span><span style="COLOR: #000000"> State </span><span id=Codehighlighter1_264_298_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.aygfsteel.com/Images/dot.gif"></span><span id=Codehighlighter1_264_298_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">14</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align=top>    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> sampleOperation();<br></span><span style="COLOR: #008080">15</span><span style="COLOR: #000000"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div> 2、状态模式的l典实现<br>Tcp是状态模式的一个经典实玎ͼTcpConnect 他有三个状态,TcpEstablished  TcpListen  TcpClosed<br>TcpConnect的功能会跟着状态的改变而改变。或是Established,或是Listen,或是Closed<br>三、状态模式的与策略模式,看到上边的部分,很容易让人想到策略模式,q两个模式有什么区别呢Q如何?br>{略模式Q?br>1Q当一个环境角色选择了一个具体的{略Q那么在整个环境cȝ生命周期都不会改?br>2Q策略模式的环境自己选择一个具体的{略<br>3Q策略模式ƈ不明告诉客L它所选择的具体策略是什么,对客h黑箱?br>状态模式:<br>1Q在整个环境cȝ生命周期中会有明昄状态改变?br>2Q状态模式是被外在原因放入一个策?br>3,状态模式明昄告诉客户端当前的状态,对客h白箱? <img src ="http://www.aygfsteel.com/dreamstone/aggbug/85173.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/dreamstone/" target="_blank">dreamstone</a> 2006-12-03 11:51 <a href="http://www.aygfsteel.com/dreamstone/archive/2006/12/03/85173.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java中的模式 --- 双重接口的实?备忘录模?/title><link>http://www.aygfsteel.com/dreamstone/archive/2006/12/03/85159.html</link><dc:creator>dreamstone</dc:creator><author>dreamstone</author><pubDate>Sun, 03 Dec 2006 02:40:00 GMT</pubDate><guid>http://www.aygfsteel.com/dreamstone/archive/2006/12/03/85159.html</guid><wfw:comment>http://www.aygfsteel.com/dreamstone/comments/85159.html</wfw:comment><comments>http://www.aygfsteel.com/dreamstone/archive/2006/12/03/85159.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.aygfsteel.com/dreamstone/comments/commentRss/85159.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/dreamstone/services/trackbacks/85159.html</trackback:ping><description><![CDATA[     摘要: 一、定义:备忘?memento)模式又叫快照(snapshot)模式或者token模式Q主要功能:备忘录模式是用一个对象来存储另外一个对象的内部状态的快照Q实现备忘录模式的关键点是在不破坏封装的情况下,一个对象的状态捕捉住Qƈ外部化,存储hQ从而可以在合适的时候,把这个对象还原。说明:备忘录模式适模式中比较好理解的一个,q里׃举例子,但是备忘录模式是模式中实现比较难Q或者说实现比较巧的Q这...  <a href='http://www.aygfsteel.com/dreamstone/archive/2006/12/03/85159.html'>阅读全文</a><img src ="http://www.aygfsteel.com/dreamstone/aggbug/85159.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/dreamstone/" target="_blank">dreamstone</a> 2006-12-03 10:40 <a href="http://www.aygfsteel.com/dreamstone/archive/2006/12/03/85159.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java中的模式 --- 命o模式?实现,功能,使用场合)及如何配合其它模式用命令模?/title><link>http://www.aygfsteel.com/dreamstone/archive/2006/11/27/83690.html</link><dc:creator>dreamstone</dc:creator><author>dreamstone</author><pubDate>Sun, 26 Nov 2006 18:31:00 GMT</pubDate><guid>http://www.aygfsteel.com/dreamstone/archive/2006/11/27/83690.html</guid><wfw:comment>http://www.aygfsteel.com/dreamstone/comments/83690.html</wfw:comment><comments>http://www.aygfsteel.com/dreamstone/archive/2006/11/27/83690.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.aygfsteel.com/dreamstone/comments/commentRss/83690.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/dreamstone/services/trackbacks/83690.html</trackback:ping><description><![CDATA[     摘要: 一,命o模式的实?命o模式里边一般都有以下几个角Ԍ客户端,h者,命o接口Q命令实玎ͼ接受?下边是简单命令模式的实现代码实现Q? 1public class Client{ 2    public static void main(String[] args){ ...  <a href='http://www.aygfsteel.com/dreamstone/archive/2006/11/27/83690.html'>阅读全文</a><img src ="http://www.aygfsteel.com/dreamstone/aggbug/83690.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/dreamstone/" target="_blank">dreamstone</a> 2006-11-27 02:31 <a href="http://www.aygfsteel.com/dreamstone/archive/2006/11/27/83690.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring的Aop的实现方?/title><link>http://www.aygfsteel.com/dreamstone/archive/2006/11/14/81007.html</link><dc:creator>dreamstone</dc:creator><author>dreamstone</author><pubDate>Mon, 13 Nov 2006 16:51:00 GMT</pubDate><guid>http://www.aygfsteel.com/dreamstone/archive/2006/11/14/81007.html</guid><wfw:comment>http://www.aygfsteel.com/dreamstone/comments/81007.html</wfw:comment><comments>http://www.aygfsteel.com/dreamstone/archive/2006/11/14/81007.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.aygfsteel.com/dreamstone/comments/commentRss/81007.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/dreamstone/services/trackbacks/81007.html</trackback:ping><description><![CDATA[     摘要: 最q看了一下Spring的Aop和Java的动态代理,下边利用个小例子Q简单的表述一下。Spring中的Aop实现一Q什么是Aop呢:AOP是Aspect Oriented Programming的羃写,意思是面向斚w~程。AOP实际是GoF设计模式的gl,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这U目标的一U实现。二,Spring中的Aopspring中的aopq用?..  <a href='http://www.aygfsteel.com/dreamstone/archive/2006/11/14/81007.html'>阅读全文</a><img src ="http://www.aygfsteel.com/dreamstone/aggbug/81007.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/dreamstone/" target="_blank">dreamstone</a> 2006-11-14 00:51 <a href="http://www.aygfsteel.com/dreamstone/archive/2006/11/14/81007.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java中的模式 --工厂模式http://www.aygfsteel.com/dreamstone/archive/2006/11/07/79608.htmldreamstonedreamstoneTue, 07 Nov 2006 07:02:00 GMThttp://www.aygfsteel.com/dreamstone/archive/2006/11/07/79608.htmlhttp://www.aygfsteel.com/dreamstone/comments/79608.htmlhttp://www.aygfsteel.com/dreamstone/archive/2006/11/07/79608.html#Feedback3http://www.aygfsteel.com/dreamstone/comments/commentRss/79608.htmlhttp://www.aygfsteel.com/dreamstone/services/trackbacks/79608.html阅读全文

dreamstone 2006-11-07 15:02 发表评论
]]>
Java中的模式 --单?Q部分翻?double-checked locking breakQ?/title><link>http://www.aygfsteel.com/dreamstone/archive/2006/11/04/79026.html</link><dc:creator>dreamstone</dc:creator><author>dreamstone</author><pubDate>Sat, 04 Nov 2006 01:26:00 GMT</pubDate><guid>http://www.aygfsteel.com/dreamstone/archive/2006/11/04/79026.html</guid><wfw:comment>http://www.aygfsteel.com/dreamstone/comments/79026.html</wfw:comment><comments>http://www.aygfsteel.com/dreamstone/archive/2006/11/04/79026.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.aygfsteel.com/dreamstone/comments/commentRss/79026.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/dreamstone/services/trackbacks/79026.html</trackback:ping><description><![CDATA[<p>单态定?<br>Singleton模式主要作用是保证在Java应用E序中,一个类Class只有一个实例存在?/p> <p>Singleton模式׃ؓ我们提供了这样实现的可能。用Singleton的好处还在于可以节省内存Q因为它限制?br>实例的个敎ͼ有利于Java垃圾回收Qgarbage collectionQ?/p> <p>使用Singleton注意事项Q?br>有时在某些情况下Q用Singletonq不能达到Singleton的目的,如有多个Singleton对象同时被不同的c?br>装入器装载;在EJBq样的分布式pȝ中用也要注意这U情况,因ؓEJB是跨服务器,跨JVM?/p> <p>单态模式的演化Q?br>单态模式是个简单的模式Q但是这个简单的模式也有很多复杂的东ѝ?br></p> <p>Q注意:在这里补充一下,现在单态模式其实有一个写法是不错的见q里Q?a href="http://www.aygfsteel.com/dreamstone/archive/2007/02/27/101000.html">http://www.aygfsteel.com/dreamstone/archive/2007/02/27/101000.html</a>Q但q是看完q篇文章Q因释的事情是不一LQ这里说的是Z么double-checked不能使用.Q?br>一Q首先最单的单态模式,单态模?<br>import java.util.*;<br>class Singleton<br>{<br>  private static Singleton instance;<br>  private Vector v;<br>  private boolean inUse;</p> <p>  private Singleton()<br>  {<br>    v = new Vector();<br>    v.addElement(new Object());<br>    inUse = true;<br>  }</p> <p>  public static Singleton getInstance()<br>  {<br>    if (instance == null)          //1<br>      instance = new Singleton();  //2<br>    return instance;               //3<br>  }<br>}<br>q个单态模式是不安全的Qؓ什么说?Q因为没考虑多线E,如下情况<br>Thread 1 调用getInstance() ҎQƈ且判断instance是nullQ然後进入if模块Q?br>在实例化instance之前Q?br>Thread 2抢占了Thread 1的cpu<br>Thread 2 调用getInstance() ҎQƈ且判断instance是nullQ然後进入if模块Q?br>Thread 2 实例化instance 完成Q返?br>Thread 1 再次实例化instance<br>q个单态已l不在是单?/p> <p>二,Z解决刚才的问题:单态模?<br>public static synchronized Singleton getInstance()<br>{<br>  if (instance == null)          //1<br>    instance = new Singleton();  //2<br>  return instance;               //3<br>}<br>采用同步来解冻Iq种方式解决了问题,但是仔细分析<br>正常的情况下只有W一ơ时候,q入对象的实例化Q须要同步,<br>其它时候都是直接返回已l实例化好的instance不须要同步,<br>大家都知到在一个多U程的程序中Q如果同步的消耗是很大的,很容易造成瓉</p> <p>三,Z解决上边的问题:单态模?Q加入同?br>public static Singleton getInstance()<br>{<br>  if (instance == null)<br>  {<br>    synchronized(Singleton.class) {<br>      instance = new Singleton();<br>    }<br>  }<br>  return instance;<br>}<br>同步Ҏ块同步,而不使用函数同步Q但是仔l分析,<br>又回C模式一的状态,再多U程的时候根本没有解决问?/p> <p>四,Z对应上边的问题:单态模?Q也是很多人采用的Double-checked locking<br>public static Singleton getInstance()<br>{<br>  if (instance == null)<br>  {<br>    synchronized(Singleton.class) {  //1<br>      if (instance == null)          //2<br>        instance = new Singleton();  //3<br>    }<br>  }<br>  return instance;<br>}<br>q样Q模式一中提到的问题解决了。不会出现多ơ实例化的现?br>当第一ơ进入的时候,保正实例化时候的单?在实例化后,多线E访问的时候直接返回,不须要进入同步模块,<br>既实C单态,又没有损失性能。表面上看我们的问题解决了,但是再仔l分析:<br>我们来假象这中情况:<br>Thread 1 :q入?/3位置Q执行new Singleton()Q但是在构造函数刚刚开始的时候被Thread2抢占cpu<br>Thread 2 :q入getInstance()Q判断instance不等于null,q回instanceQ?br>Qinstance已经被newQ已l分配了内存I间,但是没有初始化数?<br>Thread 2 :利用q回的instance做某些操做,p|或者异?br>Thread 1 :取得cpu初始化完?br>q程中可能有多个U程取到了没有完成的实例Qƈ用这个实例作出某些操做?br>Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q?br>出现以上的问题是因ؓ<br>mem = allocate();             //分配内存<br>instance = mem;               //标记instance非空<br>                              //未执行构造函?thread 2从这里进?br>ctorSingleton(instance);      //执行构造函?br>                              //q回instance<br>Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-                              </p> <p>五,证明上边的假x可能发生的,字节码是用来分析问题的最好的工具Q可以利用它来分?br>下边一D늨序:Qؓ了分析方便,所以渐了内容Q?br>字节码的使用Ҏ见这里,<a href="http://www.aygfsteel.com/dreamstone/archive/2006/11/04/79058.html">利用字节码分析问?/a><br>class Singleton<br>{<br>  private static Singleton instance;<br>  private boolean inUse;<br>  private int val;  </p> <p>  private Singleton()<br>  {<br>    inUse = true;<br>    val = 5;<br>  }<br>  public static Singleton getInstance()<br>  {<br>    if (instance == null)<br>      instance = new Singleton();<br>    return instance;<br>  }<br>}<br>得到的字节码                            <br>;asm code generated for getInstance<br>054D20B0   mov         eax,[049388C8]      ;load instance ref<br>054D20B5   test        eax,eax             ;test for null<br>054D20B7   jne         054D20D7<br>054D20B9   mov         eax,14C0988h<br>054D20BE   call        503EF8F0            ;allocate memory<br>054D20C3   mov         [049388C8],eax      ;store pointer in <br>                                           ;instance ref. instance  <br>                                           ;non-null and ctor<br>                                           ;has not run<br>054D20C8   mov         ecx,dword ptr [eax] <br>054D20CA   mov         dword ptr [ecx],1   ;inline ctor - inUse=true;<br>054D20D0   mov         dword ptr [ecx+4],5 ;inline ctor - val=5;<br>054D20D7   mov         ebx,dword ptr ds:[49388C8h]<br>054D20DD   jmp         054D20B0</p> <p>上边的字节码证明Q猜x有可能实现的</p> <p>六:好了Q上边证明Double-checked locking可能出现取出错误数据的情况,那么我们q是可以解决?br>public static Singleton getInstance()<br>{<br>  if (instance == null)<br>  {<br>    synchronized(Singleton.class) {      //1<br>      Singleton inst = instance;         //2<br>      if (inst == null)<br>      {<br>        synchronized(Singleton.class) {  //3<br>          inst = new Singleton();        //4<br>        }<br>        instance = inst;                 //5<br>      }<br>    }<br>  }<br>  return instance;<br>}<br>利用Double-checked locking 两次同步Q中间变?解决上边的问题?br>Q下边这D话我只能简单的理解Q翻译过来不好,所以保留原文,list 7是上边的代码Qlist 8是下边的<br>The code in Listing 7 doesn't work because of the current definition of the memory model.<br> The Java Language Specification (JLS) demands that code within a synchronized block <br> not be moved out of a synchronized block. However, it does not say that <br> code not in a synchronized block cannot be moved into a synchronized block.<br>A JIT compiler would see an optimization opportunity here. <br>This optimization would remove the code at <br>//4 and the code at //5, combine it and generate the code shown in Listing 8:Q?br>------------------------------------------------- <br>list 8<br>public static Singleton getInstance()<br>{<br>  if (instance == null)<br>  {<br>    synchronized(Singleton.class) {      //1<br>      Singleton inst = instance;         //2<br>      if (inst == null)<br>      {<br>        synchronized(Singleton.class) {  //3<br>          //inst = new Singleton();      //4<br>          instance = new Singleton();               <br>        }<br>        //instance = inst;               //5<br>      }<br>    }<br>  }<br>  return instance;<br>}<br>If this optimization takes place, you have the same out-of-order write problem we discussed earlier.<br>如果q个优化发生Q将再次发生上边提到的问题,取得没有实例化完成的数据?br>-------------------------------------------------</p> <p>以下部分Z避免我翻译错误误导打Ӟ保留原文</p> <p>Another idea is to use the keyword volatile for the variables inst and instance. <br>According to the JLS (see Resources), variables declared volatile are supposed to <br>be sequentially consistent, and therefore, not reordered. <br>But two problems occur with trying to use volatile to fix the problem with <br>double-checked locking:</p> <p>The problem here is not with sequential consistency. <br>Code is being moved, not reordered.</p> <p>Many JVMs do not implement volatile correctly regarding sequential consistency anyway. <br>The second point is worth expanding upon. Consider the code in Listing 9:</p> <p>Listing 9. Sequential consistency with volatile</p> <p>class test<br>{<br>  private volatile boolean stop = false;<br>  private volatile int num = 0;</p> <p>  public void foo()<br>  {<br>    num = 100;    //This can happen second<br>    stop = true;  //This can happen first<br>    //...<br>  }</p> <p>  public void bar()<br>  {<br>    if (stop)<br>      num += num;  //num can == 0!<br>  }<br>  //...<br>}<br> <br>According to the JLS, because stop and num are declared volatile, <br>they should be sequentially consistent. This means that if stop is ever true, <br>num must have been set to 100. <br>However, because many JVMs do not implement the sequential consistency feature of volatile,<br>you cannot count on this behavior. <br>Therefore, if thread 1 called foo and thread 2 called bar concurrently, <br>thread 1 might set stop to true before num is set to 100. <br>This could lead thread 2 to see stop as true, but num still set to 0. <br>There are additional problems with volatile and the atomicity of 64-bit variables,<br>but this is beyond the scope of this article. <br>See Resources for more information on this topic. </p> <p>单的理解上边q段话,使用volatile有可能能解决问题Qvolatile被定义用来保正一致性,但是很多虚拟?br>q没有很好的实现volatileQ所以用它也会存在问题?/p> <p>最l的解决ҎQ?br> Q?Q,单态模?Q用同步方?br> Q?Q,攑ּ同步Q用一个静态变量,如下<br>class Singleton<br>{<br>  private Vector v;<br>  private boolean inUse;<br>  private static Singleton instance = new Singleton();</p> <p>  private Singleton()<br>  {<br>    v = new Vector();<br>    inUse = true;<br>    //...<br>  }</p> <p>  public static Singleton getInstance()<br>  {<br>    return instance;<br>  }<br>}<br>但用静态变量也会存在问题,问题?<a >q篇文章</a></p> <p>而且如在文章开头提到的Q用EJB跨服务器Q跨JVM的情况下Q单态更是问?/p> <p>好了是不是感觉单态模式根本没法用了Q其实上辚w是特D情况,q中Ҏ情况的出现是有条件的Q只?br>Ҏ你的具体应用Q回避一些,p解决问题Q所以单态还是可以用的。但是在使用前慎重,自己考虑好自?br>的情况适合哪种情况?/p> <p>参?br><a >http://www.jdon.com/designpatterns/singleton.htm</a><br></p> <p><a target=_blank>Double-checked locking and the Singleton pattern</a> </p> <p><a target=_blank>When is a singleton not a singleton?</a> </p> <img src ="http://www.aygfsteel.com/dreamstone/aggbug/79026.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/dreamstone/" target="_blank">dreamstone</a> 2006-11-04 09:26 <a href="http://www.aygfsteel.com/dreamstone/archive/2006/11/04/79026.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank">Ž</a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank">˺</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">崨</a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank">ȫ</a>| <a href="http://" target="_blank">½</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ž</a>| <a href="http://" target="_blank">罭</a>| <a href="http://" target="_blank">ʯ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ǿ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ָ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">̩</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ȫ</a>| <a href="http://" target="_blank">غ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank"></a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>