Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
JavaÄ£Äâ Ë«·ÖÅÉDouble Dispatch
 
×÷Õß yqj2065µÄ²©¿Í£¬»ðÁú¹ûÈí¼þ    ·¢²¼ÓÚ 2014-09-05
  4443  次浏览      27
 

±¾½ÚÓ¦ÓÃÃüÁîģʽ£¬ÔÚJavaÖÐÄ£ÄâË«·ÖÅÉ¡£Àí½â±¾½Úºó£¬·ÃÎÊÕßģʽ(visitor pattern)ÊÖµ½ÇÜÀ´¡£

1. µ¥·ÖÅÉ

·ÖÅÉ/ dispatchÊÇÖ¸ÈçºÎ¸øÒ»¸öÏûÏ¢°ó¶¨Æä·½·¨Ìå¡£Java¡¢C#µÈ½ö½öÖ§³Öµ¥·ÖÅÉ£¨singledispatch£©¶ø²»Ö§³ÖË«·ÖÅÉ(double dispatch)¡£¡¾Ïà¹Ø¸ÅÄ²Î¿¼¡¶Éè¼ÆÄ£Ê½.5.11·ÃÎÊÕßģʽ¡·p223¡¿

¶ÔÓÚÏûÏ¢a.foo(b)£¬¼ÙÉèÓи¸ÀàX¼°ÆäÁ½¸ö×ÓÀàX1¡¢X2£¬aÉùÃ÷ΪXÀàÐͱäÁ¿£»Óи¸ÀàY¼°ÆäÁ½¸ö×ÓÀàY1¡¢Y2£¬bÉùÃ÷ΪYÀàÐͱäÁ¿£¬¶øÇÒX¡¢X1ºÍX2¶¼¸÷×Ô×¼±¸ÁËfoo(Y)¡¢foo(Y1)ºÍfoo(Y2)·½·¨£¬ÇëÎÊa.foo(b)½«Ö´Ðеķ½·¨ÌåÊÇ3*3=9¸ö·½·¨ÖеÄÄÄÒ»¸ö£¿

µ±Ç°Ö÷Á÷µÄÃæÏò¶ÔÏóÓïÑÔÈçC++¡¢Java¡¢C#µÈ£¬½ö½öÖ§³Öµ¥·ÖÅÉ£¨singledispatch£©¡£Àý³Ì3-18ÖУ¬Ä¿Ç°¿ÉÒÔ²»¹Üa.foo(b)ÖеIJÎÊýb£¬ÎÒÃǽö½ö¿´ÏûÏ¢a.m()ºÃÁË¡£¼Ù¶¨X¡¢X1ºÍX2¶¼¸÷×Ô×¼±¸ÁËm()£¬Ôòa.m()°´ÕÕaµÄʵ¼ÊÀàÐÍ°ó¶¨ÆäoverrideµÄ·½·¨Ì壬Õâ¾ÍÊÇÃæÏò¶ÔÏóÖеĶ¯Ì¬°ó¶¨¡£

ËùνµÄË«·ÖÅÉ£¬ÔòÊÇÏ£Íûa.foo(b)Äܹ»¢Ù°´ÕÕaµÄʵ¼ÊÀàÐÍ°ó¶¨ÆäoverrideµÄ·½·¨Ì壬¶øÇÒÄܹ»¢Ú°´ÕÕbµÄʵ¼ÊÀàÐÍ°ó¶¨ÆäÖØÔØµÄ·½·¨¼´foo(Y)¡¢foo(Y1)¡¢foo(Y2)ÖеÄÊʵ±·½·¨Ìå¡£ÏÔÈ»£¬Java²»Ö§³ÖºóÕß¡ª¡ª¼´²»Ö§³ÖË«·ÖÅÉ¡£JavaÔÚ±àÒëʱ£¬¾ÍΪfoo(b)°´ÕÕbµÄÉùÃ÷ÀàÐ;²Ì¬°ó¶¨ÁËfoo(Y)Õâ¸öµÄ·½·¨Ìå¡£JavaÖØÔØ·½·¨µÄÆ¥ÅäËã·¨£¬Çë²Î¿¼¡¾±à³Ìµ¼ÂÛ¡¤2.3.1¡¿¡£

Àý³Ì 3 18 µ¥·ÖÅÉ
package method.command.doubleDispatch;
import static tool.Print.*;
public abstract class X{
public void m(){
pln(" X.m()");
}
public void foo(X x){
p(" X.foo(X)-"); x.m();
}
public void foo(X1 x1){
p(" X.foo(X1)-"); x1.m();
}// foo(X2 x2) ÂÔ
}//×ÓÀàX1¡¢X2µÄ´úÂ룬ÂÔ
package method.command.doubleDispatch;
import tool.God;
public class Test{
public static void Xµ¥·ÖÅÉ(){
X a = (X)God.create("3-18-X1");
X b = (X)God.create("3-18-X2");
a.m(); a.foo(b);
}
}

¼òµ¥Æð¼û£¬ÏûÏ¢a.foo(b)µÄÖÐa£¬bµÄÀàÐ;ùΪX¡£Ë«·ÖÅÉ(double dispatch)¼´ÔÚÑ¡ÔñÒ»¸ö·½·¨ÌåʱÐèÒª¸ù¾ÝÏûÏ¢½ÓÊÕÕßaºÍ²ÎÊýbÁ½ÕßµÄÔËÐÐʱÀàÐÍ(ʵ¼ÊÀàÐÍ)½øÐа󶨣¬JavabuÖ§³Ö¡£ÎªÁË˵Ã÷ÕâÒ»µã£¬ÉÏÃæµÄ´úÂëÖУ¬XÏԵñȽϹÖÒìµÄ°üº¬ÁËfoo(X)¡¢foo(X1)¡¢foo(X2)·½·¨(¸¸ÀàXÒÀÀµÆä×ÓÀà)£¬¶øÇÒ×ÓÀàX1¡¢X2µÄoverrideÁËÖØÔØµÄfoo()·½·¨´úÂë¡£

Test.Xµ¥·ÖÅÉ() µÄÔËÐнá¹û£º

X1.m() // ¶¯Ì¬°ó¶¨
X1.foo(X)-X2.m() // ¶¯Ì¬°ó¶¨X1µÄfoo£¬¶ø¾²Ì¬°ó¶¨foo(X).

ÄÇô£¬b.foo(a);µÄÔËÐнá¹û£ºX2.foo(X)-X1.m()

Èç¹û¶Ô¸ÄдµÄ¶¯Ì¬°ó¶¨ºÍÖØÔØµÄ¾²Ì¬°ó¶¨£¬ÒѾ­Çå³þÁË£¬Ò²¼´Çå³þµØÖªµÀ£ºJavaÖ§³Öµ¥·ÖÅɶø²»Ö§³ÖË«·ÖÅÉ£¬ÏÂÃæ¶ÔÓ¦µØ±àдY¡¢Y1ºÍY2½ö±£Áô¸÷×Ô×¼±¸µÄm()£¬¶øYϵÁÐÖÐɾ³ý¸÷ÖÖfoo·½·¨£¬ÔÚOverloadFooÀàÖÐרעÈçºÎÄ£ÄâË«·ÖÅÉ¡£

package method.command.doubleDispatch;
import static tool.Print.*;
public class Y{
public void m(){
pln(" Y.m()");
}
}

package method.command.doubleDispatch;  
import static tool.Print.*;
public class Y1 extends Y{
@Override public void m(){
pln("Y1.m()");
}
}

package method.command.doubleDispatch;  
import static tool.Print.*;

/**
* OverloadFoo.java.
*
* @author yqj2065
* @version 0.1
*/
public class OverloadFoo{
public void foo(Y y) { y.m();pln("foo(Y)"); }
public void foo(Y1 y){ y.m();pln("foo(Y1)");}
public void foo(Y2 y){ y.m();pln("foo(Y2)");}
/**
* (Run-Time Type Identification¡¢RTTI
*/
public void foo_RTTI(Y y){
if(y instanceof Y1){
pln("foo(Y1)");
}else if(y instanceof Y2){
pln("foo(Y2)");
}else{
pln("foo(Y)");
}
}
}

JavaÖпÉÒÔʹÓÃÔËÐÐʱÀàÐÍʶ±ð(Run-Time TypeIdentification¡¢RTTI)¼¼Êõ¼´Ê¹Óùؼü×ÖinstanceofÅжÏʵ¼ÊÀàÐÍ¡£Òò¶ø£¬Ò»¸öȨÒËÖ®¼ÆÊÇɾ³ýÈý¸öÖØÔØµÄfoo()·½·¨£¬¶ø±àд·½·¨foo_RTTI (Y )¡£ËäÈ»foo_RTTI (Y) ´úÂë¼ò½à£¬µ«ÊÇ£¬Ê¹Ó÷ÖÖ§Óï¾ä²»¹»ÓÅÑÅ¡£

Èç¹ûµ½´¦Ê¹ÓÃif-elseµÄ»°£¬ºÜ¶àģʽ¾ÍʧҵÁË¡£

2.ÃüÁîÄ£Ê½Çø·ÖÖØÔØµÄ·½·¨

¡¾±à³Ìµ¼ÂÛ¡¤2.3.1¡¿ ÖÐ˵Ã÷£º¡°ÖØÔØÒ»¸ö·½·¨£¬ÕæÕý×öµÄÊÂÇéÊǶ¨ÒåÁËÈô¸É²»Í¬µÄ·½·¨£¬²»¹ý¡®ÅöÇÉ¡¯Ê¹ÓÃÁËÏàͬµÄ·½·¨Ãû¡±¡£

µ÷ÓÃfoo(Y)µÄÄ£¿éÈçTest£¬ÔÚËü¿´À´ÖØÔØfoo(X)¡¢foo(X1)¡¢foo(X2)Ò²ºÃ£¬²»Í¬ÃûµÄfooX()¡¢fooX1()¡¢fooX2()Ò²ºÃ£¬TestÏ£Íû½øÐÐͳһµÄµ÷Ó᪡ªÎÞÊÓ±»µ÷µÄ·½·¨Ãû£¬ÎÒÃÇ¿ÉÒÔ²ÉÓÃÃüÁîģʽ¡£

package method.command.doubleDispatch;  
public abstract class Command{
OverloadFoo handler = new OverloadFoo();
public abstract void foo(Y y);//±ä»¯£ºÖ´ÐÐÕßÒÑÖªOverloadFoo
}

package method.command.doubleDispatch;  
public class FooY1 extends Command {
@Override public void foo(Y y) {
handler.foo((Y1)y);
}
}//FooYºÍ FooY2ÂÔ

Õâ¸öCommandºÍ3.4 ÃüÁîģʽ(5.2)Öмòµ¥µÄCommand½Ó¿ÚÓÐЩССµÄ½ø²½£ºÃüÁîµÄÖ´ÐÐÕßÒÑ֪ΪOverloadFoo(ÒòΪËü°üÀ¨ÁË3¸öÖØÔØµÄfoo·½·¨)£»³éÏó·½·¨foo´øÓвÎÊý¡£

CommandµÄ×ÓÀàFooY1£¬Ö¸Ã÷Ö´ÐÐÕßµ÷ÓÃÖØÔØµÄfoo(Y1)·½·¨¡£

public static void Ä£ÄâË«·ÖÅÉ(){  
Y y = (Y)God.create("3-18-Y");//Y1¶ÔÏó
Command cmd = new FooY();
cmd.foo(y);
cmd = new FooY1();
cmd.foo(y);
cmd = new FooY2();//ÈÎÎñ²»¿ÉÖ´ÐÐ
//cmd.foo(y);
}

ÏÖÔÚ£¬´´½¨Ò»¸öY¶ÔÏó(ʵ¼ÊÀàÐÍY1)ºó£¬°´ÕÕ²»Í¬µÄÃüÁ²âÊÔ½á¹û£º

Y1.m()
foo(Y)
Y1.m()
foo(Y1)

ÃüÁîģʽ£¬Ê¹µÃÓû§ÀàTestÎÞÊÓ±»µ÷µÄ·½·¨Ãû£¬Ï´ïͳһµÄÃüÁîfoo(y)£»¶øÖ´ÐÐÕß°´ÕÕÃüÁî¶ÔÏóµÄ²»Í¬£¬Ö´Ðв»Í¬µÄ·½·¨Ì塪¡ªÕâÀï¾Í½«ÖØÔصķ½·¨Çø·Ö¿ªÀ´ÁË¡£

ͼ1 Ó¦ÓÃÃüÁîģʽ

3.ºÏ²¢Àà²ã´Î

ÉÏͼÖÐÓÐÁ½¸öÀà²ã´ÎYºÍCommand£¬Í¼ÐÎÏԵñȽϸ´ÔÓ¡£ÎÒÃÇ·¢ÏÖCommandµÄÆÕÊÊÃüÁîfoo(Y y)ÔÚÆä×ÓÀàFooY1ÖеĴúÂëΪ£º

@Override  public void foo(Y y)  {
handler.foo((Y1)y);
}

ÎÒÃÇÈçºÎÀûÓÃJavaµÄ¶à̬ÐÔ±ÜÃâÕâÖÖÖ¸¶¨ÐÔµÄÇ¿ÖÆÀàÐÍת»»ÄØ£¿Òªµã¾ÍÊÇÃüÁîµÄÖ´ÐÐÕß²»ÔÚÊǹ̶¨µÄ
OverloadFoo handler = new OverloadFoo();

¶øÊÇFooY1×Ô¼º¡ª¡ªÃüÁîÖ´ÐÐÕß½«ÊÇY1ºÍY2£¡

ÏÖÔÚ£¬¿ªÆôZϵÁС£

YϵÁÐʱµÄ Command¶ÔÓ¦½Ó¿ÚFoo£¬ÆÕÊÊÃüÁîfoo(Y y)¶ÔӦΪwi²ÎÊýµÄhandleFoo()¡£

package method.command.doubleDispatch;  
public interface Foo{
public void handleFoo();
}

ÓëXºÍY¶ÔÓ¦µÄZ£¬ÓëX²»Í¬Ö®´¦Îªfoo(Foo )£¡

ZµÄÀà²ã´Î³ÉΪCommand/FooµÄ×ÓÀàÐÍ¡£Z implements FooʹµÃZµÄ×ÓÀà×Ô¶¯³ÉΪFooµÄ×ÓÀàÐÍ£¬£¨ÆäʵZ±¾Éí²»ÐèÒª³ÉΪ FooµÄ×ÓÀàÐÍ£¬Äã¿ÉÒÔ½«ZµÄËùÓÐ×ÓÀàZ1¡¢Z2 implements Foo£©

package method.command.doubleDispatch;  
import static tool.Print.*;
public abstract class Z implements Foo{
public void m(){
pln(" Z.m()");
}

public void foo(Foo z ){//ʾÀý´úÂ룬¿ÉÒÔΪ¿Õ·½·¨Ìå
p(" Z.foo(Foo)-");
this.m();
}

//@Override public void handleFoo(){} //¿ÉÓпÉÎÞ
}

ÏÖÔÚ£¬Z1µÄ´úÂëÈçÏ£º

package method.command.doubleDispatch;  
import static tool.Print.*;
public class Z1 extends Z {
@Override public void m(){
pln(" Z1.m()");
}
/*ÊÂʵÉÏ£¬Òâζ×ÅÖØÔØfoo(Z1)*/
@Override public void foo(Foo z ){
p("Z1.");
z.handleFoo();//Ö´ÐÐÕßz¶¯Ì¬°ó¶¨
this.m();
}
private void foo(){
p("foo(Z1)-");
}
@Override public void handleFoo(){
this.foo();
}
}

package method.command.doubleDispatch;  
import tool.God;

public class Test{
public static void ZË«·ÖÅÉ(){
Z z1 = (Z)God.create("3-18-Z1");//Z1¶ÔÏó
Z z2 = (Z)God.create("3-18-Z2");//Z1¶ÔÏó
z1.foo(z1);
z1.foo(z2);
z2.foo(z1);
z2.foo(z2);
}
}

²âÊÔ½á¹û£º

Z1.foo(Z1)- Z1.m()
Z1.foo(Z2)- Z1.m()
Z2.foo(Z1)- Z2.m()
Z2.foo(Z2)- Z2.m()

¶ÔÓÚÏûÏ¢a.foo(b)£¬¼ÙÉèa¡¢bÉùÃ÷ΪZÀàÐͱäÁ¿£¬Ä¿Ç°ÎÒÃÇÄ£ÄâÁËË«·ÖÅÉDouble Dispatch¡£

ͼ2 ¼ò½àµÄË«·ÖÅɽṹ

ÕâÊÇÒ»ÖÖÓÐÓõĽṹ£¬ÎÒÃÇ¿ÉÒÔ³ÆÖ®ÎªË«·ÖÅÉģʽ¡££¬ÊDz»ÊǺÜÅ£±Æ£¿

²»¹ý£¬ÓÐЩÌÖÈËÏӵļһËûÃǸüÅ£±Æ£¬ËûÃÇÔÚ×Ô¼ºµÄÊéÖУ¬°ÑË«·ÖÅÉģʽ³ÆÎª·ÃÎÊÕßģʽ£¡

Äã¿ÉÒÔÐÞ¸ÄÉÏÊö´úÂ룬ʹµÃÏûÏ¢a.foo(b)£¬ÆäÖÐaÉùÃ÷ΪXÀàÐͱäÁ¿¡¢bÉùÃ÷ΪZÀàÐͱäÁ¿¡£

°´ÕÕÄ£ÄâµÄË«·ÖÅÉÄ£ÐÍ£¬»á³ÉΪ2*2µÄ±íʾ·½Ê½£¬£¬ÕâÊÇÁ½¸ö²½ÖèµÄµþ¼Ó¶øÐγÉ4¸ö´¦ÀíÁ÷³Ì¡£Ã»ÓÐË«·ÖÅÉ»úÖÆ£¬ÄÇÃ´Çø·ÖÖØÔØ²Ù×÷ÊDz»¿ÉÐе쬶ÔÓÚX1ºÍX2µÄ¶ÔÏó£¬ÐèÒª·½·¨fooZ1(Z1)ºÍfooZ2(Z2)£¬Óëa.foo(b)¶ÔÓ¦µÄ£¬ÓÐ4¸ö·½·¨Ìå¡£

   
4443 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

ΪʲôҪ×ö³ÖÐø²¿Êð£¿
ÆÊÎö¡°³ÖÐø½»¸¶¡±£ºÎå¸öºËÐÄʵ¼ù
¼¯³ÉÓë¹¹½¨Ö¸ÄÏ
³ÖÐø¼¯³É¹¤¾ßµÄÑ¡Ôñ-×°ÔØ
 
Ïà¹ØÎĵµ

³ÖÐø¼¯³É½éÉÜ
ʹÓÃHudson³ÖÐø¼¯³É
³ÖÐø¼¯³ÉÖ®-ÒÀÀµ¹ÜÀí
IPD¼¯³É²úÆ·¿ª·¢¹ÜÀí
Ïà¹Ø¿Î³Ì

ÅäÖùÜÀí¡¢ÈÕ¹¹½¨Óë³ÖÐø¼¯³É
Èí¼þ¼Ü¹¹Éè¼Æ·½·¨¡¢°¸ÀýÓëʵ¼ù
µ¥Ôª²âÊÔ¡¢Öع¹¼°³ÖÐø¼¯³É
»ùÓÚAndroidµÄµ¥Ôª¡¢ÐÔÄܲâÊÔ
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]

ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
Visitor Parttern
ÓÉ±í¼°À￴ģʽ
Éè¼ÆÄ£Ê½Ëæ±ÊϵÁÐ
ÉîÈëdz³öÉè¼ÆÄ£Ê½-½éÉÜ
.NETÖеÄÉè¼ÆÄ£Ê½

Ïà¹ØÅàѵ¿Î³Ì

J2EEÉè¼ÆÄ£Ê½ºÍÐÔÄܵ÷ÓÅ
Ó¦ÓÃģʽÉè¼ÆJavaÆóÒµ¼¶Ó¦ÓÃ
Éè¼ÆÄ£Ê½Ô­ÀíÓëÓ¦ÓÃ
J2EEÉè¼ÆÄ£Ê½Ö¸ÄÏ
µ¥Ôª²âÊÔ+ÖØ¹¹+Éè¼ÆÄ£Ê½
Éè¼ÆÄ£Ê½¼°ÆäCSharpʵÏÖ


ijµçÁ¦¹«Ë¾ Éè¼ÆÄ£Ê½Ô­Àí
À¶ÍØÆË Éè¼ÆÄ£Ê½Ô­Àí¼°Ó¦ÓÃ
ÎÀÐǵ¼º½ UML & OOAD
ÌÀɭ·͸Ñз¢ÖÐÐÄ UML& OOAD
Öдïµçͨ Éè¼ÆÄ£Ê½Ô­Àí
Î÷ÃÅ×Ó Ç¶ÈëʽÉè¼ÆÄ£Ê½
 
 
 
¡¡